2 * ================================================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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 * ================================================================================
20 package org.openecomp.portalapp.portal.service;
22 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
24 import java.lang.reflect.Type;
25 import java.net.MalformedURLException;
27 import java.util.Date;
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;
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;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.context.annotation.EnableAspectJAutoProxy;
49 import org.springframework.stereotype.Service;
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;
59 @Service("applicationsRestClientService")
60 @org.springframework.context.annotation.Configuration
61 @EnableAspectJAutoProxy
63 public class ApplicationsRestClientServiceImpl implements ApplicationsRestClientService{
65 private static final String PASSWORD_HEADER = "password";
67 private static final String APP_USERNAME_HEADER = "username";
69 private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ApplicationsRestClientServiceImpl.class);
72 private AppsCacheService appsCacheService;
75 private final ObjectMapper mapper = new ObjectMapper();
79 logger.debug(EELFLoggerDelegate.debugLogger, "initializing");
80 GsonBuilder builder = new GsonBuilder();
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());
89 gson = builder.create();
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);
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() + "]";
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);
118 logger.error(EELFLoggerDelegate.errorLogger, "http response failed. " + errMsg + "; url=" + url);
119 EPLogUtil.logEcompError(EPAppMessagesEnum.BeIncorrectHttpStatusError);
120 throw new HTTPException(status, errMsg, url);
124 private static boolean isHttpSuccess(int status){
125 return status / 100 == 2;
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 = "";
139 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
140 if (appBaseUri!=null && appBaseUri.contains("https")) {
141 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
143 MDC.put(EPSystemProperties.FULL_URL, appBaseUri + restPath);
144 MDC.put(EPSystemProperties.TARGET_ENTITY, externalApp.getName());
145 MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, restPath);
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));
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);
166 public <T> T get(Class<T> clazz, long appId, String restPath) throws HTTPException {
168 WebClient webClient = null;
169 Response response = null;
172 webClient = createClientForApp(appId, restPath);
173 EcompPortalUtils.logAndSerializeObject(restPath, "GET request =", "no-payload");
176 if (webClient!=null) {
177 response = webClient.get();
179 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
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));
187 if (response!=null) {
188 verifyResponse(response);
189 String str = response.readEntity(String.class);
190 EcompPortalUtils.logAndSerializeObject(restPath, "GET result =", str);
192 t = mapper.readValue(str, clazz);
193 } catch(Exception e) {
194 logger.error(EELFLoggerDelegate.errorLogger, EcompPortalUtils.getStackTrace(e));
195 EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
203 public <T> T post(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
204 WebClient client = null;
205 Response response = null;
208 client = createClientForApp(appId, restPath);
209 EcompPortalUtils.logAndSerializeObject(restPath, "POST request =", payload);
214 response = client.post(payload);
216 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
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));
224 if (response!=null) {
225 verifyResponse(response);
227 //String contentType = response.getHeaderString("Content-Type");
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);
241 public <T> T put(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
242 WebClient client = null;
243 Response response = null;
246 client = createClientForApp(appId, restPath);
247 EcompPortalUtils.logAndSerializeObject(restPath, "PUT request =", payload);
251 response = client.put(payload);
253 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
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));
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);