diff options
7 files changed, 402 insertions, 8 deletions
diff --git a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiReactiveHttpPatchClient.java b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiReactiveHttpPatchClient.java index fa1248df..841db6e8 100644 --- a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiReactiveHttpPatchClient.java +++ b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiReactiveHttpPatchClient.java @@ -47,7 +47,6 @@ public class AaiReactiveHttpPatchClient { private final Integer aaiHostPortNumber; private final String aaiBasePath; private final String aaiPnfPath; - private final JsonBodyBuilder jsonBodyBuilder; /** diff --git a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClient.java b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClient.java new file mode 100644 index 00000000..bd5271be --- /dev/null +++ b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClient.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * DCAEGEN2-SERVICES-SDK + * ================================================================================ + * Copyright (C) 2018-2019 NOKIA Intellectual Property. 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.dcaegen2.services.sdk.rest.services.aai.client.service.http.put; + + +import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel; +import org.onap.dcaegen2.services.sdk.rest.services.model.JsonBodyBuilder; +import org.slf4j.MDC; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.DefaultUriBuilderFactory; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.util.UUID; + + +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.REQUEST_ID; +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.X_INVOCATION_ID; +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.X_ONAP_REQUEST_ID; + + +public class AaiReactiveHttpPutClient { + + private WebClient webClient; + private final String aaiHost; + private final String aaiProtocol; + private final Integer aaiHostPortNumber; + private final String aaiBasePath; + private final String aaiPnfPath; + + private final JsonBodyBuilder jsonBodyBuilder; + + /** + * Constructor of AaiProducerReactiveHttpClient. + * + * @param configuration - AAI producer configuration object + */ + public AaiReactiveHttpPutClient(AaiClientConfiguration configuration, JsonBodyBuilder jsonBodyBuilder) { + this.aaiHost = configuration.aaiHost(); + this.aaiProtocol = configuration.aaiProtocol(); + this.aaiHostPortNumber = configuration.aaiPort(); + this.aaiBasePath = configuration.aaiBasePath(); + this.aaiPnfPath = configuration.aaiPnfPath(); + this.jsonBodyBuilder = jsonBodyBuilder; + } + + /** + * Function for calling AAI Http producer - put request to AAI database. + * + * @param aaiModel - object which will be sent to AAI database + * @return status code of operation + */ + public Mono<ClientResponse> getAaiProducerResponse(AaiModel aaiModel) { + return putAaiRequest(aaiModel); + } + + public AaiReactiveHttpPutClient createAaiWebClient(WebClient webClient) { + this.webClient = webClient; + return this; + } + + private Mono<ClientResponse> putAaiRequest(AaiModel aaiModel) { + return + webClient.put() + .uri(getUri(aaiModel.getCorrelationId())) + .header(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID)) + .header(X_INVOCATION_ID, UUID.randomUUID().toString()) + .body(Mono.just(jsonBodyBuilder.createJsonBody(aaiModel)), String.class) + .exchange(); + } + + URI getUri(String pnfName) { + return new DefaultUriBuilderFactory().builder().scheme(aaiProtocol).host(aaiHost).port(aaiHostPortNumber) + .path(aaiBasePath + aaiPnfPath + "/" + pnfName).build(); + } +}
\ No newline at end of file diff --git a/rest-services/aai-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClientTest.java b/rest-services/aai-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClientTest.java new file mode 100644 index 00000000..3b694496 --- /dev/null +++ b/rest-services/aai-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/put/AaiReactiveHttpPutClientTest.java @@ -0,0 +1,140 @@ +/* + * ============LICENSE_START======================================================= + * DCAEGEN2-SERVICES-SDK + * ================================================================================ + * Copyright (C) 2018 NOKIA Intellectual Property. 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.dcaegen2.services.sdk.rest.services.aai.client.service.http.put; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration; + +import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel; +import org.onap.dcaegen2.services.sdk.rest.services.model.JsonBodyBuilder; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication; + + +class AaiReactiveHttpPutClientTest { + private static final Integer SUCCESS_RESPONSE = 200; + private static AaiClientConfiguration aaiConfigurationMock = mock(AaiClientConfiguration.class); + + + private AaiReactiveHttpPutClient httpClient; + private WebClient webClient; + private WebClient.RequestBodyUriSpec requestBodyUriSpec; + private WebClient.ResponseSpec responseSpec; + + private Map<String, String> aaiHeaders; + private ClientResponse clientResponse; + private Mono<ClientResponse> clientResponseMono; + + private AaiModel aaiModel = mock(AaiModel.class); + private JsonBodyBuilder<AaiModel> jsonBodyBuilder = mock(JsonBodyBuilder.class); + + @BeforeEach + void setUp() { + setupHeaders(); + clientResponse = mock(ClientResponse.class); + clientResponseMono = Mono.just(clientResponse); + + when(aaiConfigurationMock.aaiHost()).thenReturn("54.45.33.2"); + when(aaiConfigurationMock.aaiProtocol()).thenReturn("https"); + when(aaiConfigurationMock.aaiPort()).thenReturn(1234); + when(aaiConfigurationMock.aaiUserName()).thenReturn("PRH"); + when(aaiConfigurationMock.aaiUserPassword()).thenReturn("PRH"); + when(aaiConfigurationMock.aaiBasePath()).thenReturn("/aai/v11"); + when(aaiConfigurationMock.aaiPnfPath()).thenReturn("/network/pnfs/pnf"); + when(aaiConfigurationMock.aaiHeaders()).thenReturn(aaiHeaders); + + when(aaiModel.getCorrelationId()).thenReturn("NOKnhfsadhff"); + + when(jsonBodyBuilder.createJsonBody(aaiModel)).thenReturn( + "{\"correlationId\":\"NOKnhfsadhff\"," + + "\"ipaddress-v4\":\"256.22.33.155\", " + + "\"ipaddress-v6\":\"200J:0db8:85a3:0000:0000:8a2e:0370:7334\"}"); + + httpClient = new AaiReactiveHttpPutClient(aaiConfigurationMock, jsonBodyBuilder); + + webClient = spy(WebClient.builder() + .defaultHeaders(httpHeaders -> httpHeaders.setAll(aaiHeaders)) + .filter(basicAuthentication(aaiConfigurationMock.aaiUserName(), aaiConfigurationMock.aaiUserPassword())) + .build()); + + requestBodyUriSpec = mock(WebClient.RequestBodyUriSpec.class); + responseSpec = mock(WebClient.ResponseSpec.class); + } + + @Test + void getAaiProducerResponse_shouldReturn200() { + //given + Mono<Integer> expectedResult = Mono.just(SUCCESS_RESPONSE); + + //when + mockWebClientDependantObject(); + doReturn(expectedResult).when(responseSpec).bodyToMono(Integer.class); + httpClient.createAaiWebClient(webClient); + + //then + StepVerifier.create(httpClient.getAaiProducerResponse(aaiModel)).expectSubscription() + .expectNextMatches(results -> { + Assertions.assertEquals(results, clientResponse); + return true; + }).verifyComplete(); + } + + + @Test + void getAppropriateUri_whenPassingCorrectedPathForPnf() { + Assertions.assertEquals(httpClient.getUri("NOKnhfsadhff"), + URI.create("https://54.45.33.2:1234/aai/v11/network/pnfs/pnf/NOKnhfsadhff")); + } + + + private void setupHeaders() { + aaiHeaders = new HashMap<>(); + aaiHeaders.put("X-FromAppId", "PRH"); + aaiHeaders.put("X-TransactionId", "vv-temp"); + aaiHeaders.put("Accept", "application/json"); + aaiHeaders.put("Real-Time", "true"); + aaiHeaders.put("Content-Type", "application/json"); + } + + private void mockWebClientDependantObject() { + WebClient.RequestHeadersSpec requestHeadersSpec = mock(WebClient.RequestHeadersSpec.class); + when(webClient.put()).thenReturn(requestBodyUriSpec); + when(requestBodyUriSpec.uri((URI) any())).thenReturn(requestBodyUriSpec); + when(requestBodyUriSpec.header(any(), any())).thenReturn(requestBodyUriSpec); + when(requestBodyUriSpec.body(any(), (Class<Object>) any())).thenReturn(requestHeadersSpec); + when(requestHeadersSpec.exchange()).thenReturn(clientResponseMono); + } +}
\ No newline at end of file diff --git a/rest-services/cbs-client/pom.xml b/rest-services/cbs-client/pom.xml index 86527e9c..2580762d 100644 --- a/rest-services/cbs-client/pom.xml +++ b/rest-services/cbs-client/pom.xml @@ -13,7 +13,7 @@ <groupId>org.onap.dcaegen2.services.sdk.rest.services</groupId> <artifactId>cbs-client</artifactId> - <version>1.1.2-SNAPSHOT</version> + <version>1.1.3-SNAPSHOT</version> <name>dcaegen2-services-sdk-rest-services-cbs-client</name> <description>Config Binding Service Rest Services Module</description> diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java index 3fb8da60..594db6d0 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java @@ -24,7 +24,6 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.providers; import com.google.gson.JsonObject; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.ImmutableEnvProperties; -import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; /** @@ -34,7 +33,6 @@ import reactor.core.publisher.Mono; * @version 1.0.0 * @since 1.0.0 */ -@Service public final class CloudConfigurationClient implements CloudConfigurationProvider { private final CloudConfigurationProvider cloudConfigurationProvider; diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java index 16a1dc3a..a0b4a6f0 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java @@ -27,14 +27,11 @@ import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuratio import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; -import org.springframework.web.util.DefaultUriBuilderFactory; import reactor.core.publisher.Mono; /** * @author <a href="mailto:przemyslaw.wasala@nokia.com">Przemysław Wąsala</a> on 11/15/18 */ -@Service public final class ReactiveCloudConfigurationProvider implements CloudConfigurationProvider { private static final Logger LOGGER = LoggerFactory.getLogger(ReactiveCloudConfigurationProvider.class); @@ -114,7 +111,7 @@ public final class ReactiveCloudConfigurationProvider implements CloudConfigurat } private String getUri(String host, Integer port, String... paths) { - return new DefaultUriBuilderFactory().builder() + return new URI.URIBuilder() .scheme("http") .host(host) .port(port) diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/URI.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/URI.java new file mode 100644 index 00000000..f478ff06 --- /dev/null +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/URI.java @@ -0,0 +1,164 @@ +/* + * ============LICENSE_START======================================================= + * DCAEGEN2-SERVICES-SDK + * ================================================================================ + * Copyright (C) 2019 NOKIA Intellectual Property. 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.dcaegen2.services.sdk.rest.services.cbs.client.providers; + +final class URI { + private String scheme; + private String host; + private int port; + private String path; + private String fragment; + private String authority; + private String userInfo; + private String query; + private String schemeSpecificPart; + private String string; + + private URI() { + } + + static final class URIBuilder { + private String scheme; + private String host; + private int port; + private String path; + private String fragment; + private String authority; + private String userInfo; + private String query; + private String schemeSpecificPart; + + URIBuilder scheme(String scheme) { + this.scheme = scheme; + return this; + } + + URIBuilder host(String host) { + this.host = host; + return this; + } + + URIBuilder port(int port) { + this.port = port; + return this; + } + + URIBuilder path(String path) { + this.path = path; + return this; + } + + URIBuilder fragment(String fragment) { + this.fragment = fragment; + return this; + } + + URIBuilder authority(String authority) { + this.authority = authority; + return this; + } + + URIBuilder userInfo(String userInfo) { + this.userInfo = userInfo; + return this; + } + + URIBuilder query(String query) { + this.query = query; + return this; + } + + URIBuilder schemeSpecificPart(String schemeSpecificPart) { + this.schemeSpecificPart = schemeSpecificPart; + return this; + } + + URI build() { + URI uri = new URI(); + uri.scheme = this.scheme; + uri.host = this.host; + uri.port = this.port; + uri.path = this.path; + uri.fragment = this.fragment; + uri.authority = this.authority; + uri.userInfo = this.userInfo; + uri.query = this.query; + uri.schemeSpecificPart = this.schemeSpecificPart; + return uri; + } + } + + @Override + public String toString() { + defineString(); + return string; + } + + private void defineString() { + if (string != null) return; + + StringBuffer sb = new StringBuffer(); + if (scheme != null) { + sb.append(scheme); + sb.append(':'); + } + if (isOpaque()) { + sb.append(schemeSpecificPart); + } else { + if (host != null) { + sb.append("//"); + if (userInfo != null) { + sb.append(userInfo); + sb.append('@'); + } + boolean needBrackets = ((host.indexOf(':') >= 0) + && !host.startsWith("[") + && !host.endsWith("]")); + if (needBrackets) sb.append('['); + sb.append(host); + if (needBrackets) sb.append(']'); + if (port != -1) { + sb.append(':'); + sb.append(port); + } + } else if (authority != null) { + sb.append("//"); + sb.append(authority); + } + if (path != null) + sb.append(path); + if (query != null) { + sb.append('?'); + sb.append(query); + } + } + if (fragment != null) { + sb.append('#'); + sb.append(fragment); + } + string = sb.toString(); + } + + private boolean isOpaque() { + return path == null; + } +}
\ No newline at end of file |