Refactor of an AAIRestInterface 15/56615/6
authortgolabek <tomasz.golabek@nokia.com>
Wed, 23 May 2018 09:40:17 +0000 (11:40 +0200)
committergolabek <tomasz.golabek@nokia.com>
Mon, 6 Aug 2018 11:40:06 +0000 (13:40 +0200)
Refactor and some additional tests added

(cherry picked from commit 6d8fa7d179b8de802ae386b317ddd1214eac1c47)

Change-Id: Ibe7583353499352aa81d100b9995b9c74133c447
Issue-ID: VID-229
Signed-off-by: Stern, Ittay (is9613) <is9613@att.com>
[Added proper headers to modified and created files]
Signed-off-by: golabek <tomasz.golabek@nokia.com>
17 files changed:
vid-app-common/src/main/java/org/onap/vid/aai/PombaRestInterface.java
vid-app-common/src/main/java/org/onap/vid/aai/exceptions/HttpClientBuilderException.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/aai/exceptions/InvalidPropertyException.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/aai/util/AAIRestInterface.java
vid-app-common/src/main/java/org/onap/vid/aai/util/HttpsAuthClient.java
vid-app-common/src/main/java/org/onap/vid/aai/util/SSLContextProvider.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/aai/util/ServletRequestHelper.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/aai/util/SystemPropertyHelper.java [new file with mode: 0644]
vid-app-common/src/main/java/org/onap/vid/controllers/WebConfig.java
vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java
vid-app-common/src/test/java/org/onap/vid/aai/util/CustomJacksonJaxBJsonProviderTest.java
vid-app-common/src/test/java/org/onap/vid/aai/util/HttpsAuthClientTest.java
vid-app-common/src/test/java/org/onap/vid/aai/util/ParametrizedAAIRestInterfaceTest.java [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/aai/util/SingleAAIRestInterfaceTest.java [new file with mode: 0644]
vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java
vid-app-common/src/test/java/org/onap/vid/controller/LocalWebConfig.java
vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java

index 73ebf69..c4bc852 100644 (file)
@@ -1,25 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.aai;
 
-import org.onap.vid.aai.util.AAIRestInterface;
-import org.onap.vid.aai.util.HttpClientMode;
-import org.onap.vid.aai.util.HttpsAuthClient;
-import org.onap.vid.utils.Logging;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.vid.aai.util.*;
+import org.onap.vid.utils.Logging;
 import org.springframework.http.HttpMethod;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import java.util.Date;
 import java.util.UUID;
 
 import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY;
 
 public class PombaRestInterface extends AAIRestInterface {
 
-    public PombaRestInterface (HttpsAuthClient httpsAuthClientFactory) {
-        super(httpsAuthClientFactory);
+    public PombaRestInterface (HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper) {
+        super(httpsAuthClientFactory, servletRequestHelper, systemPropertyHelper);
     }
 
     private Client client = null;
@@ -31,8 +49,8 @@ public class PombaRestInterface extends AAIRestInterface {
                 client = httpsAuthClientFactory.getClient(HttpClientMode.UNSECURE);
             }
             catch (Exception e) {
-                logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) +  "<== Exception in REST call to DB in initRestClient" + e.toString());
-                logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) +  "<== Exception in REST call to DB : " + e.toString());
+                logger.info(EELFLoggerDelegate.errorLogger, "Exception in REST call to DB in initRestClient" + e.toString());
+                logger.debug(EELFLoggerDelegate.debugLogger, "Exception in REST call to DB : " + e.toString());
             }
         }
     }
@@ -42,28 +60,26 @@ public class PombaRestInterface extends AAIRestInterface {
         String methodName = "RestPost";
         String transId = UUID.randomUUID().toString();
         try {
-            String responseType = MediaType.APPLICATION_JSON;
             initRestClient();
 
             Logging.logRequest(outgoingRequestsLogger, HttpMethod.POST, url, payload);
             final Response cres = client.target(url)
                     .request()
-                    .accept(responseType)
+                    .accept(MediaType.APPLICATION_JSON)
                     .header(TRANSACTION_ID_HEADER, transId)
                     .header(FROM_APP_ID_HEADER,  fromAppId)
                     .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
                     .post(Entity.entity(payload, MediaType.APPLICATION_JSON));
             Logging.logResponse(outgoingRequestsLogger, HttpMethod.POST, url, cres);
 
-            if (cres.getStatus() == 200 && cres.getStatus() <= 299) {
-                logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
-                logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
+            if (cres.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) {
+                logger.info(EELFLoggerDelegate.errorLogger, getValidResponseLogMessage(methodName));
+                logger.debug(EELFLoggerDelegate.debugLogger, getValidResponseLogMessage(methodName));
             } else {
-                logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " with status="+cres.getStatus()+ URL_DECLARATION +url);
+                logger.debug(EELFLoggerDelegate.debugLogger, getInvalidResponseLogMessage(url, methodName, cres));
             }
-            return cres;
         } catch (Exception e) {
-            logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION +url+ ", Exception: " + e.toString());
+            logger.debug(EELFLoggerDelegate.debugLogger, getFailedResponseLogMessage(url, methodName, e));
         }
         return null;
     }
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/HttpClientBuilderException.java b/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/HttpClientBuilderException.java
new file mode 100644 (file)
index 0000000..ed45fa4
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.exceptions;
+
+public class HttpClientBuilderException extends RuntimeException {
+
+    public HttpClientBuilderException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/InvalidPropertyException.java b/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/InvalidPropertyException.java
new file mode 100644 (file)
index 0000000..11875fb
--- /dev/null
@@ -0,0 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.exceptions;
+
+public class InvalidPropertyException extends Exception {
+}
index ac38b50..6b17c93 100644 (file)
@@ -3,6 +3,7 @@
  * VID
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,25 +23,22 @@ package org.onap.vid.aai.util;
 
 import com.att.eelf.configuration.EELFLogger;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.eclipse.jetty.util.security.Password;
+import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
 import org.onap.vid.aai.ExceptionWithRequestInfo;
 import org.onap.vid.aai.ResponseWithRequestInfo;
+import org.onap.vid.aai.exceptions.InvalidPropertyException;
 import org.onap.vid.utils.Logging;
-import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
-import org.onap.portalsdk.core.util.SystemProperties;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpMethod;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Base64;
-import java.util.Date;
+import java.util.Optional;
 import java.util.UUID;
 
 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
@@ -52,14 +50,11 @@ import static org.onap.vid.utils.Logging.REQUEST_ID_HEADER_KEY;
  */
 public class AAIRestInterface {
 
-       public static final String WITH_STATUS = " with status=";
        /** The logger. */
        protected EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AAIRestInterface.class);
 
        protected final EELFLogger outgoingRequestsLogger = Logging.getRequestsLogger("aai");
 
-       /** The Constant dateFormat. */
-       protected final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
 
        /** The client. */
        private Client client = null;
@@ -69,15 +64,34 @@ public class AAIRestInterface {
 
        @Autowired
        protected HttpsAuthClient httpsAuthClientFactory;
+       private final ServletRequestHelper servletRequestHelper;
+       private final SystemPropertyHelper systemPropertyHelper;
 
-       private String START_STRING = " start";
-       protected String TRANSACTION_ID_HEADER = "X-TransactionId";
-       protected String FROM_APP_ID_HEADER = "X-FromAppId";
-       private String SUCCESSFUL_API_MESSAGE=" REST api POST was successful!";
-       protected String URL_DECLARATION = ", url=";
+       protected static final String START_STRING = " start";
+       protected static final String TRANSACTION_ID_HEADER = "X-TransactionId";
+       protected static final String FROM_APP_ID_HEADER = "X-FromAppId";
+       protected static final String SUCCESSFUL_API_MESSAGE = " REST api call was successful!";
+       protected static final String URL_DECLARATION = ", url=";
 
-       public AAIRestInterface(HttpsAuthClient httpsAuthClientFactory) {
+       public AAIRestInterface(HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper) {
                this.httpsAuthClientFactory = httpsAuthClientFactory;
+               this.servletRequestHelper = servletRequestHelper;
+               this.systemPropertyHelper = systemPropertyHelper;
+               initRestClient();
+       }
+
+       /**
+        * For testing purpose
+        */
+       AAIRestInterface(Optional<Client> client,
+                                        HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper){
+               this.httpsAuthClientFactory = httpsAuthClientFactory;
+               this.servletRequestHelper = servletRequestHelper;
+               this.systemPropertyHelper = systemPropertyHelper;
+               if (client != null && client.isPresent()){
+                       this.client = client.get();
+               }
+
        }
 
        /**
@@ -96,14 +110,13 @@ public class AAIRestInterface {
     }
 
 
-       private void initRestClient(boolean propagateExceptions)
-       {
+       private void initRestClient(boolean propagateExceptions) {
                if (client == null) {
                        try {
-                               client = httpsAuthClientFactory.getClient(HttpClientMode.WITHOUT_KEYSTORE);
+                               client = httpsAuthClientFactory.getClient(HttpClientMode.WITH_KEYSTORE);
                        } catch (Exception e) {
-                               logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) +  "<== Exception in REST call to DB in initRestClient" + e.toString());
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) +  "<== Exception in REST call to DB : " + e.toString());
+                               logger.info(EELFLoggerDelegate.errorLogger, "Exception in REST call to DB in initRestClient" + e.toString());
+                               logger.debug(EELFLoggerDelegate.debugLogger, "Exception in REST call to DB : " + e.toString());
                                if (propagateExceptions) {
                                        ExceptionUtils.rethrow(e);
                                }
@@ -120,10 +133,9 @@ public class AAIRestInterface {
         */
        public void SetRestSrvrBaseURL(String baseURL)
        {
-               if (baseURL == null)
-               {
-                       logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) +  "<== REST Server base URL cannot be null.");
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) +  "<== REST Server base URL cannot be null.");
+               if (baseURL == null) {
+                       logger.info(EELFLoggerDelegate.errorLogger, "REST Server base URL cannot be null.");
+                       logger.debug(EELFLoggerDelegate.debugLogger, "REST Server base URL cannot be null.");
                }
 
                restSrvrBaseURL = baseURL;
@@ -134,8 +146,7 @@ public class AAIRestInterface {
         *
         * @return the rest srvr base URL
         */
-       public String getRestSrvrBaseURL()
-       {
+       public String getRestSrvrBaseURL() {
                return restSrvrBaseURL;
        }
 
@@ -149,81 +160,52 @@ public class AAIRestInterface {
         * @param xml the xml
         * @return the string
         */
-
        public ResponseWithRequestInfo RestGet(String fromAppId, String transId, String requestUri, boolean xml) {
                return RestGet(fromAppId, transId, requestUri, xml, false);
        }
 
        public ResponseWithRequestInfo RestGet(String fromAppId, String transId, String requestUri, boolean xml, boolean propagateExceptions) {
-               String url = null;
+        String methodName = "RestGet";
+               String url = systemPropertyHelper.getFullServicePath(requestUri);
                try {
-                       String methodName = "RestGet";
-                       url = SystemProperties.getProperty(AAIProperties.AAI_SERVER_URL) + requestUri;
-
-                       String responseType = MediaType.APPLICATION_JSON;
-                       if (xml)
-                               responseType = MediaType.APPLICATION_XML;
-
                        initRestClient(propagateExceptions);
 
-                       String clientCert = SystemProperties.getProperty(AAIProperties.AAI_USE_CLIENT_CERT);
-
-                       boolean useClientCert = false;
-                       if (clientCert != null &&
-                                       SystemProperties.getProperty(AAIProperties.AAI_USE_CLIENT_CERT).equalsIgnoreCase("true")) {
-                               useClientCert = true;
-                       }
-
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + START_STRING);
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + url + " for the get REST API");
+                       logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_STRING);
+                       logger.debug(EELFLoggerDelegate.debugLogger, url + " for the get REST API");
 
                        Logging.logRequest(outgoingRequestsLogger, HttpMethod.GET, url);
 
-                       final Response cres;
-                       if (useClientCert == true) {
-                               cres = client.target(url)
-                                               .request()
-                                               .accept(responseType)
-                                               .header(TRANSACTION_ID_HEADER, transId)
-                                               .header(FROM_APP_ID_HEADER, fromAppId)
-                                               .header("Content-Type", MediaType.APPLICATION_JSON)
-                                               .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
-                                               .get();
-                       } else {
-
-                               String vidUsername = SystemProperties.getProperty(AAIProperties.AAI_VID_USERNAME);
-                               String vidPassword = Password.deobfuscate(SystemProperties.getProperty(AAIProperties.AAI_VID_PASSWD_X));
-                               String encodeThis = vidUsername + ":" + vidPassword;
-
-                               cres = client.target(url)
-                                               .request()
-                                               .accept(responseType)
-                                               .header(TRANSACTION_ID_HEADER, transId)
-                                               .header(FROM_APP_ID_HEADER, fromAppId)
-                                               .header("Content-Type", "application/json")
-                                               .header("Authorization", "Basic " + Base64.getEncoder().encodeToString(encodeThis.getBytes("utf-8")))
-                                               .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
-                                               .get();
-                       }
-                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, cres);
-
-                       if (cres.getStatus() == 200) {
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + SUCCESSFUL_API_MESSAGE);
-                               logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + SUCCESSFUL_API_MESSAGE);
+                       final Response response;
+            Invocation.Builder requestBuilder = client.target(url)
+                    .request()
+                    .accept(xml ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
+                    .header(TRANSACTION_ID_HEADER, transId)
+                    .header(FROM_APP_ID_HEADER, fromAppId)
+                    .header("Content-Type", MediaType.APPLICATION_JSON)
+                    .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId());
+            response = systemPropertyHelper.isClientCertEnabled() ?
+                    requestBuilder.get() : authenticateRequest(requestBuilder).get();
+                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.GET, url, response);
+
+                       if (response.getStatusInfo().equals(Response.Status.OK)) {
+                               logger.debug(EELFLoggerDelegate.debugLogger, methodName + SUCCESSFUL_API_MESSAGE);
+                               logger.info(EELFLoggerDelegate.errorLogger, methodName + SUCCESSFUL_API_MESSAGE);
                        } else {
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + WITH_STATUS + cres.getStatus() + URL_DECLARATION + url);
+                               logger.debug(EELFLoggerDelegate.debugLogger, getInvalidResponseLogMessage(url, methodName, response));
                        }
-                       return new ResponseWithRequestInfo(cres, url, HttpMethod.GET);
+                       return new ResponseWithRequestInfo(response, url, HttpMethod.GET);
                } catch (Exception e) {
-                       // no need to ask if "propagateExceptions" because any exception
-                       // at this point should have already obey to the
-                       // "propagateExceptions" flag
-                       throw new ExceptionWithRequestInfo(HttpMethod.GET, defaultIfNull(url, requestUri), e);
+                       logger.debug(EELFLoggerDelegate.debugLogger, getFailedResponseLogMessage(url, methodName, e));
+                       if (propagateExceptions) {
+                throw new ExceptionWithRequestInfo(HttpMethod.GET, defaultIfNull(url, requestUri), e);
+            } else {
+                return new ResponseWithRequestInfo(null, url, HttpMethod.GET);
+            }
                }
        }
 
        protected String extractOrGenerateRequestId() {
-               return Logging.extractOrGenerateRequestId();
+               return servletRequestHelper.extractOrGenerateRequestId();
        }
 
 
@@ -235,38 +217,42 @@ public class AAIRestInterface {
         * @param path the path
         * @return true, if successful
         */
-       public boolean Delete(String sourceID,  String transId,  String path) {
+       public boolean Delete(String sourceID, String transId, String path) {
                String methodName = "Delete";
-               String url="";
                transId += ":" + UUID.randomUUID().toString();
-               logger.debug(dateFormat.format(new Date()) + "<== " +  methodName + START_STRING);
+               logger.debug(methodName + START_STRING);
+               Boolean response = false;
+               String url = systemPropertyHelper.getFullServicePath(path);;
+               try {
 
-               initRestClient();
-               url = SystemProperties.getProperty(AAIProperties.AAI_SERVER_URL) + path;
-               Logging.logRequest(outgoingRequestsLogger, HttpMethod.DELETE, url);
-               final Response cres = client.target(url)
-                               .request()
-                               .accept(MediaType.APPLICATION_JSON)
-                               .header(TRANSACTION_ID_HEADER, transId)
-                               .header(FROM_APP_ID_HEADER,  sourceID)
-                               .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
-                               .delete();
-               Logging.logResponse(outgoingRequestsLogger, HttpMethod.DELETE, url, cres);
-               if (cres.getStatus() == 404) { // resource not found
-                       String msg = "Resource does not exist...: " + cres.getStatus()
-                                       + ":" + cres.readEntity(String.class);
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + msg);
-                       return false;
-               } else if (cres.getStatus() == 200  || cres.getStatus() == 204){
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Resource " + url + " deleted");
-                       return true;
-               } else {
-                       String msg = "Deleting Resource failed: " + cres.getStatus()
-                                       + ":" + cres.readEntity(String.class);
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + msg);
-               }
+                       initRestClient();
+                       Logging.logRequest(outgoingRequestsLogger, HttpMethod.DELETE, url);
+                       final Response cres = client.target(url)
+                                       .request()
+                                       .accept(MediaType.APPLICATION_JSON)
+                                       .header(TRANSACTION_ID_HEADER, transId)
+                                       .header(FROM_APP_ID_HEADER, sourceID)
+                                       .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
+                                       .delete();
+                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.DELETE, url, cres);
+                       if (cres.getStatusInfo().equals(Response.Status.NOT_FOUND)) {
+                               logger.debug(EELFLoggerDelegate.debugLogger, "Resource does not exist...: " + cres.getStatus()
+                                               + ":" + cres.readEntity(String.class));
+                               response = false;
+                       } else if (cres.getStatusInfo().equals(Response.Status.OK) || cres.getStatusInfo().equals(Response.Status.NO_CONTENT)) {
+                               logger.debug(EELFLoggerDelegate.debugLogger, "Resource " + url + " deleted");
+                               logger.info(EELFLoggerDelegate.errorLogger, "Resource " + url + " deleted");
+                               response = true;
+                       } else {
+                               logger.debug(EELFLoggerDelegate.debugLogger, "Deleting Resource failed: " + cres.getStatus()
+                                               + ":" + cres.readEntity(String.class));
+                               response = false;
+                       }
 
-               return false;
+               } catch (Exception e) {
+                       logger.debug(EELFLoggerDelegate.debugLogger, getFailedResponseLogMessage(url, methodName, e));
+               }
+               return response;
        }
 
 
@@ -281,45 +267,33 @@ public class AAIRestInterface {
         */
        public Response RestPut(String fromAppId, String path, String payload, boolean xml) {
                String methodName = "RestPut";
-               String url="";
+               String url=systemPropertyHelper.getFullServicePath(path);
                String transId = UUID.randomUUID().toString();
-               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " +  methodName + START_STRING);
+               logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_STRING);
 
+        Response response = null;
                try {
-
-                       String responseType = MediaType.APPLICATION_JSON;
-                       if (xml)
-                               responseType = "application/xml";
-
                        initRestClient();
-
-                       url = SystemProperties.getProperty(AAIProperties.AAI_SERVER_URL) + path;
-                       String vidUsername = SystemProperties.getProperty(AAIProperties.AAI_VID_USERNAME);
-            String vidPassword = Password.deobfuscate(SystemProperties.getProperty(AAIProperties.AAI_VID_PASSWD_X));
-            String encodeThis = vidUsername + ":" + vidPassword;
-            
                        Logging.logRequest(outgoingRequestsLogger, HttpMethod.PUT, url, payload);
-                       final Response cres = client.target(url)
+                       response = authenticateRequest(client.target(url)
                                        .request()
-                                       .accept(responseType)
+                    .accept(xml ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
                                        .header(TRANSACTION_ID_HEADER, transId)
-                                       .header(FROM_APP_ID_HEADER,  fromAppId)
-                                       .header("Authorization", "Basic " + Base64.getEncoder().encodeToString(encodeThis.getBytes("utf-8")))
+                                       .header(FROM_APP_ID_HEADER,  fromAppId))
                                        .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
                                        .put(Entity.entity(payload, MediaType.APPLICATION_JSON));
-                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.PUT, url, cres);
+                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.PUT, url, response);
 
-                       if (cres.getStatus() == 200 && cres.getStatus() <= 299) {
-                               logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
+                       if (response.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) {
+                               logger.info(EELFLoggerDelegate.errorLogger, getValidResponseLogMessage(methodName));
+                               logger.debug(EELFLoggerDelegate.debugLogger, getValidResponseLogMessage(methodName));
                        } else {
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + WITH_STATUS +cres.getStatus()+ URL_DECLARATION +url);
+                               logger.debug(EELFLoggerDelegate.debugLogger, getInvalidResponseLogMessage(url, methodName, response));
                        }
-                       return cres;
                } catch (Exception e) {
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION +url+ ", Exception: " + e.toString());
+                       logger.debug(EELFLoggerDelegate.debugLogger, getFailedResponseLogMessage(url, methodName, e));
                }
-               return null;
+               return response;
        }
 
 
@@ -335,45 +309,50 @@ public class AAIRestInterface {
         */
        public Response RestPost(String fromAppId, String path, String payload, boolean xml) {
                String methodName = "RestPost";
-               String url="";
+               String url=systemPropertyHelper.getFullServicePath(path);
                String transId = UUID.randomUUID().toString();
-               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " +  methodName + START_STRING);
+               logger.debug(EELFLoggerDelegate.debugLogger, methodName + START_STRING);
 
+        Response response = null;
                try {
-
-                       String responseType = MediaType.APPLICATION_JSON;
-                       if (xml)
-                               responseType = "application/xml";
-
                        initRestClient();
-
-                       url = SystemProperties.getProperty(AAIProperties.AAI_SERVER_URL_BASE) + path;
-                       String vidUsername = SystemProperties.getProperty(AAIProperties.AAI_VID_USERNAME);
-                       String vidPassword = Password.deobfuscate(SystemProperties.getProperty(AAIProperties.AAI_VID_PASSWD_X));
-                       String encodeThis = vidUsername + ":" + vidPassword;
-                       
                        Logging.logRequest(outgoingRequestsLogger, HttpMethod.POST, url, payload);
-                       final Response cres = client.target(url)
+                       response = authenticateRequest(client.target(systemPropertyHelper.getFullServicePath(path))
                                        .request()
-                                       .accept(responseType)
+                    .accept(xml ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON)
                                        .header(TRANSACTION_ID_HEADER, transId)
-                                       .header(FROM_APP_ID_HEADER,  fromAppId)
-                                       .header("Authorization", "Basic " + Base64.getEncoder().encodeToString(encodeThis.getBytes("utf-8")))
+                                       .header(FROM_APP_ID_HEADER,  fromAppId))
                                        .header(REQUEST_ID_HEADER_KEY, extractOrGenerateRequestId())
                                        .post(Entity.entity(payload, MediaType.APPLICATION_JSON));
-                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.POST, url, cres);
+                       Logging.logResponse(outgoingRequestsLogger, HttpMethod.POST, url, response);
 
-                       if (cres.getStatus() == 200 && cres.getStatus() <= 299) {
-                               logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION);
+                       if (response.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) {
+                               logger.info(EELFLoggerDelegate.errorLogger, getValidResponseLogMessage(methodName));
+                               logger.debug(EELFLoggerDelegate.debugLogger, getValidResponseLogMessage(methodName));
                        } else {
-                               logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + WITH_STATUS +cres.getStatus()+ URL_DECLARATION +url);
+                               logger.debug(EELFLoggerDelegate.debugLogger, getInvalidResponseLogMessage(url, methodName, response));
                        }
-                       return cres;
                } catch (Exception e) {
-                       logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + URL_DECLARATION +url+ ", Exception: " + e.toString());
+                       logger.debug(EELFLoggerDelegate.debugLogger, getFailedResponseLogMessage(url, methodName, e));
                }
-               return null;
+               return response;
+       }
+
+       protected String getFailedResponseLogMessage(String path, String methodName, Exception e) {
+               return methodName + URL_DECLARATION + path + ", Exception: " + e.toString();
+       }
+
+       protected String getValidResponseLogMessage(String methodName) {
+               return methodName + URL_DECLARATION;
+       }
+
+       protected String getInvalidResponseLogMessage(String path, String methodName, Response cres) {
+               return methodName + " with status=" + cres.getStatus() + URL_DECLARATION + path;
+       }
+
+       private Invocation.Builder authenticateRequest(Invocation.Builder requestBuilder) throws InvalidPropertyException, UnsupportedEncodingException {
+               return requestBuilder
+                               .header("Authorization", "Basic " + systemPropertyHelper.getEncodedCredentials());
        }
 
 }
index f1eafe4..15f8143 100644 (file)
@@ -3,6 +3,7 @@
  * VID
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 package org.onap.vid.aai.util;
 
 
-import org.eclipse.jetty.util.security.Password;
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
-import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.aai.exceptions.HttpClientBuilderException;
 
-import javax.net.ssl.*;
+import javax.net.ssl.HttpsURLConnection;
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.security.*;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
+import java.nio.file.FileSystems;
+import java.security.GeneralSecurityException;
+
+import static org.onap.vid.aai.util.HttpClientMode.WITH_KEYSTORE;
 
 /**
  * The Class HttpsAuthClient.
  */
 public class HttpsAuthClient {
 
+    private static final String SSL_TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String SSL_TRUST_STORE_PASS_WORD = "javax.net.ssl.trustStorePassword";
+
+    private final SystemPropertyHelper systemPropertyHelper;
+    private final SSLContextProvider sslContextProvider;
 
-    public HttpsAuthClient(String certFilePath) {
+    public HttpsAuthClient(String certFilePath, SystemPropertyHelper systemPropertyHelper, SSLContextProvider sslContextProvider) {
         this.certFilePath = certFilePath;
+        this.systemPropertyHelper = systemPropertyHelper;
+        this.sslContextProvider = sslContextProvider;
     }
 
     private final String certFilePath;
@@ -52,62 +58,24 @@ public class HttpsAuthClient {
     /** The logger. */
     static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(HttpsAuthClient.class);
 
+
     /**
      * Gets the client.
      *
      * @return the client
-     * @throws KeyManagementException the key management exception
      */
     public Client getClient(HttpClientMode mode) throws GeneralSecurityException, IOException {
-        ClientConfig config = new ClientConfig();
-        SSLContext ctx;
+        ClientConfig config = prepareClientConfig(mode);
 
         try {
-            String truststorePath = getCertificatesPath() + org.onap.vid.aai.util.AAIProperties.FILESEPARTOR + SystemProperties.getProperty(org.onap.vid.aai.util.AAIProperties.AAI_TRUSTSTORE_FILENAME);
-            String truststorePassword = SystemProperties.getProperty(org.onap.vid.aai.util.AAIProperties.AAI_TRUSTSTORE_PASSWD_X);
-            String decryptedTruststorePassword = Password.deobfuscate(truststorePassword);
-
-            System.setProperty("javax.net.ssl.trustStore", truststorePath);
-            System.setProperty("javax.net.ssl.trustStorePassword", decryptedTruststorePassword);
-
-            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
-                public boolean verify(String string, SSLSession ssls) {
-                    return true;
-                }
-            });
-            ctx = SSLContext.getInstance("TLSv1.2");
-            KeyManager[] keyManagers = null;
-            TrustManager[] trustManagers = getTrustManager(mode);
-
-            switch (mode) {
-                case WITH_KEYSTORE:
-                    String aaiKeystorePath = getCertificatesPath() + org.onap.vid.aai.util.AAIProperties.FILESEPARTOR + SystemProperties.getProperty(org.onap.vid.aai.util.AAIProperties.AAI_KEYSTORE_FILENAME);
-                    String aaiKeystorePassword = SystemProperties.getProperty(org.onap.vid.aai.util.AAIProperties.AAI_KEYSTORE_PASSWD_X);
-                    config.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, Boolean.TRUE);
-                    config.connectorProvider(new HttpUrlConnectorProvider().useSetMethodWorkaround());
-                    KeyManagerFactory kmf = getKeyManagerFactory(aaiKeystorePath, aaiKeystorePassword);
-                    keyManagers = kmf.getKeyManagers();
-                    break;
-
-                case WITHOUT_KEYSTORE:
-                    config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
-                    break;
-
-                default:
-                    logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up config. HttpClientMode is " + mode);
-            }
-
-            ctx.init(keyManagers, trustManagers, null);
-            return ClientBuilder.newBuilder()
-                    .sslContext(ctx)
-                    .hostnameVerifier(new HostnameVerifier() {
-                        @Override
-                        public boolean verify(String s, SSLSession sslSession) {
-                            return true;
-                        }
-                    }).withConfig(config)
-                    .build()
-                    .register(org.onap.vid.aai.util.CustomJacksonJaxBJsonProvider.class);
+            setSystemProperties();
+
+            ignoreHostname();
+
+            return systemPropertyHelper.isClientCertEnabled() ?
+                    getTrustedClient(config, getKeystorePath(), systemPropertyHelper.getDecryptedKeystorePassword(), mode)
+                    : getUntrustedClient(config);
+
         } catch (Exception e) {
             logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up config", e);
             throw e;
@@ -115,57 +83,44 @@ public class HttpsAuthClient {
 
     }
 
-    /**
-     * @param aaiKeystorePath
-     * @param aaiKeystorePassword - in OBF format
-     * @return
-     * @throws NoSuchAlgorithmException
-     * @throws KeyStoreException
-     * @throws IOException
-     * @throws CertificateException
-     * @throws UnrecoverableKeyException
-     */
-    private KeyManagerFactory getKeyManagerFactory(String aaiKeystorePath, String aaiKeystorePassword) throws IOException, GeneralSecurityException {
-        String aaiDecryptedKeystorePassword = Password.deobfuscate(aaiKeystorePassword);
-        KeyManagerFactory kmf = null;
-        try (FileInputStream fin = new FileInputStream(aaiKeystorePath)) {
-            kmf = KeyManagerFactory.getInstance("SunX509");
-            KeyStore ks = KeyStore.getInstance("PKCS12");
-            char[] pwd = aaiDecryptedKeystorePassword.toCharArray();
-            ks.load(fin, pwd);
-            kmf.init(ks, pwd);
-        } catch (Exception e) {
-            logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up kmf");
-            logger.error(EELFLoggerDelegate.errorLogger, "Error setting up kmf (keystore path: {}, obfuascated keystore password: {})", aaiKeystorePath, aaiKeystorePassword, e);
-            throw e;
-        }
-        return kmf;
+    private void ignoreHostname() {
+        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
     }
 
-    private String getCertificatesPath() {
-        return certFilePath;
+    private Client getUntrustedClient(ClientConfig config) {
+        return ClientBuilder.newBuilder().withConfig(config).build().register(CustomJacksonJaxBJsonProvider.class);
     }
 
-    private TrustManager[] getTrustManager(HttpClientMode httpClientMode) {
-        //Creating a trustManager that will accept all certificates.
-        //TODO - remove this one the POMBA certificate is added to the tomcat_keystore file
-        TrustManager[] trustAllCerts = null;
-        if (httpClientMode == HttpClientMode.UNSECURE) {
+    private Client getTrustedClient(ClientConfig config, String keystorePath, String keystorePassword, HttpClientMode httpClientMode) throws HttpClientBuilderException {
+        return ClientBuilder.newBuilder()
+                .sslContext(sslContextProvider.getSslContext(keystorePath, keystorePassword, httpClientMode))
+                .hostnameVerifier((s, sslSession) -> true)
+                .withConfig(config)
+                .build()
+                .register(CustomJacksonJaxBJsonProvider.class);
+    }
 
-            trustAllCerts = new TrustManager[]{new X509TrustManager() {
-                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-                    return null;
-                }
+    private String getKeystorePath() {
+        return getCertificatesPath() + FileSystems.getDefault().getSeparator() + systemPropertyHelper.getAAIKeystoreFilename();
+    }
 
-                public void checkClientTrusted(X509Certificate[] certs, String authType) {
-                }
+    private void setSystemProperties() {
+        System.setProperty(SSL_TRUST_STORE, getCertificatesPath() + FileSystems.getDefault().getSeparator() +
+                systemPropertyHelper.getAAITruststoreFilename().orElse(""));
+        System.setProperty(SSL_TRUST_STORE_PASS_WORD, systemPropertyHelper.getDecryptedTruststorePassword());
+    }
 
-                public void checkServerTrusted(X509Certificate[] certs, String authType) {
-                }
-            }};
+    private ClientConfig prepareClientConfig(HttpClientMode mode) {
+        ClientConfig config = new ClientConfig();
+        if (mode.equals(WITH_KEYSTORE)) {
+            config.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, Boolean.TRUE);
+            config.connectorProvider(new HttpUrlConnectorProvider().useSetMethodWorkaround());
         }
-        return trustAllCerts;
+        return config;
     }
 
+    private String getCertificatesPath() {
+        return certFilePath;
+    }
 
 }
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/SSLContextProvider.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/SSLContextProvider.java
new file mode 100644 (file)
index 0000000..90d2be9
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.util;
+
+import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.vid.aai.exceptions.HttpClientBuilderException;
+
+import javax.net.ssl.*;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+public class SSLContextProvider {
+
+    private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SSLContextProvider.class);
+
+    public SSLContext getSslContext(String keystorePath, String keystorePassword, HttpClientMode httpClientMode) throws HttpClientBuilderException {
+        try {
+            final SSLContext ctx = SSLContext.getInstance("TLSv1.2");
+            KeyManager[] keyManagers = getKeyManagerFactory(keystorePath, keystorePassword, httpClientMode);
+            ctx.init(keyManagers, getTrustManager(httpClientMode), null);
+            return ctx;
+        } catch (IOException | GeneralSecurityException e) {
+            logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up ssl context.");
+            throw new HttpClientBuilderException(e);
+        }
+    }
+
+    /**
+     * @param keystorePath
+     * @param keystorePassword - in clear
+     * @return
+     * @throws IOException
+     * @throws GeneralSecurityException
+     */
+    private KeyManager[] getKeyManagerFactory(String keystorePath, String keystorePassword, HttpClientMode httpClientMode) throws IOException, GeneralSecurityException {
+        switch (httpClientMode) {
+            case WITH_KEYSTORE:
+                final KeyManagerFactory kmf;
+                try (FileInputStream fin = new FileInputStream(keystorePath)) {
+                    kmf = KeyManagerFactory.getInstance("SunX509");
+                    KeyStore ks = KeyStore.getInstance("PKCS12");
+                    char[] pwd = keystorePassword.toCharArray();
+                    ks.load(fin, pwd);
+                    kmf.init(ks, pwd);
+                } catch (Exception e) {
+                    logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up kmf");
+                    logger.error(EELFLoggerDelegate.errorLogger, "Error setting up kmf (keystore path: {}, deobfuascated keystore password: {})", keystorePath, keystorePassword, e);
+                    throw e;
+                }
+                return kmf.getKeyManagers();
+
+            case WITHOUT_KEYSTORE:
+                return null;
+
+            default:
+                logger.debug(EELFLoggerDelegate.debugLogger, "Error setting up getKeyManagerFactory. HttpClientMode is " + httpClientMode);
+                throw new IllegalStateException("Error setting up getKeyManagerFactory. HttpClientMode is " + httpClientMode);
+        }
+    }
+
+    private TrustManager[] getTrustManager(HttpClientMode httpClientMode) {
+        //Creating a trustManager that will accept all certificates.
+        //TODO - remove this one the POMBA certificate is added to the tomcat_keystore file
+        TrustManager[] trustAllCerts = null;
+        if (httpClientMode == HttpClientMode.UNSECURE) {
+
+            trustAllCerts = new TrustManager[]{new X509TrustManager() {
+                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+                    return new java.security.cert.X509Certificate[]{};
+                }
+
+                public void checkClientTrusted(X509Certificate[] certs, String authType) {
+                    // trust all
+                }
+
+                public void checkServerTrusted(X509Certificate[] certs, String authType) {
+                    // trust all
+                }
+            }};
+        }
+        return trustAllCerts;
+    }
+
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/ServletRequestHelper.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/ServletRequestHelper.java
new file mode 100644 (file)
index 0000000..6480bef
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.util;
+
+import org.onap.vid.utils.Logging;
+
+/**
+ * Wrapper for getting current context attributes
+ */
+public class ServletRequestHelper {
+
+    public String extractOrGenerateRequestId() {
+        return Logging.extractOrGenerateRequestId();
+    }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/SystemPropertyHelper.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/SystemPropertyHelper.java
new file mode 100644 (file)
index 0000000..ebf39c4
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.util;
+
+import org.eclipse.jetty.util.security.Password;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.aai.exceptions.InvalidPropertyException;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
+import java.util.Optional;
+
+public class SystemPropertyHelper {
+
+    public Optional<String> getAAIUseClientCert(){
+        return getSystemProperty(AAIProperties.AAI_USE_CLIENT_CERT);
+    }
+
+    public Optional<String> getAAIServerUrl(){
+        return getSystemProperty(AAIProperties.AAI_SERVER_URL);
+    }
+
+    public Optional<String> getAAIVIDUsername(){
+        return getSystemProperty(AAIProperties.AAI_VID_USERNAME);
+    }
+
+    public Optional<String> getAAIVIDPasswd(){
+        return getSystemProperty(AAIProperties.AAI_VID_PASSWD_X);
+    }
+
+    public Optional<String> getAAITruststorePasswd(){
+        return getSystemProperty(AAIProperties.AAI_TRUSTSTORE_PASSWD_X);
+    }
+
+    public Optional<String> getAAITruststoreFilename(){
+        return getSystemProperty(AAIProperties.AAI_TRUSTSTORE_FILENAME);
+    }
+
+    public Optional<String> getAAIKeystoreFilename(){
+        return getSystemProperty(AAIProperties.AAI_KEYSTORE_FILENAME);
+    }
+
+    public Optional<String> getAAIKeystorePasswd(){
+        return getSystemProperty(AAIProperties.AAI_KEYSTORE_PASSWD_X);
+    }
+
+    public boolean isClientCertEnabled() {
+        return getAAIUseClientCert().orElse("false").equalsIgnoreCase("true");
+    }
+
+    public String getFullServicePath(String path) {
+        return getAAIServerUrl().orElse("") + path;
+    }
+
+    public String getEncodedCredentials() throws InvalidPropertyException, UnsupportedEncodingException {
+        String vidUsername = getAAIVIDUsername().orElseThrow(InvalidPropertyException::new);
+        String vidPassword = Password.deobfuscate(getAAIVIDPasswd().orElseThrow(InvalidPropertyException::new));
+        return Base64.getEncoder().encodeToString((vidUsername + ":" + vidPassword).getBytes("utf-8"));
+    }
+
+    public String getDecryptedTruststorePassword(){
+        return Password.deobfuscate(getAAITruststorePasswd().orElse(""));
+    }
+
+    public String getDecryptedKeystorePassword(){
+        return Password.deobfuscate(getAAIKeystorePasswd().orElse(""));
+    }
+
+    private Optional<String> getSystemProperty(String propertyKey){
+        return Optional.ofNullable(SystemProperties.getProperty(propertyKey));
+    }
+}
index 22e4760..98c0c38 100644 (file)
@@ -1,10 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.controllers;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.onap.vid.aai.*;
 import org.onap.vid.aai.model.PortDetailsTranslator;
-import org.onap.vid.aai.util.AAIRestInterface;
-import org.onap.vid.aai.util.HttpsAuthClient;
+import org.onap.vid.aai.util.*;
 import org.onap.vid.asdc.AsdcClient;
 import org.onap.vid.asdc.parser.ToscaParserImpl2;
 import org.onap.vid.asdc.rest.RestfulAsdcClient;
@@ -66,19 +86,34 @@ public class WebConfig {
     }
 
     @Bean(name = "aaiRestInterface")
-    public AAIRestInterface aaiRestInterface(HttpsAuthClient httpsAuthClientFactory) {
-        return new AAIRestInterface(httpsAuthClientFactory);
+    public AAIRestInterface aaiRestInterface(HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper) {
+        return new AAIRestInterface(httpsAuthClientFactory, servletRequestHelper, systemPropertyHelper);
+    }
+
+    @Bean
+    public PombaRestInterface getPombaRestInterface(HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper) {
+        return new PombaRestInterface(httpsAuthClientFactory, servletRequestHelper, systemPropertyHelper);
+    }
+
+    @Bean
+    public SSLContextProvider sslContextProvider() {
+        return new SSLContextProvider();
+    }
+
+    @Bean
+    public SystemPropertyHelper systemPropertyHelper() {
+        return new SystemPropertyHelper();
     }
 
     @Bean
-    public PombaRestInterface getPombaRestInterface(HttpsAuthClient httpsAuthClientFactory) {
-        return new PombaRestInterface(httpsAuthClientFactory);
+    public ServletRequestHelper servletRequestHelper() {
+        return new ServletRequestHelper();
     }
 
     @Bean
-    public HttpsAuthClient httpsAuthClientFactory(ServletContext servletContext) {
+    public HttpsAuthClient httpsAuthClientFactory(ServletContext servletContext, SystemPropertyHelper systemPropertyHelper, SSLContextProvider sslContextProvider) {
         final String certFilePath = new File(servletContext.getRealPath("/WEB-INF/cert/")).getAbsolutePath();
-        return new HttpsAuthClient(certFilePath);
+        return new HttpsAuthClient(certFilePath, systemPropertyHelper, sslContextProvider);
     }
 
     @Bean
index 32e894d..76d1d4a 100644 (file)
@@ -1,3 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.aai;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -8,21 +29,23 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.commons.lang3.reflect.FieldUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.mockito.Mockito;
+import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.portalsdk.core.util.SystemProperties;
 import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
 import org.onap.vid.aai.model.AaiNodeQueryResponse;
 import org.onap.vid.aai.model.ResourceType;
 import org.onap.vid.aai.util.AAIRestInterface;
 import org.onap.vid.aai.util.HttpsAuthClient;
+import org.onap.vid.aai.util.ServletRequestHelper;
+import org.onap.vid.aai.util.SystemPropertyHelper;
+import org.onap.vid.controllers.LocalWebConfig;
 import org.onap.vid.exceptions.GenericUncheckedException;
 import org.onap.vid.model.Subscriber;
 import org.onap.vid.model.SubscriberList;
 import org.onap.vid.model.probes.ExternalComponentStatus;
 import org.onap.vid.model.probes.HttpRequestMetadata;
 import org.onap.vid.model.probes.StatusMetadata;
-import org.onap.vid.controllers.LocalWebConfig;
 import org.onap.vid.testUtils.TestUtils;
-import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
-import org.onap.portalsdk.core.util.SystemProperties;
 import org.springframework.http.HttpMethod;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -398,7 +421,7 @@ public class AaiClientTest {
         Response responseMock = mocks.getFakeResponse();
 
         // prepare real AAIRestInterface and AaiClient, and wire mocks
-        AAIRestInterface aaiRestInterface = new AAIRestInterface(httpsAuthClientMock);
+        AAIRestInterface aaiRestInterface = new AAIRestInterface(httpsAuthClientMock, new ServletRequestHelper(), new SystemPropertyHelper());
         final AaiClient aaiClient = new AaiClient(aaiRestInterface, null);
         when(httpsAuthClientMock.getClient(any())).thenReturn(javaxClientMock);
 
index dcd962f..f2b01f0 100644 (file)
@@ -1,5 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.aai.util;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationConfig;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.SerializationConfig;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.junit.Assert;
 import org.junit.Test;
 
 public class CustomJacksonJaxBJsonProviderTest {
@@ -9,11 +36,19 @@ public class CustomJacksonJaxBJsonProviderTest {
     }
 
     @Test
-    public void testGetMapper() throws Exception {
-        CustomJacksonJaxBJsonProvider testSubject;
+    public void testMapperHasCorrectConfig() throws Exception {
+        CustomJacksonJaxBJsonProvider testSubject = createTestSubject();
+        DeserializationConfig deserializationConfig = testSubject.getMapper().getDeserializationConfig();
+        SerializationConfig serializationConfig = testSubject.getMapper().getSerializationConfig();
+
+        Assert.assertFalse(serializationConfig.hasSerializationFeatures(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS.getMask()));
+        Assert.assertFalse(serializationConfig.hasSerializationFeatures(SerializationFeature.INDENT_OUTPUT.getMask()));
+        Assert.assertFalse(serializationConfig.hasSerializationFeatures(SerializationFeature.WRAP_ROOT_VALUE.getMask()));
+        Assert.assertFalse(serializationConfig.hasSerializationFeatures(SerializationFeature.CLOSE_CLOSEABLE.getMask()));
+
+        Assert.assertFalse(deserializationConfig.hasDeserializationFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES.getMask()));
+        Assert.assertFalse(deserializationConfig.hasDeserializationFeatures(DeserializationFeature.UNWRAP_ROOT_VALUE.getMask()));
 
-        // default test
-        testSubject = createTestSubject();
-        testSubject.getMapper();
+        Assert.assertEquals(serializationConfig.getSerializationInclusion(), JsonInclude.Include.NON_NULL);
     }
 }
\ No newline at end of file
index a26c431..f000dc8 100644 (file)
@@ -1,22 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.aai.util;
 
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.vid.aai.exceptions.HttpClientBuilderException;
+
+import javax.net.ssl.SSLContext;
+import java.util.Optional;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+@RunWith(MockitoJUnitRunner.class)
 public class HttpsAuthClientTest {
+    @Mock
+    private SystemPropertyHelper systemPropertyHelper;
+    @Mock
+    private SSLContextProvider sslContextProvider;
+    @Mock
+    private SSLContext sslContext;
+
+    public static final String CERT_FILE_PATH = "any_path";
 
     /*
     TO BE IMPLEMENTED
     
     private HttpsAuthClient createTestSubject() {
-        return new HttpsAuthClient();
+        return new HttpsAuthClient(systemPropertyHelper, sslContextProvider);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        when(systemPropertyHelper.getAAITruststoreFilename()).thenReturn(Optional.of("filename"));
+        when(systemPropertyHelper.getEncodedTruststorePassword()).thenReturn("password");
+    }
+
+    @Test(expected = HttpClientBuilderException.class)
+    public void testHttpClientBuilderExceptionOnGetClient() throws HttpClientBuilderException {
+        //when
+        when(systemPropertyHelper.getAAIUseClientCert()).thenReturn(Optional.of("true"));
+        when(sslContextProvider.getSslContext(anyString(), anyString())).thenThrow(new HttpClientBuilderException());
+        createTestSubject().getClient("nonExistingFile");
+    }
+
+    @Test
+    public void testGetSecuredClient() throws Exception {
+        // when
+        when(systemPropertyHelper.getAAIUseClientCert()).thenReturn(Optional.of("true"));
+        when(sslContextProvider.getSslContext(anyString(), anyString())).thenReturn(sslContext);
+        createTestSubject().getClient(CERT_FILE_PATH);
+
+        //then
+        verify(sslContextProvider).getSslContext(anyString(), anyString());
     }
 
     @Test
-    public void testGetClient() throws Exception {
-        String certFilePath = "";
+    public void testGetUnsecuredClient() throws Exception {
+        // when
+        when(systemPropertyHelper.getAAIUseClientCert()).thenReturn(Optional.of("false"));
+        when(sslContextProvider.getSslContext(anyString(), anyString())).thenReturn(sslContext);
+        createTestSubject().getClient(CERT_FILE_PATH);
 
-        // default test
-        HttpsAuthClient.getClient(certFilePath);
+        //then
+        verify(sslContextProvider, never()).getSslContext(anyString(), anyString());
     }
     */
 }
\ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/util/ParametrizedAAIRestInterfaceTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/util/ParametrizedAAIRestInterfaceTest.java
new file mode 100644 (file)
index 0000000..94e749a
--- /dev/null
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.aai.exceptions.InvalidPropertyException;
+import org.testng.Assert;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.UUID;
+
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(Parameterized.class)
+public class ParametrizedAAIRestInterfaceTest {
+
+    private static final String PATH = "path";
+    private static final String HTTP_LOCALHOST = "http://localhost/";
+    @Mock
+    private Client client;
+    @Mock
+    private WebTarget webTarget;
+    @Mock
+    private Invocation.Builder builder;
+    @Mock
+    private ServletRequestHelper servletRequestHelper;
+    @Mock
+    private HttpsAuthClient httpsAuthClient;
+    @Mock
+    private HttpServletRequest httpServletRequest;
+    @Mock
+    private Response response;
+    @Mock
+    private SystemPropertyHelper systemPropertyHelper;
+
+    private AAIRestInterface testSubject;
+    private Response.Status status;
+
+    @Parameterized.Parameters
+    public static Collection<Object> data() {
+        return Arrays.asList(OK, NO_CONTENT);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mockSystemProperties();
+        testSubject = createTestSubject();
+        when(client.target(HTTP_LOCALHOST+PATH)).thenReturn(webTarget);
+        when(webTarget.request()).thenReturn(builder);
+        when(builder.accept(Mockito.anyString())).thenReturn(builder);
+        when(builder.header(Mockito.anyString(), Mockito.anyString())).thenReturn(builder);
+        when(servletRequestHelper.extractOrGenerateRequestId()).thenReturn(UUID.randomUUID().toString());
+    }
+
+    public ParametrizedAAIRestInterfaceTest(Response.Status status) {
+        this.status = status;
+    }
+
+    private AAIRestInterface createTestSubject() {
+        return new AAIRestInterface(Optional.of(client), httpsAuthClient, servletRequestHelper, systemPropertyHelper);
+    }
+
+    @Test
+    public void testRestDeleteWithValidResponse() throws Exception {
+        // given
+        String methodName = "Delete";
+
+        // when
+        when(builder.delete()).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(status);
+        boolean finalResponse = testSubject.Delete("", "", PATH);
+
+        // then
+        verify(builder).delete();
+        Assert.assertTrue(finalResponse);
+    }
+
+    private void mockSystemProperties() throws UnsupportedEncodingException, InvalidPropertyException {
+        when(systemPropertyHelper.getAAIServerUrl()).thenReturn(Optional.of(HTTP_LOCALHOST));
+        when(systemPropertyHelper.getAAIUseClientCert()).thenReturn(Optional.of("cert"));
+        when(systemPropertyHelper.getAAIVIDPasswd()).thenReturn(Optional.of("passwd"));
+        when(systemPropertyHelper.getAAIVIDUsername()).thenReturn(Optional.of("user"));
+        when(systemPropertyHelper.getEncodedCredentials()).thenReturn("someCredentials");
+        when(systemPropertyHelper.getFullServicePath(Mockito.anyString())).thenReturn("http://localhost/path");
+    }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/util/SingleAAIRestInterfaceTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/util/SingleAAIRestInterfaceTest.java
new file mode 100644 (file)
index 0000000..288b891
--- /dev/null
@@ -0,0 +1,307 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.aai.util;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.vid.aai.exceptions.InvalidPropertyException;
+import org.testng.Assert;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.UnsupportedEncodingException;
+import java.util.Optional;
+import java.util.UUID;
+
+import static javax.ws.rs.core.Response.Status.*;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SingleAAIRestInterfaceTest {
+
+    private static final String PATH = "path";
+    private static final String HTTP_LOCALHOST = "http://localhost/";
+    @Mock
+    private Client client;
+    @Mock
+    private WebTarget webTarget;
+    @Mock
+    private Invocation.Builder builder;
+    @Mock
+    private ServletRequestHelper servletRequestHelper;
+    @Mock
+    private HttpsAuthClient httpsAuthClient;
+    @Mock
+    private HttpServletRequest httpServletRequest;
+    @Mock
+    private Response response;
+    @Mock
+    private SystemPropertyHelper systemPropertyHelper;
+
+    private AAIRestInterface testSubject;
+
+    @Before
+    public void setUp() throws Exception {
+        mockSystemProperties();
+        testSubject = createTestSubject();
+        when(client.target(HTTP_LOCALHOST+PATH)).thenReturn(webTarget);
+        when(webTarget.request()).thenReturn(builder);
+        when(builder.accept(Mockito.anyString())).thenReturn(builder);
+        when(builder.header(Mockito.anyString(), Mockito.anyString())).thenReturn(builder);
+        when(servletRequestHelper.extractOrGenerateRequestId()).thenReturn(UUID.randomUUID().toString());
+    }
+
+    private AAIRestInterface createTestSubject() {
+        return new AAIRestInterface(Optional.of(client), httpsAuthClient, servletRequestHelper, systemPropertyHelper);
+    }
+
+    @Test
+    public void testEncodeURL() throws Exception {
+        String nodeKey = "some unusual uri";
+        Assert.assertEquals(testSubject.encodeURL(nodeKey), "some%20unusual%20uri");
+    }
+
+    @Test
+    public void testSetRestSrvrBaseURLWithNullValue() throws Exception {
+        testSubject.SetRestSrvrBaseURL(null);
+    }
+
+    @Test
+    public void testSetRestSrvrBaseURL() throws Exception {
+        String baseUrl = "anything";
+        testSubject.SetRestSrvrBaseURL(baseUrl);
+        Assert.assertEquals(testSubject.getRestSrvrBaseURL(), baseUrl);
+    }
+
+    @Test
+    public void testRestJsonPutWithResponse200() throws Exception {
+        // given
+        String methodName = "RestPut";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.put(Mockito.any(Entity.class))).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(OK);
+        Response finalResponse = testSubject.RestPut("", PATH, payload, false);
+
+        // then
+        verify(builder).put(entity);
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testFailedRestJsonPut() throws Exception {
+        // given
+        String methodName = "RestPut";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.put(Mockito.any(Entity.class))).thenThrow(new RuntimeException());
+        Response finalResponse = testSubject.RestPut("", PATH, payload, false);
+
+        // then
+        verify(builder).put(entity);
+        Assert.assertEquals(finalResponse, null);
+    }
+
+    @Test
+    public void testRestJsonPutWithResponse400() throws Exception {
+        // given
+        String methodName = "RestPut";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.put(Mockito.any(Entity.class))).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(BAD_REQUEST);
+        when(response.getStatus()).thenReturn(BAD_REQUEST.getStatusCode());
+        Response finalResponse = testSubject.RestPut("", PATH, payload, false);
+
+        // then
+        verify(builder).put(entity);
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testRestPostWithResponse200() throws Exception {
+        // given
+        String methodName = "RestPost";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.post(Mockito.any(Entity.class))).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(OK);
+        Response finalResponse = testSubject.RestPost("", PATH, payload, false);
+
+        // then
+        verify(builder).post(entity);
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testRestPostWithResponse400() throws Exception {
+        // given
+        String methodName = "RestPost";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.post(Mockito.any(Entity.class))).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(BAD_REQUEST);
+        when(response.getStatus()).thenReturn(BAD_REQUEST.getStatusCode());
+        Response finalResponse = testSubject.RestPost("", PATH, payload, false);
+
+        // then
+        verify(builder).post(entity);
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testFailedRestPost() throws Exception {
+        // given
+        String methodName = "RestPost";
+        String payload = "{\"id\": 1}";
+        Entity<String> entity = Entity.entity(payload, MediaType.APPLICATION_JSON);
+
+        // when
+        when(builder.post(Mockito.any(Entity.class))).thenThrow(new RuntimeException());
+        Response finalResponse = testSubject.RestPost("", PATH, payload, false);
+
+        // then
+        verify(builder).post(entity);
+        Assert.assertEquals(finalResponse, null);
+    }
+
+    @Test
+    public void testRestDeleteWithResponse400() throws Exception {
+        // given
+        String methodName = "Delete";
+
+        // when
+        when(builder.delete()).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(BAD_REQUEST);
+        String reason = "Any reason";
+        when(response.readEntity(String.class)).thenReturn(reason);
+        when(response.getStatus()).thenReturn(BAD_REQUEST.getStatusCode());
+        boolean finalResponse = testSubject.Delete("", "", PATH);
+
+        // then
+        verify(builder).delete();
+        Assert.assertFalse(finalResponse);
+    }
+
+    @Test
+    public void testRestDeleteWithResponse404() throws Exception {
+        // given
+        String methodName = "Delete";
+
+        // when
+        when(builder.delete()).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(NOT_FOUND);
+        String reason = "Any reason";
+        when(response.readEntity(String.class)).thenReturn(reason);
+        when(response.getStatus()).thenReturn(NOT_FOUND.getStatusCode());
+        boolean finalResponse = testSubject.Delete("", "", PATH);
+
+        // then
+        verify(builder).delete();
+        Assert.assertFalse(finalResponse);
+    }
+
+    @Test
+    public void testFailedRestDelete() throws Exception {
+        // given
+        String methodName = "Delete";
+
+        // when
+        when(builder.delete()).thenThrow(new RuntimeException());
+        boolean finalResponse = testSubject.Delete("", "", PATH);
+
+        // then
+        verify(builder).delete();
+        Assert.assertFalse(finalResponse);
+    }
+
+    @Test
+    public void testRestJsonGetWithResponse200() throws Exception {
+        // given
+        String methodName = "RestGet";
+
+        // when
+        when(builder.get()).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(OK);
+        Response finalResponse = testSubject.RestGet("", "", PATH, false).getResponse();
+
+        // then
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testRestJsonGetWithResponse400() throws Exception {
+        // given
+        String methodName = "RestGet";
+
+        // when
+        when(builder.get()).thenReturn(response);
+        when(response.getStatusInfo()).thenReturn(BAD_REQUEST);
+        when(response.getStatus()).thenReturn(BAD_REQUEST.getStatusCode());
+        Response finalResponse = testSubject.RestGet("", "", PATH, false).getResponse();
+
+        // then
+        Assert.assertEquals(response, finalResponse);
+    }
+
+    @Test
+    public void testFailedRestGet() throws Exception {
+        // given
+        String methodName = "RestGet";
+
+        // when
+        when(builder.get()).thenThrow(new RuntimeException());
+        Response finalResponse = testSubject.RestGet("", "", PATH, false).getResponse();
+
+        // then
+        Assert.assertEquals(finalResponse, null);
+    }
+
+    private void mockSystemProperties() throws UnsupportedEncodingException, InvalidPropertyException {
+        when(systemPropertyHelper.getAAIServerUrl()).thenReturn(Optional.of(HTTP_LOCALHOST));
+        when(systemPropertyHelper.getAAIUseClientCert()).thenReturn(Optional.of("cert"));
+        when(systemPropertyHelper.getAAIVIDPasswd()).thenReturn(Optional.of("passwd"));
+        when(systemPropertyHelper.getAAIVIDUsername()).thenReturn(Optional.of("user"));
+        when(systemPropertyHelper.getEncodedCredentials()).thenReturn("someCredentials");
+        when(systemPropertyHelper.getFullServicePath(Mockito.anyString())).thenReturn("http://localhost/path");
+    }
+
+}
\ No newline at end of file
index 245623a..56ac28d 100644 (file)
@@ -1,9 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.config;
 
 import org.hibernate.SessionFactory;
 import org.mockito.Mockito;
+import org.onap.portalsdk.core.service.DataAccessService;
 import org.onap.vid.aai.AaiClientInterface;
 import org.onap.vid.aai.util.HttpsAuthClient;
+import org.onap.vid.aai.util.SSLContextProvider;
+import org.onap.vid.aai.util.SystemPropertyHelper;
 import org.onap.vid.job.JobAdapter;
 import org.onap.vid.job.JobsBrokerService;
 import org.onap.vid.job.command.InProgressStatusCommand;
@@ -17,13 +41,11 @@ import org.onap.vid.services.AsyncInstantiationBusinessLogic;
 import org.onap.vid.services.AsyncInstantiationBusinessLogicImpl;
 import org.onap.vid.services.AuditService;
 import org.onap.vid.services.AuditServiceImpl;
-import org.onap.portalsdk.core.service.DataAccessService;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Scope;
-import org.togglz.core.manager.FeatureManager;
 
 @Configuration
 public class JobCommandsConfigWithMockedMso {
@@ -40,7 +62,7 @@ public class JobCommandsConfigWithMockedMso {
 
     @Bean
     public HttpsAuthClient httpsAuthClientFactory(){
-        return new HttpsAuthClient("some random path");
+        return new HttpsAuthClient("some random path", new SystemPropertyHelper(), new SSLContextProvider());
     }
 
     @Bean
index 54d0d77..f63580d 100644 (file)
@@ -1,3 +1,24 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018 Nokia. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
 package org.onap.vid.controller;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -5,8 +26,7 @@ import org.onap.vid.aai.AaiClient;
 import org.onap.vid.aai.AaiClientInterface;
 import org.onap.vid.aai.AaiResponseTranslator;
 import org.onap.vid.aai.model.PortDetailsTranslator;
-import org.onap.vid.aai.util.AAIRestInterface;
-import org.onap.vid.aai.util.HttpsAuthClient;
+import org.onap.vid.aai.util.*;
 import org.onap.vid.asdc.AsdcClient;
 import org.onap.vid.asdc.parser.ToscaParserImpl2;
 import org.onap.vid.services.AaiService;
@@ -46,14 +66,29 @@ public class LocalWebConfig {
     }
 
     @Bean
-    public HttpsAuthClient httpsAuthClientFactory(ServletContext servletContext) {
+    public SSLContextProvider sslContextProvider() {
+        return new SSLContextProvider();
+    }
+
+    @Bean
+    public SystemPropertyHelper systemPropertyHelper() {
+        return new SystemPropertyHelper();
+    }
+
+    @Bean
+    public ServletRequestHelper servletRequestHelper() {
+        return new ServletRequestHelper();
+    }
+
+    @Bean
+    public HttpsAuthClient httpsAuthClientFactory(ServletContext servletContext, SystemPropertyHelper systemPropertyHelper, SSLContextProvider sslContextProvider) {
         final String certFilePath = new File(servletContext.getRealPath("/WEB-INF/cert/")).getAbsolutePath();
-        return new HttpsAuthClient(certFilePath);
+        return new HttpsAuthClient(certFilePath, systemPropertyHelper, sslContextProvider);
     }
 
     @Bean(name = "aaiRestInterface")
-    public AAIRestInterface aaiRestInterface(HttpsAuthClient httpsAuthClientFactory) {
-        return new AAIRestInterface(httpsAuthClientFactory);
+    public AAIRestInterface aaiRestInterface(HttpsAuthClient httpsAuthClientFactory, ServletRequestHelper servletRequestHelper, SystemPropertyHelper systemPropertyHelper) {
+        return new AAIRestInterface(httpsAuthClientFactory, servletRequestHelper, systemPropertyHelper);
     }
 
     @Bean
index 175f87f..0460f53 100644 (file)
@@ -133,6 +133,7 @@ public class TestUtils {
             Mockito.when(fakeBuilder.get(any(GenericType.class))).thenReturn(null);
 
             Mockito.when(fakeResponse.getStatus()).thenReturn(200);
+            Mockito.when(fakeResponse.getStatusInfo()).thenReturn(Response.Status.OK);
             Mockito.when(fakeResponse.readEntity(Service.class)).thenReturn(null);
         }
     }