fa8ab5d55fb52176f0b3560711b17cdf257b3d71
[portal.git] / portal-BE / src / main / java / org / onap / portal / logging / aop / EPEELFLoggerAdvice.java
1 /*
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ===================================================================
9  *
10  * Unless otherwise specified, all software contained herein is licensed
11  * under the Apache License, Version 2.0 (the "License");
12  * you may not use this software except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *             http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * Unless otherwise specified, all documentation contained herein is licensed
24  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25  * you may not use this documentation except in compliance with the License.
26  * You may obtain a copy of the License at
27  *
28  *             https://creativecommons.org/licenses/by/4.0/
29  *
30  * Unless required by applicable law or agreed to in writing, documentation
31  * distributed under the License is distributed on an "AS IS" BASIS,
32  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33  * See the License for the specific language governing permissions and
34  * limitations under the License.
35  *
36  * ============LICENSE_END============================================
37  *
38  *
39  */
40
41 package org.onap.portal.logging.aop;
42
43 import com.att.eelf.configuration.Configuration;
44 import java.net.InetAddress;
45 import java.security.Principal;
46 import java.text.SimpleDateFormat;
47 import java.util.Date;
48 import java.util.UUID;
49 import javax.servlet.http.HttpServletRequest;
50 import org.onap.portal.domain.db.fn.FnApp;
51 import org.onap.portal.domain.db.fn.FnUser;
52 import org.onap.portal.service.fn.FnUserService;
53 import org.onap.portal.service.fn.old.AppsCacheService;
54 import org.onap.portal.utils.EPCommonSystemProperties;
55 import org.onap.portal.utils.EcompPortalUtils;
56 import org.onap.portalsdk.core.exception.SessionExpiredException;
57 import org.onap.portalsdk.core.logging.format.AlarmSeverityEnum;
58 import org.onap.portalsdk.core.logging.format.AuditLogFormatter;
59 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
60 import org.onap.portalsdk.core.util.SystemProperties;
61 import org.onap.portalsdk.core.util.SystemProperties.SecurityEventTypeEnum;
62 import org.onap.portalsdk.core.web.support.UserUtils;
63 import org.slf4j.MDC;
64 import org.springframework.beans.factory.annotation.Autowired;
65
66 @org.springframework.context.annotation.Configuration
67 public class EPEELFLoggerAdvice {
68
69         private EELFLoggerDelegate adviceLogger = EELFLoggerDelegate.getLogger(EPEELFLoggerAdvice.class);
70
71         private final AppsCacheService appCacheService;
72         private final FnUserService fnUserService;
73
74         @Autowired
75         public EPEELFLoggerAdvice(AppsCacheService appCacheService, FnUserService fnUserService) {
76                 this.appCacheService = appCacheService;
77                 this.fnUserService = fnUserService;
78         }
79
80         public static String getCurrentDateTimeUTC() {
81                 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
82                 return ecompLogDateFormat.format(new Date());
83         }
84
85         public void loadServletRequestBasedDefaults(Principal principal, HttpServletRequest req, SecurityEventTypeEnum securityEventType) {
86                 try {
87                         setHttpRequestBasedDefaultsIntoGlobalLoggingContext(principal, req, securityEventType, req.getServletPath());
88                 } catch (Exception e) {
89                         adviceLogger.error(EELFLoggerDelegate.errorLogger, "loadServletRequestBasedDefaults failed", e);
90                 }
91         }
92
93         public Object[] before(Principal principal, SecurityEventTypeEnum securityEventType, Object[] args, Object[] passOnArgs) {
94                 String className = "";
95                 if (passOnArgs.length > 0 && passOnArgs[0] != null)
96                         className = passOnArgs[0].toString();
97                 String methodName = EPCommonSystemProperties.ECOMP_PORTAL_BE;
98                 if (passOnArgs.length > 1 && passOnArgs[1] != null)
99                         methodName = passOnArgs[1].toString();
100
101                 MDC.put(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP, getCurrentDateTimeUTC());
102                 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
103                 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
104                 if (MDC.get(Configuration.MDC_KEY_REQUEST_ID) == null||MDC.get(Configuration.MDC_KEY_REQUEST_ID).isEmpty()){
105                         String requestId = UUID.randomUUID().toString();
106                         MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
107                 }
108                 MDC.put(EPCommonSystemProperties.PARTNER_NAME, "Unknown");
109                 MDC.put(Configuration.MDC_SERVICE_NAME, EPCommonSystemProperties.ECOMP_PORTAL_BE);
110
111                 if (securityEventType != null) {
112                         MDC.put(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
113                                         getCurrentDateTimeUTC());
114                         HttpServletRequest req;
115                         if (args.length > 0 && args[0] != null && args[0] instanceof HttpServletRequest) {
116                                 req = (HttpServletRequest) args[0];
117                                 this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(principal, req, securityEventType, methodName);
118                         }
119                 }
120
121                 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
122                 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#before: entering {}", methodName);
123                 return new Object[] { "" };
124         }
125
126         public void after(Principal principal, SecurityEventTypeEnum securityEventType, String statusCode, String responseCode, Object[] args,
127                         Object[] returnArgs, Object[] passOnArgs) {
128                 String className = "";
129                 if (passOnArgs.length > 0 && passOnArgs[0] != null)
130                         className = passOnArgs[0].toString();
131                 String methodName =  EPCommonSystemProperties.ECOMP_PORTAL_BE;
132                 if (passOnArgs.length > 1 && passOnArgs[1] != null)
133                         methodName = passOnArgs[1].toString();
134
135                 if (MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME) == null
136                                 || "".equals(MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME)))
137                         MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, methodName);
138
139                 if (MDC.get(EPCommonSystemProperties.TARGET_ENTITY) == null
140                                 || "".equals(MDC.get(EPCommonSystemProperties.TARGET_ENTITY)))
141                         MDC.put(EPCommonSystemProperties.TARGET_ENTITY, EPCommonSystemProperties.ECOMP_PORTAL_BE);
142
143                 if (MDC.get(Configuration.MDC_KEY_REQUEST_ID) == null||MDC.get(Configuration.MDC_KEY_REQUEST_ID).isEmpty()){
144                         String requestId = UUID.randomUUID().toString();
145                         MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
146                 }
147
148                 if (MDC.get(EPCommonSystemProperties.PARTNER_NAME) == null|| MDC.get(EPCommonSystemProperties.PARTNER_NAME).isEmpty()){
149                         MDC.put(EPCommonSystemProperties.PARTNER_NAME, "Unknown");
150                 }
151
152                 MDC.put(Configuration.MDC_SERVICE_NAME, EPCommonSystemProperties.ECOMP_PORTAL_BE);
153
154
155                 MDC.put(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP,
156                                 MDC.get(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP));
157                 MDC.put(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
158                 this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP),
159                                 MDC.get(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP));
160
161                 if (securityEventType != null && args.length > 0 && args[0] != null && args[0] instanceof HttpServletRequest
162                                 && securityEventType == SecurityEventTypeEnum.INCOMING_REST_MESSAGE
163                                 && (MDC.get(EPCommonSystemProperties.FULL_URL) == null
164                                                 || MDC.get(EPCommonSystemProperties.FULL_URL).isEmpty())) {
165                         HttpServletRequest req = (HttpServletRequest) args[0];
166                         this.setHttpRequestBasedDefaultsIntoGlobalLoggingContext(principal, req, securityEventType, methodName);
167                 }
168
169                 String externalAPIResponseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
170                 if (externalAPIResponseCode == null || "".equals(externalAPIResponseCode)
171                                 || externalAPIResponseCode.trim().equalsIgnoreCase("200")) {
172                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, responseCode);
173                         MDC.put(EPCommonSystemProperties.STATUS_CODE, statusCode);
174                 } else {
175                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, externalAPIResponseCode);
176                         MDC.put(EPCommonSystemProperties.STATUS_CODE, "ERROR");
177                 }
178
179                 EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(className);
180                 logger.debug(EELFLoggerDelegate.debugLogger, "EPEELFLoggerAdvice#after: finished {}", methodName);
181
182                 logger.info(EELFLoggerDelegate.metricsLogger,  methodName + " operation is completed.");
183
184                 if (securityEventType != null) {
185                         MDC.put(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP,
186                                         MDC.get(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP));
187                         MDC.put(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP, getCurrentDateTimeUTC());
188                         this.calculateDateTimeDifference(MDC.get(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP),
189                                         MDC.get(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP));
190
191                         this.logSecurityMessage(logger, securityEventType, methodName);
192
193                         if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
194                                         && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
195                                 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
196                                 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
197                                 MDC.remove(Configuration.MDC_SERVICE_NAME);
198                                 MDC.remove(EPCommonSystemProperties.MDC_LOGIN_ID);
199                                 MDC.remove(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
200                         }else{
201                                 MDC.remove(Configuration.MDC_KEY_REQUEST_ID);
202                                 MDC.remove(EPCommonSystemProperties.PARTNER_NAME);
203                                 MDC.remove(Configuration.MDC_SERVICE_NAME);
204                         }
205
206
207                         MDC.remove(EPCommonSystemProperties.FULL_URL);
208                         MDC.remove(EPCommonSystemProperties.PROTOCOL);
209                         MDC.remove(EPCommonSystemProperties.STATUS_CODE);
210                         MDC.remove(className + methodName + EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
211                         MDC.remove(EPCommonSystemProperties.AUDITLOG_BEGIN_TIMESTAMP);
212                         MDC.remove(EPCommonSystemProperties.AUDITLOG_END_TIMESTAMP);
213                         MDC.remove(EPCommonSystemProperties.RESPONSE_CODE);
214                 }
215                 MDC.remove(className + methodName + EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
216                 MDC.remove(EPCommonSystemProperties.METRICSLOG_BEGIN_TIMESTAMP);
217                 MDC.remove(EPCommonSystemProperties.METRICSLOG_END_TIMESTAMP);
218                 MDC.remove(EPCommonSystemProperties.MDC_TIMER);
219                 MDC.remove(EPCommonSystemProperties.TARGET_ENTITY);
220                 MDC.remove(EPCommonSystemProperties.TARGET_SERVICE_NAME);
221
222         }
223
224         private void logSecurityMessage(EELFLoggerDelegate logger, SecurityEventTypeEnum securityEventType,
225                         String restMethod) {
226                 StringBuilder additionalInfoAppender = new StringBuilder();
227                 String auditMessage;
228
229                 if (securityEventType == SecurityEventTypeEnum.OUTGOING_REST_MESSAGE) {
230                         additionalInfoAppender.append(String.format("%s '%s' request was initiated.", restMethod,
231                                         MDC.get(EPCommonSystemProperties.TARGET_SERVICE_NAME)));
232                 } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
233                         additionalInfoAppender.append("LDAP Phonebook search operation is performed.");
234                 } else {
235                         additionalInfoAppender.append(String.format("%s request was received.", restMethod));
236
237                         if (securityEventType == SecurityEventTypeEnum.FE_LOGIN_ATTEMPT) {
238                                 String loginId;
239                                 String additionalMessage = " Successfully authenticated.";
240                                 loginId = MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID);
241                                 if (loginId == null || "".equals(loginId) || EPCommonSystemProperties.UNKNOWN.equals(loginId)) {
242                                         additionalMessage = " No cookies are found.";
243                                 }
244                                 additionalInfoAppender.append(additionalMessage);
245                         } else if (securityEventType == SecurityEventTypeEnum.FE_LOGOUT) {
246                                 additionalInfoAppender.append(" User has been successfully logged out.");
247                         }
248                 }
249
250                 String fullURL = MDC.get(EPCommonSystemProperties.FULL_URL);
251                 if (fullURL != null && !"".equals(fullURL)) {
252                         additionalInfoAppender.append(" Request-URL:").append(MDC.get(EPCommonSystemProperties.FULL_URL));
253                 }
254
255                 auditMessage = AuditLogFormatter.getInstance().createMessage(MDC.get(EPCommonSystemProperties.PROTOCOL),
256                                 securityEventType.name(), MDC.get(EPCommonSystemProperties.MDC_LOGIN_ID),
257                                 additionalInfoAppender.toString());
258
259                 logger.info(EELFLoggerDelegate.auditLogger, auditMessage);
260         }
261
262         private void setHttpRequestBasedDefaultsIntoGlobalLoggingContext(Principal principal, HttpServletRequest req,
263                         SecurityEventTypeEnum securityEventType, String restMethod) {
264
265                 if (req != null) {
266                         if (securityEventType != SecurityEventTypeEnum.OUTGOING_REST_MESSAGE
267                                         && securityEventType != SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH
268                                         && securityEventType != SecurityEventTypeEnum.INCOMING_UEB_MESSAGE) {
269                                 loadRequestId(req);
270
271                                 loadPartnerName(req);
272
273                                 loadLoginId(principal, req);
274
275                                 loadUrlProtocol(req);
276
277                                 loadServicePath(req, restMethod);
278
279                                 loadClientAddress(req);
280
281                         } else if (securityEventType == SecurityEventTypeEnum.LDAP_PHONEBOOK_USER_SEARCH) {
282                                 MDC.put(EPCommonSystemProperties.TARGET_ENTITY, "Phonebook");
283                                 MDC.put(EPCommonSystemProperties.TARGET_SERVICE_NAME, "search");
284                         }
285                 } else {
286                         MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
287                         MDC.put(EPCommonSystemProperties.PARTNER_NAME, EPCommonSystemProperties.ECOMP_PORTAL_FE);
288                 }
289
290                 MDC.put(Configuration.MDC_SERVICE_INSTANCE_ID, "");
291                 MDC.put(Configuration.MDC_ALERT_SEVERITY, AlarmSeverityEnum.INFORMATIONAL.severity());
292                 try {
293                         MDC.put(Configuration.MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName());
294                         MDC.put(Configuration.MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
295                         MDC.put(Configuration.MDC_INSTANCE_UUID, SystemProperties.getProperty(SystemProperties.INSTANCE_UUID));
296                 } catch (Exception e) {
297                         adviceLogger.error(EELFLoggerDelegate.errorLogger,
298                                         "setHttpRequestBasedDefaultsIntoGlobalLoggingContext failed", e);
299                 }
300         }
301
302         private void loadClientAddress(HttpServletRequest req) {
303                 String clientIPAddress;
304                 clientIPAddress = req.getHeader("X-FORWARDED-FOR");
305                 if (clientIPAddress == null) {
306                         clientIPAddress = req.getRemoteAddr();
307                 }
308                 MDC.put(EPCommonSystemProperties.CLIENT_IP_ADDRESS, clientIPAddress);
309         }
310
311         private void loadServicePath(HttpServletRequest req, String restMethod) {
312                 MDC.put(Configuration.MDC_SERVICE_NAME, restMethod);
313                 String restPath = req.getServletPath();
314                 if (restPath != null && restPath.trim().length()>0) {
315
316                         MDC.put(Configuration.MDC_SERVICE_NAME, restPath);
317                 }
318         }
319
320         private void loadUrlProtocol(HttpServletRequest req) {
321                 String restURL;
322                 MDC.put(EPCommonSystemProperties.FULL_URL, EPCommonSystemProperties.UNKNOWN);
323                 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTP);
324                 restURL = UserUtils.getFullURL(req);
325                 if (restURL.trim().length() > 0) {
326                         MDC.put(EPCommonSystemProperties.FULL_URL, restURL);
327                         if (restURL.toLowerCase().contains("https")) {
328                                 MDC.put(EPCommonSystemProperties.PROTOCOL, EPCommonSystemProperties.HTTPS);
329                         }
330                 }
331         }
332
333         private void loadRequestId(HttpServletRequest req) {
334                 String requestId = UserUtils.getRequestId(req);
335                 if (requestId == null||requestId.trim().length()==0) {
336                         requestId = UUID.randomUUID().toString();
337                 }
338                 MDC.put(Configuration.MDC_KEY_REQUEST_ID, requestId);
339         }
340
341         private void loadLoginId(Principal principal, HttpServletRequest req) {
342                 String loginId = "NoUser";
343                 try {
344                         FnUser user = fnUserService.loadUserByUsername(principal.getName());
345                         loginId = (user != null ? user.getOrgUserId(): loginId);
346                 } catch (SessionExpiredException se) {
347                         adviceLogger.debug(EELFLoggerDelegate.debugLogger,
348                                         "setHttpRequestBasedDefaultsIntoGlobalLoggingContext: No user found in session");
349                 }
350
351                 final String nameHeader = req.getHeader(EPCommonSystemProperties.USERNAME);
352                 if (nameHeader != null) {
353                         loginId = nameHeader;
354                 }
355
356                 final String authHeader = req.getHeader(EPCommonSystemProperties.AUTHORIZATION);
357                 if (authHeader != null) {
358                         String[] accountNamePassword = EcompPortalUtils.getUserNamePassword(authHeader);
359                         if (accountNamePassword != null && accountNamePassword.length == 2) {
360                                 loginId = accountNamePassword[0];
361                         }
362                 }
363
364                 MDC.put(EPCommonSystemProperties.MDC_LOGIN_ID, loginId );
365         }
366
367         private void loadPartnerName(HttpServletRequest req) {
368
369
370                 // Load user agent into MDC context, if available.
371                 String accessingClient = req.getHeader(SystemProperties.USERAGENT_NAME);
372                 accessingClient = (accessingClient == null || accessingClient.trim().length()==0)?"Unknown":accessingClient;
373                 if (accessingClient != null && accessingClient.trim().length()==0 && (accessingClient.contains("Mozilla")
374                                 || accessingClient.contains("Chrome") || accessingClient.contains("Safari"))) {
375                         accessingClient = EPCommonSystemProperties.ECOMP_PORTAL_FE;
376                 }
377                 MDC.put(EPCommonSystemProperties.PARTNER_NAME, accessingClient);
378
379                 String uebVal = req.getHeader(EPCommonSystemProperties.UEB_KEY);
380                 if(uebVal != null) {
381                         FnApp appRecord = appCacheService.getAppFromUeb(uebVal);
382                         MDC.put(EPCommonSystemProperties.PARTNER_NAME, appRecord.getAppName());
383                 }
384
385
386         }
387
388         private void calculateDateTimeDifference(String beginDateTime, String endDateTime) {
389                 if (beginDateTime != null && endDateTime != null && !beginDateTime.isEmpty()&&!endDateTime.isEmpty()) {
390                         try {
391                                 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
392                                 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
393                                 Date endDate = ecompLogDateFormat.parse(endDateTime);
394                                 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
395                                 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
396                         } catch (Exception e) {
397                                 adviceLogger.error(EELFLoggerDelegate.errorLogger, "calculateDateTimeDifference failed", e);
398                         }
399                 }
400         }
401
402         public String getInternalResponseCode() {
403                 return MDC.get(EPCommonSystemProperties.RESPONSE_CODE);
404         }
405
406 }