2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
8 * Unless otherwise specified, all software contained herein is licensed
9 * under the Apache License, Version 2.0 (the “License”);
10 * you may not use this software except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * Unless otherwise specified, all documentation contained herein is licensed
22 * under the Creative Commons License, Attribution 4.0 Intl. (the “License”);
23 * you may not use this documentation except in compliance with the License.
24 * You may obtain a copy of the License at
26 * https://creativecommons.org/licenses/by/4.0/
28 * Unless required by applicable law or agreed to in writing, documentation
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
34 * ============LICENSE_END============================================
36 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
38 package org.openecomp.portalapp.portal.service;
40 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
42 import java.lang.reflect.Type;
43 import java.net.MalformedURLException;
45 import java.util.Date;
47 import javax.annotation.PostConstruct;
48 import javax.servlet.http.HttpServletResponse;
49 import javax.ws.rs.core.MediaType;
50 import javax.ws.rs.core.Response;
52 import org.apache.cxf.jaxrs.client.WebClient;
53 import org.apache.cxf.transport.http.HTTPException;
54 import org.openecomp.portalapp.portal.domain.EPApp;
55 import org.openecomp.portalapp.portal.logging.aop.EPAuditLog;
56 import org.openecomp.portalapp.portal.logging.aop.EPMetricsLog;
57 import org.openecomp.portalapp.portal.logging.format.EPAppMessagesEnum;
58 import org.openecomp.portalapp.portal.logging.logic.EPLogUtil;
59 import org.openecomp.portalapp.portal.utils.EPSystemProperties;
60 import org.openecomp.portalapp.portal.utils.EcompPortalUtils;
61 import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
62 import org.openecomp.portalsdk.core.onboarding.util.CipherUtil;
63 import org.openecomp.portalsdk.core.util.SystemProperties;
65 import org.springframework.beans.factory.annotation.Autowired;
66 import org.springframework.context.annotation.EnableAspectJAutoProxy;
67 import org.springframework.stereotype.Service;
69 import com.fasterxml.jackson.databind.ObjectMapper;
70 import com.google.gson.Gson;
71 import com.google.gson.GsonBuilder;
72 import com.google.gson.JsonDeserializationContext;
73 import com.google.gson.JsonDeserializer;
74 import com.google.gson.JsonElement;
75 import com.google.gson.JsonParseException;
77 @Service("applicationsRestClientService")
78 @org.springframework.context.annotation.Configuration
79 @EnableAspectJAutoProxy
81 public class ApplicationsRestClientServiceImpl implements ApplicationsRestClientService {
83 private static final String PASSWORD_HEADER = "password";
85 private static final String APP_USERNAME_HEADER = "username";
87 private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ApplicationsRestClientServiceImpl.class);
90 private AppsCacheService appsCacheService;
93 private final ObjectMapper mapper = new ObjectMapper();
97 logger.debug(EELFLoggerDelegate.debugLogger, "initializing");
98 GsonBuilder builder = new GsonBuilder();
100 // Register an adapter to manage the date types as long values
101 builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
102 public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
103 throws JsonParseException {
104 return new Date(json.getAsJsonPrimitive().getAsLong());
108 gson = builder.create();
111 // TODO: do we need to do additional logging for remote API calls?
112 private static WebClient createClientForPath(String baseUri, String path) {
113 logger.info(EELFLoggerDelegate.debugLogger, "Creating web client for " + baseUri + " + " + path);
114 WebClient client = WebClient.create(baseUri);
115 client.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
121 private void verifyResponse(Response response) throws HTTPException {
122 int status = response.getStatus();
123 logger.debug(EELFLoggerDelegate.debugLogger, "http response status=" + status);
124 MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE, Integer.toString(status));
125 if (!isHttpSuccess(status)) {
126 String errMsg = "Failed. Status=" + status + "; [" + response.getStatusInfo().getReasonPhrase().toString()
130 // must not be null to avoid NPE in HTTPException constructor
131 url = new URL("http://null");
132 if (response.getLocation() != null)
133 url = response.getLocation().toURL();
134 } catch (MalformedURLException e) {
135 // never mind. it is only for the debug message.
136 logger.warn(EELFLoggerDelegate.errorLogger, "Failed to build URL", e);
138 logger.error(EELFLoggerDelegate.errorLogger, "http response failed. " + errMsg + "; url=" + url);
139 EPLogUtil.logEcompError(EPAppMessagesEnum.BeIncorrectHttpStatusError);
140 throw new HTTPException(status, errMsg, url);
144 private static boolean isHttpSuccess(int status) {
145 return status / 100 == 2;
149 private WebClient createClientForApp(long appId, String restPath) {
150 logger.debug(EELFLoggerDelegate.debugLogger, "creating client for appId=" + appId + "; restPath=" + restPath);
151 EPApp externalApp = appsCacheService.getApp(appId);
152 if (externalApp != null) {
153 String appBaseUri = externalApp.getAppRestEndpoint();
154 String username = externalApp.getUsername();
155 String encriptedPwd = externalApp.getAppPassword();
156 String decreptedAppPwd = "";
159 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
160 if (appBaseUri != null && appBaseUri.contains("https")) {
161 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
163 MDC.put(EPSystemProperties.FULL_URL, appBaseUri + restPath);
164 MDC.put(EPSystemProperties.TARGET_ENTITY, externalApp.getName());
165 MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, restPath);
168 decreptedAppPwd = CipherUtil.decrypt(encriptedPwd,
169 SystemProperties.getProperty(SystemProperties.Decryption_Key));
170 } catch (Exception e) {
171 logger.error(EELFLoggerDelegate.errorLogger, "createClientForApp failed to decrypt", e);
173 logger.debug(EELFLoggerDelegate.debugLogger,
174 String.format("App %d found, baseUri=[%s], Headers: [%s=%s, %s=%s]", appId, appBaseUri,
175 APP_USERNAME_HEADER, username, PASSWORD_HEADER, encriptedPwd));
176 WebClient client = createClientForPath(appBaseUri, restPath);
177 client.header(APP_USERNAME_HEADER, username);
178 client.header(PASSWORD_HEADER, decreptedAppPwd);
179 client.header(SystemProperties.ECOMP_REQUEST_ID, MDC.get(MDC_KEY_REQUEST_ID));
180 client.header(SystemProperties.USERAGENT_NAME, EPSystemProperties.ECOMP_PORTAL_BE);
188 public <T> T get(Class<T> clazz, long appId, String restPath) throws HTTPException {
190 WebClient webClient = null;
191 Response response = null;
194 webClient = createClientForApp(appId, restPath);
195 EcompPortalUtils.logAndSerializeObject(restPath, "GET request =", "no-payload");
198 if (webClient != null) {
199 response = webClient.get();
201 logger.error(EELFLoggerDelegate.errorLogger,
202 "Unable to create the Webclient to make the '" + restPath + "' API call.");
204 } catch (Exception e) {
205 MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE,
206 Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
207 EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
208 logger.error(EELFLoggerDelegate.errorLogger, "get 1 failed", e);
211 if (response != null) {
212 verifyResponse(response);
213 String str = response.readEntity(String.class);
214 EcompPortalUtils.logAndSerializeObject(restPath, "GET result =", str);
216 t = mapper.readValue(str, clazz);
217 } catch (Exception e) {
218 logger.error(EELFLoggerDelegate.errorLogger, "get 2 failed", e);
219 EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
227 public <T> T post(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
228 WebClient client = null;
229 Response response = null;
232 client = createClientForApp(appId, restPath);
233 EcompPortalUtils.logAndSerializeObject(restPath, "POST request =", payload);
236 if (client != null) {
237 response = client.post(payload);
239 logger.error(EELFLoggerDelegate.errorLogger,
240 "Unable to create the Webclient to make the {} API call", restPath);
242 } catch (Exception e) {
243 MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE,
244 Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
245 EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
246 logger.error(EELFLoggerDelegate.errorLogger, "post 1 failed", e);
249 if (response != null) {
250 verifyResponse(response);
252 // String contentType = response.getHeaderString("Content-Type");
254 String str = response.readEntity(String.class);
255 EcompPortalUtils.logAndSerializeObject(restPath, "POST result =", str);
257 t = gson.fromJson(str, clazz);
258 } catch (Exception e) {
259 logger.error(EELFLoggerDelegate.errorLogger, "post 2 failed", e);
260 EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);
268 public <T> T put(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
269 WebClient client = null;
270 Response response = null;
273 client = createClientForApp(appId, restPath);
274 EcompPortalUtils.logAndSerializeObject(restPath, "PUT request =", payload);
277 if (client != null) {
278 response = client.put(payload);
280 logger.error(EELFLoggerDelegate.errorLogger,
281 "Unable to create the Webclient to make the '" + restPath + "' API call.");
283 } catch (Exception e) {
284 MDC.put(EPSystemProperties.EXTERNAL_API_RESPONSE_CODE,
285 Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
286 EPLogUtil.logEcompError(EPAppMessagesEnum.BeRestApiGeneralError);
287 logger.error(EELFLoggerDelegate.errorLogger, "put 1 failed", e);
290 if (response != null) {
291 verifyResponse(response);
292 String str = response.readEntity(String.class);
293 EcompPortalUtils.logAndSerializeObject(restPath, "PUT result =", str);
295 t = gson.fromJson(str, clazz);
296 } catch (Exception e) {
297 logger.error(EELFLoggerDelegate.errorLogger, "put 2 failed", e);
298 EPLogUtil.logEcompError(EPAppMessagesEnum.BeInvalidJsonInput);