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.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;
 
  58 @Service("applicationsRestClientService")
 
  59 @org.springframework.context.annotation.Configuration
 
  60 @EnableAspectJAutoProxy
 
  62 public class ApplicationsRestClientServiceImpl implements ApplicationsRestClientService{
 
  64         private static final String PASSWORD_HEADER = "password";
 
  66         private static final String APP_USERNAME_HEADER = "username";
 
  68         private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ApplicationsRestClientServiceImpl.class);
 
  71         private AppsCacheService appsCacheService;
 
  76                 logger.debug(EELFLoggerDelegate.debugLogger, "initializing");
 
  77                 GsonBuilder builder = new GsonBuilder(); 
 
  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()); 
 
  86                 gson = builder.create();        
 
  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);
 
  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() + "]";
 
 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);
 
 115                         logger.error(EELFLoggerDelegate.errorLogger, "http response failed. " + errMsg + "; url=" + url);
 
 116                         EPLogUtil.logEcompError(EPAppMessagesEnum.BeIncorrectHttpStatusError);
 
 117                         throw new HTTPException(status, errMsg, url);
 
 121         private static boolean isHttpSuccess(int status){
 
 122                 return status / 100 == 2;
 
 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 = "";
 
 136                         MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTP);
 
 137                         if (appBaseUri!=null && appBaseUri.contains("https")) {
 
 138                                 MDC.put(EPSystemProperties.PROTOCOL, EPSystemProperties.HTTPS);
 
 140                         MDC.put(EPSystemProperties.FULL_URL, appBaseUri + restPath);
 
 141                         MDC.put(EPSystemProperties.TARGET_ENTITY, externalApp.getName());
 
 142                         MDC.put(EPSystemProperties.TARGET_SERVICE_NAME, restPath);
 
 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));
 
 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);
 
 163         public <T> T get(Class<T> clazz, long appId, String restPath) throws HTTPException {
 
 165                 WebClient webClient = null;
 
 166                 Response response = null;
 
 169                 webClient = createClientForApp(appId, restPath);
 
 170                 EcompPortalUtils.logAndSerializeObject(restPath, "GET request =", "no-payload");
 
 173                         if (webClient!=null) {
 
 174                                 response = webClient.get();
 
 176                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
 
 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));
 
 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); 
 
 198         public <T> T post(Class<T> clazz, long appId, Object payload, String restPath) throws HTTPException {
 
 199                 WebClient client = null;
 
 200                 Response response = null;
 
 203                 client = createClientForApp(appId, restPath);
 
 204                 EcompPortalUtils.logAndSerializeObject(restPath, "POST request =", payload);
 
 209                                 response = client.post(payload);
 
 211                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
 
 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));
 
 219                 if (response!=null) {
 
 220                         verifyResponse(response);
 
 222                         //String contentType = response.getHeaderString("Content-Type");
 
 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);
 
 236         public <T> T put(Class<T> clazz, long appId, Object payload, String restPath)  throws HTTPException {
 
 237                 WebClient client = null;
 
 238                 Response response = null;
 
 241                 client = createClientForApp(appId, restPath);
 
 242                 EcompPortalUtils.logAndSerializeObject(restPath, "PUT request =", payload);
 
 246                                 response = client.put(payload);
 
 248                                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to create the Webclient to make the '" + restPath + "' API call.");
 
 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));
 
 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);