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