From 7d6e1ae492d91b74c6db995f42ef665d9e375245 Mon Sep 17 00:00:00 2001 From: Michal Kabaj Date: Thu, 15 Nov 2018 13:48:36 +0100 Subject: Add unit tests for ExternalAPIUtil -Add unit tests for ExternalAPIUtil -Add dependency injection via constructor -Add factory for creating ExternalAPIUtil and RESTClient Change-Id: Ied89afa3612de8d51424c95239341a57387ad94f Issue-ID: SO-1195 Signed-off-by: Michal Kabaj --- .../so/bpmn/common/scripts/ExternalAPIUtil.groovy | 37 ++-- .../common/scripts/ExternalAPIUtilFactory.groovy | 29 +++ .../bpmn/common/scripts/ExternalAPIUtilTest.groovy | 199 +++++++++++++++++++++ 3 files changed, 247 insertions(+), 18 deletions(-) create mode 100644 bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilFactory.groovy create mode 100644 bpmn/MSOCommonBPMN/src/test/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilTest.groovy (limited to 'bpmn/MSOCommonBPMN/src') diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtil.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtil.groovy index 5c935e9081..250cdda0a1 100644 --- a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtil.groovy +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtil.groovy @@ -19,29 +19,30 @@ */ package org.onap.so.bpmn.common.scripts -import org.camunda.bpm.engine.delegate.BpmnError + + import org.camunda.bpm.engine.delegate.DelegateExecution -import org.onap.so.bpmn.common.scripts.AbstractServiceTaskProcessor; +import org.onap.logging.ref.slf4j.ONAPLogConstants import org.onap.so.client.HttpClient +import org.onap.so.client.HttpClientFactory import org.onap.so.logger.MsoLogger -import org.apache.commons.lang3.StringEscapeUtils -import java.util.regex.Matcher -import java.util.regex.Pattern +import org.onap.so.utils.TargetEntity import javax.ws.rs.core.MediaType import javax.ws.rs.core.Response -import org.onap.so.utils.TargetEntity +import java.util.regex.Matcher +import java.util.regex.Pattern class ExternalAPIUtil { String Prefix="EXTAPI_" - public MsoUtils utils = new MsoUtils() - - ExceptionUtil exceptionUtil = new ExceptionUtil() - private static final MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.BPEL, ExternalAPIUtil.class) + private final HttpClientFactory httpClientFactory; + private final MsoUtils utils; + private final ExceptionUtil exceptionUtil; + public static final String PostServiceOrderRequestsTemplate = "{\n" + "\t\"externalId\": ,\n" + @@ -85,7 +86,10 @@ class ExternalAPIUtil { "\t} \n" + "}" - public ExternalAPIUtil() { + ExternalAPIUtil(HttpClientFactory httpClientFactory, MsoUtils utils, ExceptionUtil exceptionUtil) { + this.httpClientFactory = httpClientFactory + this.utils = utils + this.exceptionUtil = exceptionUtil } // public String getUri(DelegateExecution execution, resourceName) { @@ -137,8 +141,7 @@ class ExternalAPIUtil { msoLogger.debug( "Generated uuid is: " + uuid) msoLogger.debug( "URL to be used is: " + url) - URL Url = new URL(url) - HttpClient client = new HttpClient(Url, MediaType.APPLICATION_JSON, TargetEntity.EXTERNAL) + HttpClient client = httpClientFactory.create(new URL(url), MediaType.APPLICATION_JSON, TargetEntity.EXTERNAL) client.addBasicAuthHeader(execution.getVariable("URN_externalapi_auth"), execution.getVariable("URN_mso_msoKey")) client.addAdditionalHeader("X-FromAppId", "MSO") client.addAdditionalHeader(ONAPLogConstants.Headers.REQUEST_ID, uuid) @@ -166,17 +169,15 @@ class ExternalAPIUtil { * @return Response * */ - public Response executeExternalAPIPostCall(DelegateExecution execution, String urlString, String payload){ + public Response executeExternalAPIPostCall(DelegateExecution execution, String url, String payload){ msoLogger.debug( " ======== Started Execute ExternalAPI Post Process ======== ") Response apiResponse = null try{ String uuid = utils.getRequestID() msoLogger.debug( "Generated uuid is: " + uuid) - msoLogger.debug( "URL to be used is: " + urlString) - - URL url = new URL(urlString); + msoLogger.debug( "URL to be used is: " + url) - HttpClient httpClient = new HttpClient(url, "application/json", TargetEntity.AAI) + HttpClient httpClient = httpClientFactory.create(new URL(url), MediaType.APPLICATION_JSON, TargetEntity.AAI) httpClient.addBasicAuthHeader(execution.getVariable("URN_externalapi_auth"), execution.getVariable("URN_mso_msoKey")) httpClient.addAdditionalHeader("X-FromAppId", "MSO") httpClient.addAdditionalHeader("X-TransactionId", uuid) diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilFactory.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilFactory.groovy new file mode 100644 index 0000000000..e7f46464ee --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilFactory.groovy @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 Nokia. + * ================================================================================ + * 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.so.bpmn.common.scripts + +import org.onap.so.client.HttpClientFactory + +class ExternalAPIUtilFactory { + + ExternalAPIUtil create() { + return new ExternalAPIUtil(new HttpClientFactory(), new MsoUtils(), new ExceptionUtil()) + } +} diff --git a/bpmn/MSOCommonBPMN/src/test/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilTest.groovy b/bpmn/MSOCommonBPMN/src/test/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilTest.groovy new file mode 100644 index 0000000000..5f428f1f9f --- /dev/null +++ b/bpmn/MSOCommonBPMN/src/test/groovy/org/onap/so/bpmn/common/scripts/ExternalAPIUtilTest.groovy @@ -0,0 +1,199 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 Nokia. + * ================================================================================ + * 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.so.bpmn.common.scripts + +import org.assertj.core.api.AbstractAssert +import org.camunda.bpm.engine.delegate.BpmnError +import org.camunda.bpm.engine.delegate.DelegateExecution +import org.junit.Test +import org.onap.logging.ref.slf4j.ONAPLogConstants +import org.onap.so.client.HttpClient +import org.onap.so.client.HttpClientFactory +import org.onap.so.utils.TargetEntity +import org.springframework.http.HttpStatus + +import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response + +import static org.assertj.core.api.Assertions.assertThat +import static org.assertj.core.api.Assertions.catchThrowableOfType +import static org.mockito.BDDMockito.given +import static org.mockito.BDDMockito.then +import static org.mockito.BDDMockito.willThrow +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.times + +class ExternalAPIUtilTest { + + private static final String URL = "http://someUrl" + private static final String UUID_STR = UUID.nameUUIDFromBytes("deterministic_uuid".getBytes()) + private static final String BODY_PAYLOAD = "payload" + + @Test + void executeExternalAPIGetCall_shouldPerformRestGetCall_withAuthorizationHeaderSet() { + // GIVEN + Response expectedResponse = createExpectedResponse(HttpStatus.ACCEPTED, BODY_PAYLOAD) + HttpClient httpClient = mock(HttpClient.class) + given(httpClient.get()).willReturn(expectedResponse) + HttpClientFactory httpClientFactory = mock(HttpClientFactory.class) + given(httpClientFactory.create(new URL(URL), MediaType.APPLICATION_JSON, TargetEntity.EXTERNAL)).willReturn(httpClient) + + // WHEN + ExternalAPIUtil externalAPIUtil = new ExternalAPIUtil(httpClientFactory, new DummyMsoUtils(UUID_STR), new ExceptionUtil()) + Response apiResponse = externalAPIUtil.executeExternalAPIGetCall(createDelegateExecution(), URL) + + // THEN + then(httpClient).should(times(1)).addBasicAuthHeader("value_externalapi_auth", "value_mso_msoKey") + then(httpClient).should(times(1)).addAdditionalHeader("X-FromAppId", "MSO") + then(httpClient).should(times(1)).addAdditionalHeader(ONAPLogConstants.Headers.REQUEST_ID, UUID_STR) + then(httpClient).should(times(1)).addAdditionalHeader("Accept", MediaType.APPLICATION_JSON) + ResponseAssert.assertThat(apiResponse) + .hasStatusCode(HttpStatus.ACCEPTED) + .hasBody(BODY_PAYLOAD) + } + + @Test + void executeExternalAPIGetCall_shouldHandleExceptionsThrownByGetCall_andRethrowAsBpmnError() { + // GIVEN + HttpClient httpClient = mock(HttpClient.class) + willThrow(new RuntimeException("error occurred")).given(httpClient).get() + HttpClientFactory httpClientFactory = mock(HttpClientFactory.class) + given(httpClientFactory.create(new URL(URL), MediaType.APPLICATION_JSON, TargetEntity.EXTERNAL)).willReturn(httpClient) + DelegateExecution delegateExecution = createDelegateExecution() + DummyExceptionUtil exceptionUtil = new DummyExceptionUtil() + + // WHEN + ExternalAPIUtil externalAPIUtil = new ExternalAPIUtil(httpClientFactory, new DummyMsoUtils(UUID_STR), exceptionUtil) + BpmnError bpmnError = catchThrowableOfType({ -> externalAPIUtil.executeExternalAPIGetCall(delegateExecution, URL) + }, BpmnError.class) + + // THEN + assertThat(exceptionUtil.getDelegateExecution()).isSameAs(delegateExecution) + assertThat(bpmnError.getMessage()).isEqualTo("error occurred") + assertThat(bpmnError.getErrorCode()).isEqualTo("9999") + } + + @Test + void executeExternalAPIPostCall_shouldHandleExceptionsThrownByPostCall_andRethrowAsBpmnError() { + // GIVEN + HttpClient httpClient = mock(HttpClient.class) + willThrow(new RuntimeException("error occurred")).given(httpClient).post(BODY_PAYLOAD) + HttpClientFactory httpClientFactory = mock(HttpClientFactory.class) + given(httpClientFactory.create(new URL(URL), MediaType.APPLICATION_JSON, TargetEntity.AAI)).willReturn(httpClient) + DelegateExecution delegateExecution = createDelegateExecution() + DummyExceptionUtil exceptionUtil = new DummyExceptionUtil() + + // WHEN + ExternalAPIUtil externalAPIUtil = new ExternalAPIUtil(httpClientFactory, new DummyMsoUtils(UUID_STR), exceptionUtil) + BpmnError bpmnError = catchThrowableOfType({ -> + externalAPIUtil.executeExternalAPIPostCall(delegateExecution, URL, BODY_PAYLOAD) + }, BpmnError.class) + + // THEN + assertThat(exceptionUtil.getDelegateExecution()).isSameAs(delegateExecution) + assertThat(bpmnError.getMessage()).isEqualTo("error occurred") + assertThat(bpmnError.getErrorCode()).isEqualTo("9999") + } + + @Test + void executeExternalAPIPostCall_shouldPerformRestPostCall_withPayloadAndAuthorizationHeaderSet() { + // GIVEN + Response expectedResponse = createExpectedResponse(HttpStatus.ACCEPTED, BODY_PAYLOAD) + HttpClient httpClient = mock(HttpClient.class) + given(httpClient.post(BODY_PAYLOAD)).willReturn(expectedResponse) + HttpClientFactory httpClientFactory = mock(HttpClientFactory.class) + given(httpClientFactory.create(new URL(URL), MediaType.APPLICATION_JSON, TargetEntity.AAI)).willReturn(httpClient) + + // WHEN + ExternalAPIUtil externalAPIUtil = new ExternalAPIUtil(httpClientFactory, new DummyMsoUtils(UUID_STR), new ExceptionUtil()) + Response apiResponse = externalAPIUtil.executeExternalAPIPostCall(createDelegateExecution(), URL, BODY_PAYLOAD) + + // THEN + then(httpClient).should(times(1)).addBasicAuthHeader("value_externalapi_auth", "value_mso_msoKey") + then(httpClient).should(times(1)).addAdditionalHeader("X-FromAppId", "MSO") + then(httpClient).should(times(1)).addAdditionalHeader("X-TransactionId", UUID_STR) + ResponseAssert.assertThat(apiResponse) + .hasStatusCode(HttpStatus.ACCEPTED) + .hasBody(BODY_PAYLOAD) + } + + private Response createExpectedResponse(HttpStatus httpStatus, String body) { + Response expectedResponse = mock(Response.class) + given(expectedResponse.getStatus()).willReturn(httpStatus.value()) + given(expectedResponse.getEntity()).willReturn(body) + return expectedResponse + } + + private DelegateExecution createDelegateExecution() { + DelegateExecution delegateExecution = mock(DelegateExecution.class) + given(delegateExecution.getVariable("URN_externalapi_auth")).willReturn("value_externalapi_auth") + given(delegateExecution.getVariable("URN_mso_msoKey")).willReturn("value_mso_msoKey") + return delegateExecution + } + + private static class ResponseAssert extends AbstractAssert { + + ResponseAssert(Response response) { + super(response, ResponseAssert.class) + } + + static ResponseAssert assertThat(Response response) { + return new ResponseAssert(response) + } + + ResponseAssert hasStatusCode(HttpStatus httpStatus) { + assertThat(actual.getStatus()).isEqualTo(httpStatus.value()) + return this + } + + ResponseAssert hasBody(String responseBody) { + assertThat(actual.getEntity()).isEqualTo(responseBody) + return this + } + } + + private static class DummyMsoUtils extends MsoUtils { + + private final String uuid + + DummyMsoUtils(String uuid) { + this.uuid = uuid + } + + String getRequestID() { + return uuid + } + } + + private static class DummyExceptionUtil extends ExceptionUtil { + + private DelegateExecution delegateExecution + + @Override + void buildAndThrowWorkflowException(DelegateExecution delegateExecution, int errorCode, String errorMessage) { + this.delegateExecution = delegateExecution + throw new BpmnError(String.valueOf(errorCode), errorMessage) + } + + DelegateExecution getDelegateExecution() { + return delegateExecution + } + } +} \ No newline at end of file -- cgit 1.2.3-korg