0284452ad0fa619a6f928158c986af0b8d3c707a
[portal.git] / ecomp-portal-BE-common / src / main / java / org / openecomp / portalapp / portal / utils / EcompPortalUtils.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.utils;
21
22 import java.io.PrintWriter;
23 import java.io.StringWriter;
24 import java.net.InetAddress;
25 import java.net.UnknownHostException;
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.Date;
29 import java.util.List;
30
31 import javax.servlet.http.HttpServletResponse;
32 import javax.xml.bind.DatatypeConverter;
33
34 import org.hibernate.Session;
35 import org.hibernate.Transaction;
36 import org.openecomp.portalapp.portal.domain.EPUser;
37 import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
38 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
39 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
40 import org.openecomp.portalsdk.core.onboarding.util.CipherUtil;
41 import org.openecomp.portalsdk.core.util.SystemProperties;
42 import org.slf4j.MDC;
43 import org.springframework.http.HttpHeaders;
44 import org.springframework.http.MediaType;
45
46 import com.fasterxml.jackson.core.JsonProcessingException;
47 import com.fasterxml.jackson.databind.ObjectMapper;
48
49 public class EcompPortalUtils {
50
51         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(EcompPortalUtils.class);
52
53         /**
54          * @param orgUserId
55          * @return true if orgUserId is not empty and contains only alphanumeric,
56          *         false otherwise
57          */
58         public static boolean legitimateUserId(String orgUserId) {
59                 return orgUserId.matches("^[a-zA-Z0-9]+$");
60         }
61
62         /**
63          * Splits the string into a list of tokens using the specified regular
64          * expression
65          * 
66          * @param source
67          * @param regex
68          * @return List of tokens split from the source
69          */
70         public static List<String> parsingByRegularExpression(String source, String regex) {
71                 List<String> tokens = new ArrayList<String>();
72                 if (source != null && source.length() > 0) {
73                         String[] parsed = source.split(regex);
74                         for (String token : parsed) {
75                                 if (token.length() > 0) {
76                                         tokens.add(token);
77                                 }
78                         }
79                 }
80                 return tokens;
81         }
82
83         /**
84          * Builds a JSON object with error code and message information.
85          * 
86          * @param errorCode
87          * @param errorMessage
88          * @return JSON object as a String
89          */
90         public static String jsonErrorMessageResponse(int errorCode, String errorMessage) {
91                 return "{\"error\":{\"code\":" + errorCode + "," + "\"message\":\"" + errorMessage + "\"}}";
92         }
93
94         /**
95          * Builds a JSON object with the specified message
96          * 
97          * @param message
98          * @return JSON object as a String
99          */
100         public static String jsonMessageResponse(String message) {
101                 return String.format("{\"message\":\"%s\"}", message);
102         }
103
104         /**
105          * Serializes the specified object as JSON and writes the result to the
106          * debug log. If serialization fails, logs a message to the error logger.
107          * 
108          * @param logger
109          *            Logger for the class where the object was built; the logger
110          *            carries the class name.
111          * @param source
112          *            First portion of the log message
113          * @param msg
114          *            Second portion of the log message
115          * @param obj
116          *            Object to serialize as JSON
117          */
118         public static void logAndSerializeObject(EELFLoggerDelegate logger, String source, String msg, Object obj) {
119                 try {
120                         String objectAsJson = new ObjectMapper().writeValueAsString(obj);
121                         logger.debug(EELFLoggerDelegate.debugLogger,
122                                         String.format("source= [%s]; %s [%s];", source, msg, objectAsJson));
123                 } catch (JsonProcessingException e) {
124                         logger.warn(EELFLoggerDelegate.errorLogger, "logAndSerializedObject failed to serialize", e);
125                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, e);
126                 } catch (Exception e) {
127                         logger.error(EELFLoggerDelegate.errorLogger, "logAndSerializedObject failed", e);
128                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeInvalidJsonInput, e);
129                 }
130         }
131
132         /**
133          * Serializes the specified object as JSON and writes the result to the
134          * debug log. If serialization fails, logs a message to the error logger.
135          * 
136          * @param source
137          *            First portion of the log message
138          * @param msg
139          *            Second portion of the log message
140          * @param obj
141          *            Object to serialize as JSON
142          */
143         public static void logAndSerializeObject(String source, String msg, Object obj) {
144                 logAndSerializeObject(logger, source, msg, obj);
145         }
146
147         public static void rollbackTransaction(Transaction transaction, String errorMessage) {
148                 logger.error(EELFLoggerDelegate.errorLogger, errorMessage);
149                 try {
150                         if (transaction != null) {
151                                 transaction.rollback();
152                         }
153                 } catch (Exception e) {
154                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeExecuteRollbackError, e);
155                         logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while performing a rollback transaction",
156                                         e);
157                 }
158         }
159
160         public static void closeLocalSession(Session localSession, String errorMessage) {
161                 logger.error(EELFLoggerDelegate.errorLogger, errorMessage);
162                 try {
163                         if (localSession != null) {
164                                 localSession.close();
165                         }
166                 } catch (Exception e) {
167                         EPLogUtil.logEcompError(logger, EPAppMessagesEnum.BeDaoCloseSessionError, e);
168                         logger.error(EELFLoggerDelegate.errorLogger, errorMessage + ", closeLocalSession exception", e);
169                 }
170         }
171
172         // TODO: GLOBAL_LOGIN_URL is the same as in SessionTimeoutInterceptor.
173         // It should be defined in SystemProperties.
174         private static final String GLOBAL_LOGIN_URL = "global-login-url";
175
176         /**
177          * Set response status to Unauthorized if user == null and to Forbidden in
178          * all (!) other cases. Logging is not performed if invocator == null
179          * 
180          * @param user
181          * @param response
182          * @param invocator
183          *            - may be null
184          */
185         public static void setBadPermissions(EPUser user, HttpServletResponse response, String invocator) {
186                 if (user == null) {
187                         String loginUrl = SystemProperties.getProperty(EPCommonSystemProperties.LOGIN_URL_NO_RET_VAL);
188                         response.setHeader(GLOBAL_LOGIN_URL, loginUrl);
189                         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
190                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_UNAUTHORIZED));
191                 } else {
192                         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
193                         MDC.put(EPCommonSystemProperties.RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_FORBIDDEN));
194                 }
195                 if (invocator != null) {
196                         logger.warn(EELFLoggerDelegate.errorLogger,
197                                         invocator + ", permissions problem, response status = " + response.getStatus());
198                 }
199         }
200
201         public static int getExternalAppResponseCode() {
202                 String responseCode = MDC.get(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE);
203                 int responseCodeInt = 0;
204                 try {
205                         if (responseCode != null && responseCode != "") {
206                                 responseCodeInt = Integer.valueOf(responseCode);
207                         }
208                 } catch (Exception e) {
209                         logger.error(EELFLoggerDelegate.errorLogger,
210                                         "Exception occurred in getResponseCode(). Details: " + EcompPortalUtils.getStackTrace(e));
211                 }
212                 return responseCodeInt;
213         }
214
215         // This method might be just for testing purposes.
216         public static void setExternalAppResponseCode(int responseCode) {
217                 try {
218                         String responseCodeString = String.valueOf(responseCode);
219                         MDC.put(EPCommonSystemProperties.EXTERNAL_API_RESPONSE_CODE, responseCodeString);
220                 } catch (Exception e) {
221                         logger.error(EELFLoggerDelegate.errorLogger,
222                                         "Exception occurred in setResponseCode(). Details: " + EcompPortalUtils.getStackTrace(e));
223                 }
224         }
225
226         public static String getHTTPStatusString(int httpStatusCode) {
227                 String httpStatusString = "unknown_error";
228                 try {
229                         httpStatusString = org.springframework.http.HttpStatus.valueOf(httpStatusCode).name();
230                         if (httpStatusString != null) {
231                                 httpStatusString = httpStatusString.toLowerCase();
232                         }
233                 } catch (Exception e) {
234                         logger.error(EELFLoggerDelegate.errorLogger,
235                                         "Exception occurred in getHTTPStatusString(). Details: " + EcompPortalUtils.getStackTrace(e));
236                 }
237                 return httpStatusString;
238         }
239
240         public static String getFEErrorString(Boolean internal, int responseCode) {
241                 // Return a String like the following:
242                 // "Internal Ecomp Error: 500 internal_server_error" or
243                 // "External App Error: 404 not_found"
244                 // TODO: create our own Ecomp error codes, starting with 1000 and up.
245                 String responseString = "";
246                 String internalExternalString = internal ? "Ecomp Error: " : "App Error: ";
247                 String httpStatusString = "unknown_error";
248                 try {
249                         if (responseCode < 1000) {
250                                 httpStatusString = getHTTPStatusString(responseCode);
251                         }
252                 } catch (Exception e) {
253                         logger.error(EELFLoggerDelegate.errorLogger,
254                                         "Exception occurred in getFEErrorString(). Details: " + EcompPortalUtils.getStackTrace(e));
255                 }
256                 responseString = internalExternalString + responseCode + " " + httpStatusString;
257                 return responseString;
258         }
259
260         public static boolean isProductionBuild() {
261                 boolean productionBuild = true;
262                 String epVersion = EcompVersion.buildNumber;
263                 if (epVersion != null) {
264                         int buildNum = epVersion.lastIndexOf('.');
265                         if (buildNum > 0) {
266                                 int buildNumber = Integer.parseInt(epVersion.substring(buildNum + 1));
267                                 if (buildNumber < 3000) // Production versions are 3000+, (ie
268                                                                                 // 1.0.3003)
269                                 {
270                                         productionBuild = false;
271                                 }
272                         }
273                 }
274                 return productionBuild;
275         }
276
277         private static final Object stackTraceLock = new Object();
278
279         public static String getStackTrace(Throwable t) {
280                 synchronized (stackTraceLock) {
281                         StringWriter sw = new StringWriter();
282                         PrintWriter pw = new PrintWriter(sw);
283                         t.printStackTrace(pw);
284                         return sw.toString();
285                 }
286         }
287
288         public static String getMyIpAdddress() {
289                 InetAddress ip;
290                 String localIp;
291                 try {
292                         ip = InetAddress.getLocalHost();
293                         localIp = ip.getHostAddress();
294                 } catch (UnknownHostException e) {
295                         localIp = "unknown";
296                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
297                 }
298                 return localIp;
299         }
300
301         public static String getMyHostName() {
302                 InetAddress ip;
303                 String hostName;
304                 try {
305                         ip = InetAddress.getLocalHost();
306                         hostName = ip.getHostName();
307                 } catch (UnknownHostException e) {
308                         hostName = "unknown";
309                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
310                 }
311                 return hostName;
312         }
313
314         /* return a default property if the expected one is not available */
315         public static String getPropertyOrDefault(String property, String defaultValue) {
316                 return ((null == SystemProperties.getProperty(property) || SystemProperties.getProperty(property).equals(""))
317                                 ? defaultValue : SystemProperties.getProperty(property));
318         }
319
320         /**
321          * Calculates the time duration of a function call for logging purpose. It
322          * stores the result by using "MDC.put(SystemProperties.MDC_TIMER,
323          * timeDifference);" It is important to call
324          * "MDC.remove(SystemProperties.MDC_TIMER);" after this method call to clean
325          * up the record in MDC
326          *
327          * @param beginDateTime
328          *            the given begin time for the call
329          * @param endDateTime
330          *            the given end time for the call
331          * 
332          */
333         public static void calculateDateTimeDifferenceForLog(String beginDateTime, String endDateTime) {
334                 if (beginDateTime != null && endDateTime != null) {
335                         try {
336                                 SimpleDateFormat ecompLogDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
337
338                                 Date beginDate = ecompLogDateFormat.parse(beginDateTime);
339                                 Date endDate = ecompLogDateFormat.parse(endDateTime);
340                                 String timeDifference = String.format("%d", endDate.getTime() - beginDate.getTime());
341                                 MDC.put(SystemProperties.MDC_TIMER, timeDifference);
342                         } catch (Exception e) {
343                                 logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
344                         }
345                 }
346         }
347         
348         public static String widgetMsProtocol(){
349                 final String protocol;
350                 try{
351                         protocol = SystemProperties.getProperty(EPCommonSystemProperties.WIDGET_MS_PROTOCOL);
352                         return (protocol == null || protocol.trim().equals("")) ? "https" : protocol ;
353                 }
354                 catch(IllegalStateException ese){
355                         //looks like SystemProperties.getProperty throws IllegalStateException if it cannot find a property you are looking for
356                         //In order to not break the code if a non-required property is missing from system.properties, returning https as default
357                         //when this exception is caught.
358                         return "https";
359                 }               
360         }
361         
362         public static String localOrDockerHost(){
363                 final String effectiveHost;
364                 try{
365                         effectiveHost = SystemProperties.getProperty(EPCommonSystemProperties.WIDGET_MS_HOSTNAME);
366                         return (effectiveHost == null || effectiveHost.trim().equals("")) ? "localhost" : effectiveHost ;
367                 }
368                 catch(IllegalStateException ese){
369                         //looks like SystemProperties.getProperty throws IllegalStateException if it cannot find a property you are looking for
370                         //In order to not break the code if a non-required property is missing from system.properties, returning https as default
371                         //when this exception is caught.
372                         return "localhost";
373                 }               
374         }
375
376         /**
377          * It returns headers where username and password of external central auth
378          * is encoded to base64
379          * 
380          * @return header which contains external central auth username and password
381          *         base64 encoded
382          * @throws Exception
383          *             if unable to decrypt the password
384          */
385         public static HttpHeaders base64encodeKeyForAAFBasicAuth() throws Exception {
386                 
387                 String userName = "";
388                 String decryptedPass = "";
389                 if (EPCommonSystemProperties
390                                 .containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_USER_NAME) && EPCommonSystemProperties
391                                 .containsProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_PASSWORD)) {
392                         decryptedPass = SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_PASSWORD);
393                         userName = SystemProperties.getProperty(EPCommonSystemProperties.EXTERNAL_CENTRAL_AUTH_USER_NAME);
394                 }
395                 String decPass = decrypted(decryptedPass);
396                 String usernamePass = userName + ":" + decPass;
397                 String encToBase64 = String.valueOf((DatatypeConverter.printBase64Binary(usernamePass.getBytes())));
398                 HttpHeaders headers = new HttpHeaders();
399                 headers.add("Authorization", "Basic " + encToBase64);
400                 headers.setContentType(MediaType.APPLICATION_JSON);
401                 return headers;
402         }
403         
404         private static String decrypted(String encrypted) throws Exception {
405                 String result = "";
406                 if (encrypted != null && encrypted.length() > 0) {
407                         try {
408                                 result = CipherUtil.decrypt(encrypted, SystemProperties.getProperty(SystemProperties.Decryption_Key));
409                         } catch (Exception e) {
410                                 logger.error(EELFLoggerDelegate.errorLogger, "decryptedPassword failed", e);
411                                 throw e;
412                         }
413                 }
414                 return result;
415         }
416
417 }