[PORTAL-16 PORTAL-18] Widget ms; staging
[portal.git] / ecomp-portal-BE-common / src / main / java / org / openecomp / portalapp / portal / controller / DashboardController.java
1 /*-
2  * ================================================================================
3  * ECOMP Portal
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ================================================================================
19  */
20 package org.openecomp.portalapp.portal.controller;
21
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30
31 import javax.servlet.http.HttpServletRequest;
32
33 import org.openecomp.portalapp.controller.EPRestrictedBaseController;
34 import org.openecomp.portalapp.portal.domain.EPUser;
35 import org.openecomp.portalapp.portal.domain.EcompAuditLog;
36 import org.openecomp.portalapp.portal.ecomp.model.PortalRestResponse;
37 import org.openecomp.portalapp.portal.ecomp.model.PortalRestStatusEnum;
38 import org.openecomp.portalapp.portal.ecomp.model.SearchResultItem;
39 import org.openecomp.portalapp.portal.logging.aop.EPAuditLog;
40 import org.openecomp.portalapp.portal.logging.aop.EPEELFLoggerAdvice;
41 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
42 import org.openecomp.portalapp.portal.service.DashboardSearchService;
43 import org.openecomp.portalapp.portal.transport.CommonWidget;
44 import org.openecomp.portalapp.portal.transport.CommonWidgetMeta;
45 import org.openecomp.portalapp.portal.utils.EPCommonSystemProperties;
46 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
47 import org.openecomp.portalapp.util.EPUserUtils;
48 import org.openecomp.portalsdk.core.domain.AuditLog;
49 import org.openecomp.portalsdk.core.domain.support.CollaborateList;
50 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
51 import org.openecomp.portalsdk.core.service.AuditService;
52 import org.openecomp.portalsdk.core.util.SystemProperties;
53 import org.slf4j.MDC;
54 import org.springframework.beans.factory.annotation.Autowired;
55 import org.springframework.context.annotation.Configuration;
56 import org.springframework.web.bind.annotation.RequestBody;
57 import org.springframework.web.bind.annotation.RequestMapping;
58 import org.springframework.web.bind.annotation.RequestMethod;
59 import org.springframework.web.bind.annotation.RequestParam;
60 import org.springframework.web.bind.annotation.RestController;
61
62 /**
63  * Controller supplies data to Angular services on the dashboard page.
64  */
65 @Configuration
66 @RestController
67 @RequestMapping("/portalApi/dashboard")
68 public class DashboardController extends EPRestrictedBaseController {
69
70         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(DashboardController.class);
71
72         @Autowired
73         private DashboardSearchService searchService;
74         @Autowired
75         private AuditService auditService;
76         
77         public enum WidgetCategory {
78                 EVENTS, NEWS, IMPORTANTRESOURCES;
79         }
80
81         /**
82          * Validates the resource type parameter.
83          * 
84          * @param resourceType
85          * @return True if known in the enum WidgetCategory, else false.
86          */
87         private boolean isValidResourceType(String resourceType) {
88                 if (resourceType == null)
89                         return false;
90                 for (WidgetCategory wc : WidgetCategory.values())
91                         if (wc.name().equals(resourceType))
92                                 return true;
93                 return false;
94         }
95
96         /**
97          * Gets all widgets of the specified resource type. 
98          * In iteration 41 (when widget will utilized service onboarding), this method can be removed, instead we will use CommonWidgetController.java (basic auth based)
99          * 
100          * @param request
101          * @param resourceType
102          *            Request parameter.
103          * @return Rest response wrapped around a CommonWidgetMeta object.
104          */
105         @RequestMapping(value = "/widgetData", method = RequestMethod.GET, produces = "application/json")
106         public PortalRestResponse<CommonWidgetMeta> getWidgetData(HttpServletRequest request,
107                         @RequestParam String resourceType) {
108                 if (!isValidResourceType(resourceType))
109                         return new PortalRestResponse<CommonWidgetMeta>(PortalRestStatusEnum.ERROR,
110                                         "Unexpected resource type " + resourceType, null);
111                 return new PortalRestResponse<CommonWidgetMeta>(PortalRestStatusEnum.OK, "success",
112                                 searchService.getWidgetData(resourceType));
113         }
114         
115         
116         /**
117          * Saves a batch of events, news or resources.
118          * 
119          * @param commonWidgetMeta
120          *            read from POST body.
121          * @return Rest response wrapped around a String; e.g., "success" or "ERROR"
122          */
123         @RequestMapping(value = "/widgetDataBulk", method = RequestMethod.POST, produces = "application/json")
124         public PortalRestResponse<String> saveWidgetDataBulk(@RequestBody CommonWidgetMeta commonWidgetMeta) {
125                 logger.debug(EELFLoggerDelegate.debugLogger, "saveWidgetDataBulk: argument is {}", commonWidgetMeta);
126                 if (commonWidgetMeta.getCategory() == null || commonWidgetMeta.getCategory().trim().equals(""))
127                         return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, "ERROR",
128                                         "Category cannot be null or empty");
129                 if (!isValidResourceType(commonWidgetMeta.getCategory()))
130                         return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR,
131                                         "Unexpected resource type " + commonWidgetMeta.getCategory(), null);
132                 // validate dates
133                 for (CommonWidget cw : commonWidgetMeta.getItems()) {
134                         String err = validateCommonWidget(cw);
135                         if (err != null)
136                                 return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, err, null);
137                 }
138                 return new PortalRestResponse<String>(PortalRestStatusEnum.OK, "success",
139                                 searchService.saveWidgetDataBulk(commonWidgetMeta));
140         }
141
142         /**
143          * Saves one: event, news or resource
144          * 
145          * @param commonWidget
146          *            read from POST body
147          * @return Rest response wrapped around a String; e.g., "success" or "ERROR"
148          */
149         @RequestMapping(value = "/widgetData", method = RequestMethod.POST, produces = "application/json")
150         public PortalRestResponse<String> saveWidgetData(@RequestBody CommonWidget commonWidget) {
151                 logger.debug(EELFLoggerDelegate.debugLogger, "saveWidgetData: argument is {}", commonWidget);
152                 if (commonWidget.getCategory() == null || commonWidget.getCategory().trim().equals(""))
153                         return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, "ERROR",
154                                         "Category cannot be null or empty");
155                 String err = validateCommonWidget(commonWidget);
156                 if (err != null)
157                         return new PortalRestResponse<String>(PortalRestStatusEnum.ERROR, err, null);
158                 return new PortalRestResponse<String>(PortalRestStatusEnum.OK, "success",
159                                 searchService.saveWidgetData(commonWidget));
160         }
161
162         /**
163          * Used by the validate function
164          */
165         private final SimpleDateFormat yearMonthDayFormat = new SimpleDateFormat("yyyy-MM-dd");
166
167         /**
168          * Validates the content of a common widget.
169          * 
170          * @param cw
171          * @return null on success; an error message if validation fails.
172          * @throws Exception
173          */
174         private String validateCommonWidget(CommonWidget cw) {
175                 if (!isValidResourceType(cw.getCategory()))
176                         return "Invalid category: " + cw.getCategory();
177                 if (cw.getTitle() == null || cw.getTitle().trim().length() == 0)
178                         return "Title is missing";
179                 if (cw.getHref() == null || cw.getHref().trim().length() == 0)
180                         return "HREF is missing";
181                 if (!cw.getHref().toLowerCase().startsWith("http"))
182                         return "HREF does not start with http";
183                 if (cw.getSortOrder() == null)
184                         return "Sort order is null";
185                 if (WidgetCategory.EVENTS.name().equals(cw.getCategory())) {
186                         if (cw.getEventDate() == null || cw.getEventDate().trim().length() == 0)
187                                 return "Date is missing";
188                         try {
189                                 yearMonthDayFormat.setLenient(false);
190                                 Date date = yearMonthDayFormat.parse(cw.getEventDate());
191                                 if (date == null)
192                                         return "Failed to parse date " + cw.getEventDate();
193                         } catch (ParseException ex) {
194                                 return ex.toString();
195                         }
196                 }
197                 return null;
198         }
199
200         /**
201          * Deletes one: event, news or resource
202          * 
203          * @param commonWidget
204          *            read from POST body
205          * @return Rest response wrapped around a String; e.g., "success" or "ERROR"
206          */
207         @RequestMapping(value = "/deleteData", method = RequestMethod.POST, produces = "application/json")
208         public PortalRestResponse<String> deleteWidgetData(@RequestBody CommonWidget commonWidget) {
209                 logger.debug(EELFLoggerDelegate.debugLogger, "deleteWidgetData: argument is {}", commonWidget);
210                 return new PortalRestResponse<String>(PortalRestStatusEnum.OK, "success",
211                                 searchService.deleteWidgetData(commonWidget));
212         }
213
214         /**
215          * Searches all portal for the input string.
216          * 
217          * @param request
218          * @param searchString
219          * @return Rest response wrapped around a Map of String to List of Search
220          *         Result Item.
221          */
222         @EPAuditLog
223         @RequestMapping(value = "/search", method = RequestMethod.GET, produces = "application/json")
224         public PortalRestResponse<Map<String, List<SearchResultItem>>> searchPortal(HttpServletRequest request,
225                         @RequestParam String searchString) {
226
227                 if (searchString != null)
228                         searchString = searchString.trim();
229                 EPUser user = EPUserUtils.getUserSession(request);
230                 try {
231                         if (user == null) {
232                                 return new PortalRestResponse<>(PortalRestStatusEnum.ERROR,
233                                                 "searchPortal: User object is null? - check logs",
234                                                 new HashMap<String, List<SearchResultItem>>());
235                         } else if (searchString == null || searchString.length() == 0) {
236                                 return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "searchPortal: String string is null",
237                                                 new HashMap<String, List<SearchResultItem>>());
238                         } else {
239                                 logger.debug(EELFLoggerDelegate.debugLogger, "searchPortal: user {}, search string '{}'",
240                                                 user.getLoginId(), searchString);
241                                 Map<String, List<SearchResultItem>> results = searchService.searchResults(user.getLoginId(),
242                                                 searchString);
243                                 /*Audit log the search*/
244                                 AuditLog auditLog = new AuditLog();
245                                 auditLog.setUserId(user.getId());
246                                 auditLog.setActivityCode(EcompAuditLog.CD_ACTIVITY_SEARCH);
247                                 auditLog.setComments(searchString);
248                                 MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,EPEELFLoggerAdvice.getCurrentDateTimeUTC());          
249                                 auditService.logActivity(auditLog, null);
250                                 MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP,EPEELFLoggerAdvice.getCurrentDateTimeUTC());
251                                 EcompPortalUtils.calculateDateTimeDifferenceForLog(MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
252                                 logger.info(EELFLoggerDelegate.auditLogger, EPLogUtil.formatAuditLogMessage("DashboardController.PortalRestResponse", 
253                                                 EcompAuditLog.CD_ACTIVITY_SEARCH, user.getOrgUserId(), null, searchString));    
254                                 MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
255                                 MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
256                                 MDC.remove(SystemProperties.MDC_TIMER);
257                                 return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success", results);
258                         }
259                 } catch (Exception e) {
260                         logger.error(EELFLoggerDelegate.errorLogger, "searchPortal failed", e);
261                         return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.getMessage() + " - check logs.",
262                                         new HashMap<String, List<SearchResultItem>>());
263                 }
264         }
265
266         /**
267          * Gets all active users.
268          * 
269          * TODO: should only the superuser be allowed to use this API?
270          * 
271          * @param request
272          * @return Rest response wrapped around a list of String
273          */
274         @RequestMapping(value = "/activeUsers", method = RequestMethod.GET, produces = "application/json")
275         public List<String> getActiveUsers(HttpServletRequest request) {
276                 List<String> activeUsers = null;
277                 List<String> onlineUsers = new ArrayList<>();
278                 try {
279                         EPUser user = EPUserUtils.getUserSession(request);
280                         String userId = user.getOrgUserId();
281
282                         activeUsers = searchService.getRelatedUsers(userId);
283                         HashSet<String> usersSet = CollaborateList.getInstance().getAllUserName();
284                         for (String users : activeUsers) {
285                                 if (usersSet.contains(users)) {
286                                         onlineUsers.add(users);
287                                 }
288                         }
289
290                 } catch (Exception e) {
291                         logger.error(EELFLoggerDelegate.errorLogger, "getActiveUsers failed", e);
292                 }
293                 return onlineUsers;
294         }
295         
296         /**
297          * Gets the refresh interval and duration of a cycle of continuous refreshing for the online users side panel, both in milliseconds.
298          * 
299          * @param request
300          * @return Rest response wrapped around a number that is the number of milliseconds.
301          */
302         @RequestMapping(value = "/onlineUserUpdateRate", method = RequestMethod.GET, produces = "application/json")
303         public PortalRestResponse<Map<String, String>> getOnlineUserUpdateRate(HttpServletRequest request) {
304                 try {
305                         String updateRate = SystemProperties.getProperty(EPCommonSystemProperties.ONLINE_USER_UPDATE_RATE);     
306                         String updateDuration = SystemProperties.getProperty(EPCommonSystemProperties.ONLINE_USER_UPDATE_DURATION);                             
307                         Integer rateInMiliSec = Integer.valueOf(updateRate)*1000;
308                         Integer durationInMiliSec = Integer.valueOf(updateDuration)*1000;
309                         Map<String, String> results = new HashMap<String,String>();
310                         results.put("onlineUserUpdateRate", String.valueOf(rateInMiliSec));
311                         results.put("onlineUserUpdateDuration", String.valueOf(durationInMiliSec));                     
312                         return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success", results);
313                 } catch (Exception e) {
314                         logger.error(EELFLoggerDelegate.errorLogger, "getOnlineUserUpdateRate failed", e);
315                         return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.toString(), null);
316                 }               
317         }
318
319         /**
320          * Gets the window width threshold for collapsing right menu from system.properties.
321          * 
322          * @param request
323          * @return Rest response wrapped around a number that is the window width threshold to collapse right menu.
324          */
325         @RequestMapping(value = "/windowWidthThresholdRightMenu", method = RequestMethod.GET, produces = "application/json")
326         public PortalRestResponse<Map<String, String>> getWindowWidthThresholdForRightMenu(HttpServletRequest request) {
327                 try {
328                         String windowWidthString = SystemProperties.getProperty(EPCommonSystemProperties.WINDOW_WIDTH_THRESHOLD_RIGHT_MENU);    
329                         Integer windowWidth = Integer.valueOf(windowWidthString);
330                         Map<String, String> results = new HashMap<String,String>();
331                         results.put("windowWidth", String.valueOf(windowWidth));
332                         return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success", results);
333                 } catch (Exception e) {
334                         logger.error(EELFLoggerDelegate.errorLogger, "getWindowWidthThresholdForRightMenu failed", e);
335                         return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.toString(), null);
336                 }               
337         }
338
339
340         /**
341          * Gets the window width threshold for collapsing left menu from system.properties.
342          * 
343          * @param request
344          * @return Rest response wrapped around a number that is the window width threshold to collapse the left menu.
345          */
346         @RequestMapping(value = "/windowWidthThresholdLeftMenu", method = RequestMethod.GET, produces = "application/json")
347         public PortalRestResponse<Map<String, String>> getWindowWidthThresholdForLeftMenu(HttpServletRequest request) {
348                 try {
349                         String windowWidthString = SystemProperties.getProperty(EPCommonSystemProperties.WINDOW_WIDTH_THRESHOLD_LEFT_MENU);     
350                         Integer windowWidth = Integer.valueOf(windowWidthString);
351                         Map<String, String> results = new HashMap<String,String>();
352                         results.put("windowWidth", String.valueOf(windowWidth));
353                         return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success", results);
354                 } catch (Exception e) {
355                         logger.error(EELFLoggerDelegate.errorLogger, "getWindowWidthThresholdForLeftMenu failed", e);
356                         return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.toString(), null);
357                 }               
358         }
359         
360         /**
361          * Gets only those users that are 'related' to the currently logged-in user.
362          * 
363          * @param request
364          * @return Rest response wrapped around a List of String
365          */
366         @RequestMapping(value = "/relatedUsers", method = RequestMethod.GET, produces = "application/json")
367         public PortalRestResponse<List<String>> activeUsers(HttpServletRequest request) {
368                 EPUser user = EPUserUtils.getUserSession(request);
369                 try {
370                         if (user == null) {
371                                 return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, "User object is null? - check logs",
372                                                 new ArrayList<>());
373                         } else {
374                                 logger.debug(EELFLoggerDelegate.debugLogger, "activeUsers: searching for user {}", user.getLoginId());
375                                 return new PortalRestResponse<>(PortalRestStatusEnum.OK, "success",
376                                                 searchService.getRelatedUsers(user.getLoginId()));
377                         }
378                 } catch (Exception e) {
379                         logger.error(EELFLoggerDelegate.errorLogger, "activeUsers failed", e);
380                         return new PortalRestResponse<>(PortalRestStatusEnum.ERROR, e.getMessage() + " - check logs.",
381                                         new ArrayList<>());
382                 }
383         }
384
385 }