[PORTAL-7] Rebase
[portal.git] / ecomp-portal-BE-os / src / main / java / org / openecomp / portalapp / portal / service / ApplicationsRestClientServiceImpl.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.service;
21
22 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
23
24 import java.lang.reflect.Type;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.util.Date;
28
29 import javax.annotation.PostConstruct;
30 import javax.servlet.http.HttpServletResponse;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
33
34 import org.apache.cxf.jaxrs.client.WebClient;
35 import org.apache.cxf.transport.http.HTTPException;
36 import org.openecomp.portalapp.portal.domain.EPApp;
37 import org.openecomp.portalapp.portal.logging.aop.EPAuditLog;
38 import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
39 import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
40 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
41 import org.openecomp.portalapp.portal.utils.EPSystemProperties;
42 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
43 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
44 import org.openecomp.portalsdk.core.onboarding.util.CipherUtil;
45 import org.openecomp.portalsdk.core.util.SystemProperties;
46 import org.slf4j.MDC;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.context.annotation.EnableAspectJAutoProxy;
49 import org.springframework.stereotype.Service;
50
51 import com.google.gson.Gson;
52 import com.google.gson.GsonBuilder;
53 import com.google.gson.JsonDeserializationContext;
54 import com.google.gson.JsonDeserializer;
55 import com.google.gson.JsonElement;
56 import com.google.gson.JsonParseException;
57
58 @Service("applicationsRestClientService")
59 @org.springframework.context.annotation.Configuration
60 @EnableAspectJAutoProxy
61 @EPAuditLog
62 public class ApplicationsRestClientServiceImpl implements ApplicationsRestClientService{
63         
64         private static final String PASSWORD_HEADER = "password";
65
66         private static final String APP_USERNAME_HEADER = "username";
67
68         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ApplicationsRestClientServiceImpl.class);
69         
70         @Autowired
71         private AppsCacheService appsCacheService;
72         Gson gson = null;
73         
74         @PostConstruct
75         private void init(){
76                 logger.debug(EELFLoggerDelegate.debugLogger, "initializing");
77                 GsonBuilder builder = new GsonBuilder(); 
78
79                 // Register an adapter to manage the date types as long values 
80                 builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
81                    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
82                       return new Date(json.getAsJsonPrimitive().getAsLong()); 
83                    } 
84                 });
85
86                 gson = builder.create();        
87         }
88         
89         // TODO: do we need to do additional logging for remote API calls?
90         private static WebClient createClientForPath(String baseUri, String path) {
91                 logger.info(EELFLoggerDelegate.debugLogger, "Creating web client for " + baseUri + "   +   " + path); 
92                 WebClient client = WebClient.create(baseUri);
93                 client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
94                 client.path(path);
95                 return client;
96         }
97
98         @EPMetricsLog
99         private void verifyResponse(Response response) throws HTTPException {
100                 int status = response.getStatus();
101                 logger.debug(EELFLoggerDelegate.debugLogger, "http response status=" + status);
102                 MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE, Integer.toString(status));
103                 if (!isHttpSuccess(status)) {
104                         String errMsg = "Failed. Status=" + status + "; [" + response.getStatusInfo().getReasonPhrase().toString() + "]";
105                         URL url = null;
106                         try {
107                                 // must not be null to avoid NPE in HTTPException constructor
108                                 url = new URL("http://null");
109                                 if (response.getLocation() != null)
110                                         url = response.getLocation().toURL();
111                         } catch (MalformedURLException e) {
112                                 // never mind. it is only for the debug message.
113                                 logger.warn(EELFLoggerDelegate.errorLogger, "Failed to build URL", e);
114                         }
115                         logger.error(EELFLoggerDelegate.errorLogger, "http response failed. " + errMsg + "; url=" + url);
116                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeIncorrectHttpStatusError);
117                         throw new HTTPException(status, errMsg, url);
118                 }
119         }
120         
121         private static boolean isHttpSuccess(int status){
122                 return status / 100 == 2;
123         }
124
125         @EPMetricsLog
126         private WebClient createClientForApp(long appId, String restPath) {
127                 logger.debug(EELFLoggerDelegate.debugLogger, "creating client for appId=" + appId + "; restPath=" + restPath); 
128                 EPApp externalApp = appsCacheService.getApp(appId);
129                 if(externalApp != null){
130                         String appBaseUri = externalApp.getAppRestEndpoint();
131                         String username = externalApp.getUsername();                    
132                         String encriptedPwd = externalApp.getAppPassword();
133                         String decreptedAppPwd = "";
134                         
135                         //Set local context
136                         MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
137                         if (appBaseUri!=null && appBaseUri.contains("https")) {
138                                 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
139                         }
140                         MDC.put(EPSystemProperties.FULL_URL, appBaseUri + restPath);
141                         MDC.put(EPSystemProperties.TARGET_ENTITY, externalApp.getName());
142                         MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, restPath);
143                         
144                         try {
145                                 decreptedAppPwd = CipherUtil.decrypt(encriptedPwd, SystemProperties.getProperty(SystemProperties.Decryption_Key));
146                         } catch (Exception e) {                         
147                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to decrypt App name = " + externalApp, EcompPortalUtils.getStackTrace(e));
148                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to decrypt App name = " + externalApp, EcompPortalUtils.getStackTrace(e));
149                         }
150                         logger.debug(EELFLoggerDelegate.debugLogger, String.format("App %d found, baseUri=[%s], Headers: [%s=%s, %s=%s]", appId, appBaseUri, APP_USERNAME_HEADER, username, PASSWORD_HEADER, encriptedPwd));
151                         WebClient client = createClientForPath(appBaseUri, restPath);
152                         client.header(APP_USERNAME_HEADER, username);
153                         client.header(PASSWORD_HEADER, decreptedAppPwd);
154                         client.header(SystemProperties.ECOMP_REQUEST_ID, MDC.get(MDC_KEY_REQUEST_ID));
155                         client.header(SystemProperties.USERAGENT_NAME, EPSystemProperties.ECOMP_PORTAL_BE);
156                         
157                         return client;
158                 }
159                 return null;
160         }
161         
162         @Override
163         public <T> T get(Class<T> clazz, long appId, String restPath) throws HTTPException {
164                 
165                 WebClient webClient = null;
166                 Response response = null;
167                 T t = null;
168                 
169                 webClient = createClientForApp(appId, restPath);
170                 EcompPortalUtils.logAndSerializeObject(restPath, "GET request =", "no-payload");
171                                                 
172                 try {
173                         if (webClient!=null) {
174                                 response = webClient.get();
175                         } else {
176                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
177                         }
178                 } catch (Exception e) {
179                         MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
180                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
181                         logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while making the GET REST API call, Details: " + EcompPortalUtils.getStackTrace(e));
182                 }
183                 
184                 if (response!=null) {
185                         verifyResponse(response);
186                         String str = response.readEntity(String.class);
187                         EcompPortalUtils.logAndSerializeObject(restPath, "GET result =", str);
188                     try { t = gson.fromJson(str, clazz); } catch(Exception e) {
189                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
190                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput); 
191                         }
192                 }
193                 
194                 return t;
195         }
196
197         @Override
198         public <T> T post(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
199                 WebClient client = null;
200                 Response response = null;
201                 T t = null;
202                 
203                 client = createClientForApp(appId, restPath);
204                 EcompPortalUtils.logAndSerializeObject(restPath, "POST request =", payload);
205                 
206                 
207                 try {
208                         if (client!=null) {
209                                 response = client.post(payload);
210                         } else {
211                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
212                         }
213                 } catch (Exception e) {
214                         MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
215                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
216                         logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while making the POST REST API call, Details: " + EcompPortalUtils.getStackTrace(e));
217                 }
218                 
219                 if (response!=null) {
220                         verifyResponse(response);
221                         
222                         //String contentType = response.getHeaderString("Content-Type");
223                         if(clazz != null) {
224                                 String str = response.readEntity(String.class);
225                                 EcompPortalUtils.logAndSerializeObject(restPath, "POST result =", str);
226                                 try { t = gson.fromJson(str, clazz); } catch (Exception e) {
227                                         logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
228                                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
229                                         }
230                         }
231                 }
232                 return t;
233         }
234
235         @Override
236         public <T> T put(Class<T> clazz, long appId, Object payload, String restPath)  throws HTTPException {
237                 WebClient client = null;
238                 Response response = null;
239                 T t = null;
240                 
241                 client = createClientForApp(appId, restPath);
242                 EcompPortalUtils.logAndSerializeObject(restPath, "PUT request =", payload);
243                 
244                 try {
245                         if (client!=null) {
246                                 response = client.put(payload);
247                         } else {
248                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
249                         }
250                 } catch(Exception e) {
251                         MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE, Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
252                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
253                         logger.error(EELFLoggerDelegate.errorLogger, "Exception occurred while making the PUT REST API call, Details: " + EcompPortalUtils.getStackTrace(e));
254                 }
255                 
256                 if (response!=null) {
257                         verifyResponse(response);
258                         String str = response.readEntity(String.class);
259                         EcompPortalUtils.logAndSerializeObject(restPath, "PUT result =", str);
260                         try { t = gson.fromJson(str, clazz); } catch (Exception e) {
261                                 logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
262                                 EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
263                                 }
264                 }
265                 return t;
266         }
267 }