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