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