From f07fc1a586328d2b4cef02bd1d8f9e791130bf1b Mon Sep 17 00:00:00 2001 From: tgolabek Date: Wed, 23 May 2018 11:40:17 +0200 Subject: Refactor of an AAIRestInterface Refactor and some additional tests added (cherry picked from commit 6d8fa7d179b8de802ae386b317ddd1214eac1c47) Change-Id: Ibe7583353499352aa81d100b9995b9c74133c447 Issue-ID: VID-229 Signed-off-by: Stern, Ittay (is9613) [Added proper headers to modified and created files] Signed-off-by: golabek --- .../java/org/onap/vid/aai/PombaRestInterface.java | 50 ++-- .../aai/exceptions/HttpClientBuilderException.java | 28 ++ .../aai/exceptions/InvalidPropertyException.java | 24 ++ .../org/onap/vid/aai/util/AAIRestInterface.java | 303 ++++++++++---------- .../org/onap/vid/aai/util/HttpsAuthClient.java | 153 ++++------ .../org/onap/vid/aai/util/SSLContextProvider.java | 105 +++++++ .../onap/vid/aai/util/ServletRequestHelper.java | 33 +++ .../onap/vid/aai/util/SystemPropertyHelper.java | 90 ++++++ .../java/org/onap/vid/controllers/WebConfig.java | 51 +++- .../test/java/org/onap/vid/aai/AaiClientTest.java | 31 ++- .../util/CustomJacksonJaxBJsonProviderTest.java | 45 ++- .../org/onap/vid/aai/util/HttpsAuthClientTest.java | 82 +++++- .../aai/util/ParametrizedAAIRestInterfaceTest.java | 123 +++++++++ .../vid/aai/util/SingleAAIRestInterfaceTest.java | 307 +++++++++++++++++++++ .../vid/config/JobCommandsConfigWithMockedMso.java | 28 +- .../org/onap/vid/controller/LocalWebConfig.java | 47 +++- .../java/org/onap/vid/testUtils/TestUtils.java | 1 + 17 files changed, 1192 insertions(+), 309 deletions(-) create mode 100644 vid-app-common/src/main/java/org/onap/vid/aai/exceptions/HttpClientBuilderException.java create mode 100644 vid-app-common/src/main/java/org/onap/vid/aai/exceptions/InvalidPropertyException.java create mode 100644 vid-app-common/src/main/java/org/onap/vid/aai/util/SSLContextProvider.java create mode 100644 vid-app-common/src/main/java/org/onap/vid/aai/util/ServletRequestHelper.java create mode 100644 vid-app-common/src/main/java/org/onap/vid/aai/util/SystemPropertyHelper.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/aai/util/ParametrizedAAIRestInterfaceTest.java create mode 100644 vid-app-common/src/test/java/org/onap/vid/aai/util/SingleAAIRestInterfaceTest.java (limited to 'vid-app-common') diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/PombaRestInterface.java b/vid-app-common/src/main/java/org/onap/vid/aai/PombaRestInterface.java index 73ebf69d9..c4bc852ff 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/PombaRestInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/PombaRestInterface.java @@ -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 index 000000000..ed45fa455 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/HttpClientBuilderException.java @@ -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 index 000000000..11875fbd2 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/exceptions/InvalidPropertyException.java @@ -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 { +} diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/AAIRestInterface.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/AAIRestInterface.java index ac38b5057..6b17c932a 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/util/AAIRestInterface.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/AAIRestInterface.java @@ -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, + 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()); } } diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/util/HttpsAuthClient.java b/vid-app-common/src/main/java/org/onap/vid/aai/util/HttpsAuthClient.java index f1eafe42a..15f81439b 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/util/HttpsAuthClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/HttpsAuthClient.java @@ -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. @@ -21,30 +22,35 @@ 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 index 000000000..90d2be956 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/SSLContextProvider.java @@ -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 index 000000000..6480bef0d --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/ServletRequestHelper.java @@ -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 index 000000000..ebf39c409 --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/aai/util/SystemPropertyHelper.java @@ -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 getAAIUseClientCert(){ + return getSystemProperty(AAIProperties.AAI_USE_CLIENT_CERT); + } + + public Optional getAAIServerUrl(){ + return getSystemProperty(AAIProperties.AAI_SERVER_URL); + } + + public Optional getAAIVIDUsername(){ + return getSystemProperty(AAIProperties.AAI_VID_USERNAME); + } + + public Optional getAAIVIDPasswd(){ + return getSystemProperty(AAIProperties.AAI_VID_PASSWD_X); + } + + public Optional getAAITruststorePasswd(){ + return getSystemProperty(AAIProperties.AAI_TRUSTSTORE_PASSWD_X); + } + + public Optional getAAITruststoreFilename(){ + return getSystemProperty(AAIProperties.AAI_TRUSTSTORE_FILENAME); + } + + public Optional getAAIKeystoreFilename(){ + return getSystemProperty(AAIProperties.AAI_KEYSTORE_FILENAME); + } + + public Optional 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 getSystemProperty(String propertyKey){ + return Optional.ofNullable(SystemProperties.getProperty(propertyKey)); + } +} diff --git a/vid-app-common/src/main/java/org/onap/vid/controllers/WebConfig.java b/vid-app-common/src/main/java/org/onap/vid/controllers/WebConfig.java index 22e476001..98c0c3833 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controllers/WebConfig.java +++ b/vid-app-common/src/main/java/org/onap/vid/controllers/WebConfig.java @@ -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 diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java index 32e894d0a..76d1d4aff 100644 --- a/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/aai/AaiClientTest.java @@ -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); diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/util/CustomJacksonJaxBJsonProviderTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/util/CustomJacksonJaxBJsonProviderTest.java index dcd962f1b..f2b01f0c0 100644 --- a/vid-app-common/src/test/java/org/onap/vid/aai/util/CustomJacksonJaxBJsonProviderTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/aai/util/CustomJacksonJaxBJsonProviderTest.java @@ -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 diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/util/HttpsAuthClientTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/util/HttpsAuthClientTest.java index a26c431e8..f000dc801 100644 --- a/vid-app-common/src/test/java/org/onap/vid/aai/util/HttpsAuthClientTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/aai/util/HttpsAuthClientTest.java @@ -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 index 000000000..94e749ace --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/aai/util/ParametrizedAAIRestInterfaceTest.java @@ -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 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 index 000000000..288b891c0 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/aai/util/SingleAAIRestInterfaceTest.java @@ -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 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 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 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 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 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 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 diff --git a/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java b/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java index 245623aa3..56ac28d2e 100644 --- a/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java +++ b/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java @@ -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 diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/LocalWebConfig.java b/vid-app-common/src/test/java/org/onap/vid/controller/LocalWebConfig.java index 54d0d77b5..f63580d27 100644 --- a/vid-app-common/src/test/java/org/onap/vid/controller/LocalWebConfig.java +++ b/vid-app-common/src/test/java/org/onap/vid/controller/LocalWebConfig.java @@ -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 diff --git a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java index 175f87f2a..0460f5325 100644 --- a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java +++ b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java @@ -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); } } -- cgit 1.2.3-korg