From 7861185045a47e86ea34afb22038cce3ab4196b7 Mon Sep 17 00:00:00 2001 From: Jozsef Csongvai Date: Fri, 26 Nov 2021 15:31:40 -0500 Subject: Add REST client for Api-handler This enables calling api-handler from bpmn-infra Issue-ID: SO-3811 Signed-off-by: Jozsef Csongvai Change-Id: I59a6c7859505f9fca4729089914f43834ceb6323 --- .../so/client/orchestration/ApiHandlerClient.java | 73 +++++++++++++ .../orchestration/ApiHandlerClientException.java | 8 ++ .../orchestration/RestTemplateApiClientConfig.java | 23 ++++ .../client/orchestration/ApiHandlerClientTest.java | 121 +++++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClient.java create mode 100644 bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClientException.java create mode 100644 bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/RestTemplateApiClientConfig.java create mode 100644 bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/orchestration/ApiHandlerClientTest.java (limited to 'bpmn/so-bpmn-tasks/src') diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClient.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClient.java new file mode 100644 index 0000000000..132e618ba5 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClient.java @@ -0,0 +1,73 @@ +package org.onap.so.client.orchestration; + +import org.onap.so.serviceinstancebeans.ServiceInstancesRequest; +import org.onap.so.serviceinstancebeans.ServiceInstancesResponse; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import static org.onap.so.client.orchestration.RestTemplateApiClientConfig.REST_TEMPLATE_API_HANDLER; + +@Component +public class ApiHandlerClient { + + @Value("${mso.adapters.apihandler.serviceInstantiationEndpoint:/onap/so/infra/serviceInstantiation/v7/serviceInstances}") + private String serviceInstantiationEndpoint; + @Value("${mso.adapters.apihandler.endpoint}") + private String baseUri; + @Value("${mso.adapters.apihandler.auth}") + private String auth; + + private RestTemplate restTemplate; + + public ApiHandlerClient(@Qualifier(REST_TEMPLATE_API_HANDLER) RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + public ServiceInstancesResponse createServiceInstance(ServiceInstancesRequest serviceInstancesRequest) + throws ApiHandlerClientException { + try { + HttpEntity request = createRequest(serviceInstancesRequest); + return restTemplate.exchange(baseUri + serviceInstantiationEndpoint, HttpMethod.POST, request, + ServiceInstancesResponse.class).getBody(); + } catch (HttpStatusCodeException e) { + throw new ApiHandlerClientException("Failed sending service createInstance request to api-handler." + + " Error: " + e.getResponseBodyAsString()); + } catch (RestClientException e) { + throw new ApiHandlerClientException( + "Failed sending service createInstance request to api-handler." + " Error: " + e.getMessage()); + } + } + + public ServiceInstancesResponse deleteServiceInstance(ServiceInstancesRequest serviceInstancesRequest) + throws ApiHandlerClientException { + try { + HttpEntity request = createRequest(serviceInstancesRequest); + return restTemplate.exchange( + baseUri + serviceInstantiationEndpoint + + String.format("/%s", serviceInstancesRequest.getServiceInstanceId()), + HttpMethod.DELETE, request, ServiceInstancesResponse.class).getBody(); + } catch (HttpStatusCodeException e) { + throw new ApiHandlerClientException("Failed sending service deleteInstance request to api-handler." + + " Error: " + e.getResponseBodyAsString()); + } catch (RestClientException e) { + throw new ApiHandlerClientException( + "Failed sending service deleteInstance request to api-handler." + " Error: " + e.getMessage()); + } + } + + private HttpEntity createRequest(ServiceInstancesRequest serviceInstancesRequest) { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.AUTHORIZATION, auth); + headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + headers.set(HttpHeaders.ACCEPT, String.valueOf(MediaType.APPLICATION_JSON)); + + return new HttpEntity<>(serviceInstancesRequest, headers); + } +} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClientException.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClientException.java new file mode 100644 index 0000000000..0a4c60cdf7 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/ApiHandlerClientException.java @@ -0,0 +1,8 @@ +package org.onap.so.client.orchestration; + +public class ApiHandlerClientException extends Exception { + + public ApiHandlerClientException(String errorMessage) { + super(errorMessage); + } +} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/RestTemplateApiClientConfig.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/RestTemplateApiClientConfig.java new file mode 100644 index 0000000000..a01fbe18f8 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/orchestration/RestTemplateApiClientConfig.java @@ -0,0 +1,23 @@ +package org.onap.so.client.orchestration; + +import org.onap.logging.filter.spring.SpringClientPayloadFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateApiClientConfig { + public static final String REST_TEMPLATE_API_HANDLER = "restTemplateApiHandler"; + + @Bean(REST_TEMPLATE_API_HANDLER) + public RestTemplate restTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate + .setRequestFactory(new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory())); + restTemplate.getInterceptors().add((new SpringClientPayloadFilter())); + return restTemplate; + } + +} diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/orchestration/ApiHandlerClientTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/orchestration/ApiHandlerClientTest.java new file mode 100644 index 0000000000..f3a04e6f54 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/orchestration/ApiHandlerClientTest.java @@ -0,0 +1,121 @@ +package org.onap.so.client.orchestration; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.so.serviceinstancebeans.ServiceInstancesRequest; +import org.onap.so.serviceinstancebeans.ServiceInstancesResponse; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.instanceOf; + + +@TestPropertySource(properties = {"mso.adapters.apihandler.endpoint=http://localhost:", + "mso.adapters.apihandler.auth=Basic dGVzdDp0ZXN0Cg=="}) +@RunWith(SpringJUnit4ClassRunner.class) +public class ApiHandlerClientTest { + + @InjectMocks + private ApiHandlerClient client; + + @Mock + protected RestTemplate restTemplate; + + private ServiceInstancesRequest buildRequest(String incomingRequest) { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + ServiceInstancesRequest request = null; + try { + request = mapper.readValue(incomingRequest, ServiceInstancesRequest.class); + System.out.println("Java Object: " + request); + } catch (Exception e) { + System.out.println("Caught Exception " + e.getMessage()); + Assert.fail("Could not build ServiceInstancesRequest object"); + } + return request; + } + + @Test + public void createServiceInstanceTest() { + String incomingRequest = + "{\"requestDetails\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"owningEntity\":{\"owningEntityId\":\"038d99af-0427-42c2-9d15-971b99b9b489\",\"owningEntityName\":\"PACKETCORE\"},\"project\":{\"projectName\":\"{someprojectname}\"},\"subscriberInfo\":{\"globalSubscriberId\":\"{somesubscriberid}\"},\"requestInfo\":{\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"source\":\"VID\",\"suppressRollback\":true,\"requestorId\":\"xxxxxx\"},\"requestParameters\":{\"subscriptionServiceType\":\"VMX\",\"aLaCarte\":false,\"userParams\":[{\"service\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"instanceParams\":[],\"resources\":{\"vnfs\":[{\"modelInfo\":{\"modelType\":\"vnf\",\"modelName\":\"2016-73_MOW\",\"modelVersionId\":\"7f40c192-f63c-463e-ba94-286933b895f8\",\"modelCustomizationName\":\"2016-73_MOW\",\"modelCustomizationId\":\"ab153b6e-c364-44c0-bef6-1f2982117f04\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"platform\":{\"platformName\":\"test\"},\"lineOfBusiness\":{\"lineOfBusinessName\":\"someValue\"},\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"instanceParams\":[],\"vfModules\":[{\"modelInfo\":{\"modelType\":\"vfModule\",\"modelName\":\"201673MowtestBvL\",\"modelVersionId\":\"4c75f813-fa91-45a4-89d0-790ff5f1ae79\",\"modelCustomizationId\":\"a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f\"},\"instanceName\":\"vfModule1\",\"instanceParams\":[{\"vmx_int_net_len\":\"24\"}]}]}]}}}]}}}"; + ServiceInstancesRequest request = buildRequest(incomingRequest); + ResponseEntity responseEntity = + new ResponseEntity(new ServiceInstancesResponse(), HttpStatus.ACCEPTED); + Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class), + ArgumentMatchers.any(), ArgumentMatchers.>any())) + .thenReturn(responseEntity); + + try { + ServiceInstancesResponse response = client.createServiceInstance(request); + assertThat(response, instanceOf(ServiceInstancesResponse.class)); + } catch (ApiHandlerClientException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void createServiceInstanceErrorTest() { + String incomingRequest = + "{\"requestDetails\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"owningEntity\":{\"owningEntityId\":\"038d99af-0427-42c2-9d15-971b99b9b489\",\"owningEntityName\":\"PACKETCORE\"},\"project\":{\"projectName\":\"{someprojectname}\"},\"subscriberInfo\":{\"globalSubscriberId\":\"{somesubscriberid}\"},\"requestInfo\":{\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"source\":\"VID\",\"suppressRollback\":true,\"requestorId\":\"xxxxxx\"},\"requestParameters\":{\"subscriptionServiceType\":\"VMX\",\"aLaCarte\":false,\"userParams\":[{\"service\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"instanceParams\":[],\"resources\":{\"vnfs\":[{\"modelInfo\":{\"modelType\":\"vnf\",\"modelName\":\"2016-73_MOW\",\"modelVersionId\":\"7f40c192-f63c-463e-ba94-286933b895f8\",\"modelCustomizationName\":\"2016-73_MOW\",\"modelCustomizationId\":\"ab153b6e-c364-44c0-bef6-1f2982117f04\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"platform\":{\"platformName\":\"test\"},\"lineOfBusiness\":{\"lineOfBusinessName\":\"someValue\"},\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"instanceParams\":[],\"vfModules\":[{\"modelInfo\":{\"modelType\":\"vfModule\",\"modelName\":\"201673MowtestBvL\",\"modelVersionId\":\"4c75f813-fa91-45a4-89d0-790ff5f1ae79\",\"modelCustomizationId\":\"a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f\"},\"instanceName\":\"vfModule1\",\"instanceParams\":[{\"vmx_int_net_len\":\"24\"}]}]}]}}}]}}}"; + ServiceInstancesRequest request = buildRequest(incomingRequest); + Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class), + ArgumentMatchers.any(), ArgumentMatchers.>any())) + .thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)); + try { + client.createServiceInstance(request); + Assert.fail("ApiHandlerClientException exception was not thrown"); + } catch (ApiHandlerClientException e) { + assertEquals("Failed sending service createInstance request to api-handler. Error: ", e.getMessage()); + } + } + + @Test + public void deleteServiceInstanceTest() { + String incomingRequest = + "{\"requestDetails\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"owningEntity\":{\"owningEntityId\":\"038d99af-0427-42c2-9d15-971b99b9b489\",\"owningEntityName\":\"PACKETCORE\"},\"project\":{\"projectName\":\"{someprojectname}\"},\"subscriberInfo\":{\"globalSubscriberId\":\"{somesubscriberid}\"},\"requestInfo\":{\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"source\":\"VID\",\"suppressRollback\":true,\"requestorId\":\"xxxxxx\"},\"requestParameters\":{\"subscriptionServiceType\":\"VMX\",\"aLaCarte\":false,\"userParams\":[{\"service\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"instanceParams\":[],\"resources\":{\"vnfs\":[{\"modelInfo\":{\"modelType\":\"vnf\",\"modelName\":\"2016-73_MOW\",\"modelVersionId\":\"7f40c192-f63c-463e-ba94-286933b895f8\",\"modelCustomizationName\":\"2016-73_MOW\",\"modelCustomizationId\":\"ab153b6e-c364-44c0-bef6-1f2982117f04\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"platform\":{\"platformName\":\"test\"},\"lineOfBusiness\":{\"lineOfBusinessName\":\"someValue\"},\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"instanceParams\":[],\"vfModules\":[{\"modelInfo\":{\"modelType\":\"vfModule\",\"modelName\":\"201673MowtestBvL\",\"modelVersionId\":\"4c75f813-fa91-45a4-89d0-790ff5f1ae79\",\"modelCustomizationId\":\"a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f\"},\"instanceName\":\"vfModule1\",\"instanceParams\":[{\"vmx_int_net_len\":\"24\"}]}]}]}}}]}}}"; + ServiceInstancesRequest request = buildRequest(incomingRequest); + ResponseEntity responseEntity = + new ResponseEntity(new ServiceInstancesResponse(), HttpStatus.ACCEPTED); + Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class), + ArgumentMatchers.any(), ArgumentMatchers.>any())) + .thenReturn(responseEntity); + + try { + ServiceInstancesResponse response = client.deleteServiceInstance(request); + assertThat(response, instanceOf(ServiceInstancesResponse.class)); + } catch (ApiHandlerClientException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void deleteServiceInstanceErrorTest() { + String incomingRequest = + "{\"requestDetails\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"owningEntity\":{\"owningEntityId\":\"038d99af-0427-42c2-9d15-971b99b9b489\",\"owningEntityName\":\"PACKETCORE\"},\"project\":{\"projectName\":\"{someprojectname}\"},\"subscriberInfo\":{\"globalSubscriberId\":\"{somesubscriberid}\"},\"requestInfo\":{\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"source\":\"VID\",\"suppressRollback\":true,\"requestorId\":\"xxxxxx\"},\"requestParameters\":{\"subscriptionServiceType\":\"VMX\",\"aLaCarte\":false,\"userParams\":[{\"service\":{\"modelInfo\":{\"modelType\":\"service\",\"modelInvariantId\":\"5d48acb5-097d-4982-aeb2-f4a3bd87d31b\",\"modelVersionId\":\"3c40d244-808e-42ca-b09a-256d83d19d0a\",\"modelName\":\"MOWvMXBV1Service\",\"modelVersion\":\"10.0\"},\"instanceParams\":[],\"resources\":{\"vnfs\":[{\"modelInfo\":{\"modelType\":\"vnf\",\"modelName\":\"2016-73_MOW\",\"modelVersionId\":\"7f40c192-f63c-463e-ba94-286933b895f8\",\"modelCustomizationName\":\"2016-73_MOW\",\"modelCustomizationId\":\"ab153b6e-c364-44c0-bef6-1f2982117f04\"},\"cloudConfiguration\":{\"lcpCloudRegionId\":\"mdt1\",\"tenantId\":\"88a6ca3ee0394ade9403f075db23167e\"},\"platform\":{\"platformName\":\"test\"},\"lineOfBusiness\":{\"lineOfBusinessName\":\"someValue\"},\"productFamilyId\":\"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"instanceParams\":[],\"vfModules\":[{\"modelInfo\":{\"modelType\":\"vfModule\",\"modelName\":\"201673MowtestBvL\",\"modelVersionId\":\"4c75f813-fa91-45a4-89d0-790ff5f1ae79\",\"modelCustomizationId\":\"a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f\"},\"instanceName\":\"vfModule1\",\"instanceParams\":[{\"vmx_int_net_len\":\"24\"}]}]}]}}}]}}}"; + ServiceInstancesRequest request = buildRequest(incomingRequest); + Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class), + ArgumentMatchers.any(), ArgumentMatchers.>any())) + .thenThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)); + try { + client.deleteServiceInstance(request); + Assert.fail("ApiHandlerClientException exception was not thrown"); + } catch (ApiHandlerClientException e) { + assertEquals("Failed sending service deleteInstance request to api-handler. Error: ", e.getMessage()); + } + } + +} -- cgit 1.2.3-korg