Adding AAI reactive webClient

Change-Id: Iedf88dfe12f41f0d994bcfc7c94e21ddf945a001
Issue-ID: DCAEGEN2-609
Signed-off-by: pwielebs <piotr.wielebski@nokia.com>
diff --git a/prh-aai-client/pom.xml b/prh-aai-client/pom.xml
index f8aeea5..87cdf38 100644
--- a/prh-aai-client/pom.xml
+++ b/prh-aai-client/pom.xml
@@ -50,6 +50,11 @@
       <artifactId>gson</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-webflux</artifactId>
+      <version>5.0.5.RELEASE</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
     </dependency>
@@ -66,6 +71,11 @@
       <artifactId>commons-lang3</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-reactor-netty</artifactId>
+      <version>2.0.4.RELEASE</version>
+    </dependency>
+    <dependency>
       <groupId>org.onap.dcaegen2.services.prh</groupId>
       <artifactId>prh-commons</artifactId>
       <version>1.0.0-SNAPSHOT</version>
@@ -111,5 +121,10 @@
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>io.projectreactor</groupId>
+      <artifactId>reactor-test</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/config/AaiClientConfiguration.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/config/AaiClientConfiguration.java
index c9d7820..50259ba 100644
--- a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/config/AaiClientConfiguration.java
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/config/AaiClientConfiguration.java
@@ -41,7 +41,7 @@
     public abstract String aaiHost();
 
     @Value.Parameter
-    public abstract Integer aaiHostPortNumber();
+    public abstract Integer aaiPort();
 
     @Value.Parameter
     public abstract String aaiProtocol();
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiRequestException.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiRequestException.java
new file mode 100644
index 0000000..33654c7
--- /dev/null
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiRequestException.java
@@ -0,0 +1,31 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * 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.prh.exceptions;
+
+public class AaiRequestException extends Exception {
+    public AaiRequestException() {
+        super();
+    }
+
+    public AaiRequestException(String message) {
+        super(message);
+    }
+}
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiClientImpl.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiClientImpl.java
index f925257..d9ba7c8 100644
--- a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiClientImpl.java
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiClientImpl.java
@@ -79,7 +79,7 @@
 
         if (aaiUserName != null) {
             final String aaiHost = aaiClientConfig.aaiHost();
-            final Integer aaiHostPortNumber = aaiClientConfig.aaiHostPortNumber();
+            final Integer aaiHostPortNumber = aaiClientConfig.aaiPort();
             final String aaiUserPassword = aaiClientConfig.aaiUserPassword();
             final AuthScope aaiHostPortAuthScope = new AuthScope(aaiHost, aaiHostPortNumber);
             final Credentials aaiCredentials = new UsernamePasswordCredentials(aaiUserName, aaiUserPassword);
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClient.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClient.java
index 7c86d0e..3cd95f5 100644
--- a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClient.java
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClient.java
@@ -61,7 +61,7 @@
         closeableHttpClient = new AaiClientImpl(aaiClientConfiguration).getAaiHttpClient();
         aaiHost = aaiClientConfiguration.aaiHost();
         aaiProtocol = aaiClientConfiguration.aaiProtocol();
-        aaiHostPortNumber = aaiClientConfiguration.aaiHostPortNumber();
+        aaiHostPortNumber = aaiClientConfiguration.aaiPort();
         aaiPath = aaiClientConfiguration.aaiBasePath() + aaiClientConfiguration.aaiPnfPath();
         aaiHeaders = aaiClientConfiguration.aaiHeaders();
     }
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiProducerClient.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiProducerClient.java
index 0c3f580..b5368c6 100644
--- a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiProducerClient.java
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiProducerClient.java
@@ -67,7 +67,7 @@
         closeableHttpClient = new AaiClientImpl(aaiClientConfiguration).getAaiHttpClient();
         aaiHost = aaiClientConfiguration.aaiHost();
         aaiProtocol = aaiClientConfiguration.aaiProtocol();
-        aaiHostPortNumber = aaiClientConfiguration.aaiHostPortNumber();
+        aaiHostPortNumber = aaiClientConfiguration.aaiPort();
         aaiPath = aaiClientConfiguration.aaiBasePath() + aaiClientConfiguration.aaiPnfPath();
         aaiHeaders = aaiClientConfiguration.aaiHeaders();
         aaiUserName = aaiClientConfiguration.aaiUserName();
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiReactiveWebClient.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiReactiveWebClient.java
new file mode 100644
index 0000000..f3b511a
--- /dev/null
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/AaiReactiveWebClient.java
@@ -0,0 +1,83 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * 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.prh.service;
+
+import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;
+
+import java.util.Map;
+import org.onap.dcaegen2.services.prh.config.AaiClientConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+
+public class AaiReactiveWebClient {
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private String aaiUserName;
+    private String aaiUserPassword;
+    private Map<String, String> aaiHeaders;
+
+    /**
+     * Creating AaiReactiveWebClient
+     * @param configuration - configuration object
+     * @return AaiReactiveWebClient
+     */
+    public AaiReactiveWebClient fromConfiguration(AaiClientConfiguration configuration) {
+        this.aaiUserName = configuration.aaiUserName();
+        this.aaiUserPassword = configuration.aaiUserPassword();
+        this.aaiHeaders = configuration.aaiHeaders();
+        return this;
+    }
+
+    /**
+     * Construct Reactive WebClient with appropriate settings.
+     *
+     * @return WebClient
+     */
+    public WebClient build() {
+        return WebClient.builder()
+                .defaultHeaders(httpHeaders -> httpHeaders.setAll(aaiHeaders))
+                .filter(basicAuthentication(aaiUserName, aaiUserPassword))
+                .filter(logRequest())
+                .filter(logResponse())
+                .build();
+    }
+
+    private ExchangeFilterFunction logRequest() {
+        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
+            logger.info("Request: {} {}", clientRequest.method(), clientRequest.url());
+            clientRequest.headers()
+                    .forEach((name, values) -> values.forEach(value -> logger.info("{}={}",name, value)));
+            return Mono.just(clientRequest);
+        });
+    }
+
+    private ExchangeFilterFunction logResponse() {
+        return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
+            logger.info("Response Status {}", clientResponse.statusCode());
+            return Mono.just(clientResponse);
+        });
+    }
+}
diff --git a/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClient.java b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClient.java
new file mode 100644
index 0000000..5547590
--- /dev/null
+++ b/prh-aai-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClient.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * 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.prh.service.producer;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.onap.dcaegen2.services.prh.config.AaiClientConfiguration;
+import org.onap.dcaegen2.services.prh.exceptions.AaiRequestException;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+
+public class AaiProducerReactiveHttpClient {
+
+    private WebClient webClient;
+    private final String aaiHost;
+    private final String aaiProtocol;
+    private final Integer aaiHostPortNumber;
+    private final String aaiBasePath;
+
+
+    /**
+     * Constructor
+     *
+     * @param configuration - AAI producer configuration object
+     */
+    public AaiProducerReactiveHttpClient(AaiClientConfiguration configuration) {
+        this.aaiHost = configuration.aaiHost();
+        this.aaiProtocol = configuration.aaiProtocol();
+        this.aaiHostPortNumber = configuration.aaiPort();
+        this.aaiBasePath = configuration.aaiBasePath();
+    }
+
+    /**
+     * Function for calling AAI Http producer - patch request to AAI database
+     *
+     * @param consumerDmaapModelMono - object which will be sent to AAI database
+     * @return status code of operation
+     */
+    public Mono<Integer> getAaiProducerResponse(Mono<ConsumerDmaapModel> consumerDmaapModelMono) {
+        return consumerDmaapModelMono.flatMap(this::patchAaiRequest);
+    }
+
+    public AaiProducerReactiveHttpClient createAaiWebClient(WebClient webClient) {
+        this.webClient = webClient;
+        return this;
+    }
+
+    private Mono<Integer> patchAaiRequest(ConsumerDmaapModel dmaapModel) {
+        try {
+            return webClient.patch()
+                    .uri(getUri(dmaapModel.getPnfName()))
+                    .body(BodyInserters.fromObject(dmaapModel))
+                    .retrieve()
+                    .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new AaiRequestException("HTTP 400")))
+                    .onStatus(HttpStatus::is5xxServerError, clientResponse -> Mono.error(new AaiRequestException("HTTP 500")))
+                    .bodyToMono(Integer.class);
+        } catch (URISyntaxException e) {
+            return Mono.error(e);
+        }
+    }
+
+    URI getUri(String pnfName) throws URISyntaxException {
+        return new URIBuilder()
+                .setScheme(aaiProtocol)
+                .setHost(aaiHost)
+                .setPort(aaiHostPortNumber)
+                .setPath(aaiBasePath + "/" + pnfName)
+                .build();
+    }
+}
diff --git a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClientTest.java b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClientTest.java
index 8b4a211..a7b82b5 100644
--- a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClientTest.java
+++ b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiConsumerClientTest.java
@@ -62,7 +62,7 @@
 
         when(aaiHttpClientConfigurationMock.aaiHost()).thenReturn("54.45.33.2");
         when(aaiHttpClientConfigurationMock.aaiProtocol()).thenReturn("https");
-        when(aaiHttpClientConfigurationMock.aaiHostPortNumber()).thenReturn(1234);
+        when(aaiHttpClientConfigurationMock.aaiPort()).thenReturn(1234);
         when(aaiHttpClientConfigurationMock.aaiUserName()).thenReturn("PRH");
         when(aaiHttpClientConfigurationMock.aaiUserPassword()).thenReturn("PRH");
         when(aaiHttpClientConfigurationMock.aaiBasePath()).thenReturn("/aai/v11");
diff --git a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiHttpClientImplTest.java b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiHttpClientImplTest.java
index 419fe32..ebedc4a 100644
--- a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiHttpClientImplTest.java
+++ b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiHttpClientImplTest.java
@@ -38,7 +38,7 @@
         AaiClientConfiguration aaiHttpClientConfigurationMock = mock(AaiClientConfiguration.class);
         when(aaiHttpClientConfigurationMock.aaiHost()).thenReturn("54.45.33.2");
         when(aaiHttpClientConfigurationMock.aaiProtocol()).thenReturn("https");
-        when(aaiHttpClientConfigurationMock.aaiHostPortNumber()).thenReturn(1234);
+        when(aaiHttpClientConfigurationMock.aaiPort()).thenReturn(1234);
         when(aaiHttpClientConfigurationMock.aaiUserName()).thenReturn("PNF");
         when(aaiHttpClientConfigurationMock.aaiUserPassword()).thenReturn("PNF");
         when(aaiHttpClientConfigurationMock.aaiIgnoreSslCertificateErrors()).thenReturn(true);
diff --git a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiProducerClientTest.java b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiProducerClientTest.java
index 27cb374..13d4dce 100644
--- a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiProducerClientTest.java
+++ b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/AaiProducerClientTest.java
@@ -64,7 +64,7 @@
     static void setup() throws NoSuchFieldException, IllegalAccessException {
         when(aaiHttpClientConfigurationMock.aaiHost()).thenReturn("eucalyptus.es-si-eu-dhn-20.eecloud.nsn-net.net");
         when(aaiHttpClientConfigurationMock.aaiProtocol()).thenReturn("https");
-        when(aaiHttpClientConfigurationMock.aaiHostPortNumber()).thenReturn(1234);
+        when(aaiHttpClientConfigurationMock.aaiPort()).thenReturn(1234);
         when(aaiHttpClientConfigurationMock.aaiUserName()).thenReturn("PRH");
         when(aaiHttpClientConfigurationMock.aaiUserPassword()).thenReturn("PRH");
         when(aaiHttpClientConfigurationMock.aaiBasePath()).thenReturn("/aai/v11");
diff --git a/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClientTest.java b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClientTest.java
new file mode 100644
index 0000000..3b6fe4d
--- /dev/null
+++ b/prh-aai-client/src/test/java/org/onap/dcaegen2/services/prh/service/producer/AaiProducerReactiveHttpClientTest.java
@@ -0,0 +1,140 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * 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.prh.service.producer;
+
+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;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.onap.dcaegen2.services.prh.config.AaiClientConfiguration;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModelForUnitTest;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+
+
+class AaiProducerReactiveHttpClientTest {
+
+    private static AaiProducerReactiveHttpClient aaiProducerReactiveHttpClient;
+
+    private static final Integer SUCCESS_RESPONSE = 200;
+
+    private static AaiClientConfiguration aaiConfigurationMock = mock(AaiClientConfiguration.class);
+    private static WebClient webClient = mock(WebClient.class);
+
+    private static ConsumerDmaapModel dmaapModel = new ConsumerDmaapModelForUnitTest();
+    private static WebClient.RequestBodyUriSpec requestBodyUriSpec;
+    private static ResponseSpec responseSpec;
+
+    private static Map<String, String> aaiHeaders;
+
+    @BeforeAll
+    static void setUp() {
+        setupHeaders();
+
+        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);
+
+        aaiProducerReactiveHttpClient = new AaiProducerReactiveHttpClient(aaiConfigurationMock);
+
+        webClient = spy(WebClient.builder()
+                .defaultHeaders(httpHeaders -> httpHeaders.setAll(aaiHeaders))
+                .filter(basicAuthentication(aaiConfigurationMock.aaiUserName(), aaiConfigurationMock.aaiUserPassword()))
+                .build());
+
+        requestBodyUriSpec = mock(WebClient.RequestBodyUriSpec.class);
+        responseSpec = mock(ResponseSpec.class);
+    }
+
+
+    @Test
+    void getAaiProducerResponse_shouldReturn200() {
+        //given
+        Mono<Integer> expectedResult = Mono.just(SUCCESS_RESPONSE);
+
+        //when
+        mockWebClientDependantObject();
+        doReturn(expectedResult).when(responseSpec).bodyToMono(Integer.class);
+        aaiProducerReactiveHttpClient.createAaiWebClient(webClient);
+        Mono<Integer> response = aaiProducerReactiveHttpClient.getAaiProducerResponse(Mono.just(dmaapModel));
+
+        //then
+        StepVerifier.create(response).expectSubscription()
+                .expectNextMatches(results -> {
+                    Assertions.assertEquals(results, expectedResult.block());
+                    return true;
+                }).verifyComplete();
+    }
+
+    @Test
+    void getHttpResponse_whenUriSyntaxExceptionHasBeenThrown() throws URISyntaxException {
+        ///given
+        aaiProducerReactiveHttpClient = spy(aaiProducerReactiveHttpClient);
+        //when
+        when(webClient.patch()).thenReturn(requestBodyUriSpec);
+        aaiProducerReactiveHttpClient.createAaiWebClient(webClient);
+        when(aaiProducerReactiveHttpClient.getUri("pnfName")).thenThrow(URISyntaxException.class);
+
+        //then
+        StepVerifier.create(aaiProducerReactiveHttpClient.getAaiProducerResponse(Mono.just(dmaapModel))).expectSubscription()
+                .expectError(Exception.class).verify();
+    }
+
+
+    private void mockWebClientDependantObject() {
+        WebClient.RequestHeadersSpec requestHeadersSpec = mock(WebClient.RequestHeadersSpec.class);
+        when(webClient.patch()).thenReturn(requestBodyUriSpec);
+        when(requestBodyUriSpec.uri((URI) any())).thenReturn(requestBodyUriSpec);
+        when(requestBodyUriSpec.body(any())).thenReturn(requestHeadersSpec);
+        doReturn(responseSpec).when(requestHeadersSpec).retrieve();
+        doReturn(responseSpec).when(responseSpec).onStatus(any(), any());
+    }
+
+    private static 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/merge-patch+json");
+    }
+
+}
+
diff --git a/prh-app-server/config/prh_endpoints.json b/prh-app-server/config/prh_endpoints.json
index f5f7959..429dac4 100644
--- a/prh-app-server/config/prh_endpoints.json
+++ b/prh-app-server/config/prh_endpoints.json
@@ -27,7 +27,7 @@
     "aai": {
       "aaiClientConfiguration": {
         "aaiHost": "localhost",
-        "aaiHostPortNumber": 8080,
+        "aaiPort": 8080,
         "aaiProtocol": "https",
         "aaiUserName": "AAI",
         "aaiUserPassword": "AAI",
@@ -38,7 +38,8 @@
           "X-FromAppId": "prh",
           "X-TransactionId": "9999",
           "Accept": "application/json",
-          "Real-Time": "true"
+          "Real-Time": "true",
+          "Content-Type":"application/merge-patch+json"
         }
       }
     }
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AppConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AppConfig.java
index e10c51d..c1000fe 100644
--- a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AppConfig.java
+++ b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AppConfig.java
@@ -101,7 +101,7 @@
     public String aaiHost;
 
     @Value("${aai.aaiClientConfiguration.aaiHostPortNumber:}")
-    public Integer aaiHostPortNumber;
+    public Integer aaiPort;
 
     @Value("${aai.aaiClientConfiguration.aaiProtocol:}")
     public String aaiProtocol;
@@ -161,9 +161,9 @@
     public AaiClientConfiguration getAaiClientConfiguration() {
         return new ImmutableAaiClientConfiguration.Builder()
             .aaiHost(Optional.ofNullable(aaiHost).filter(isEmpty.negate()).orElse(aaiClientConfiguration.aaiHost()))
-            .aaiHostPortNumber(
-                Optional.ofNullable(aaiHostPortNumber).filter(p -> !p.toString().isEmpty())
-                    .orElse(aaiClientConfiguration.aaiHostPortNumber()))
+            .aaiPort(
+                Optional.ofNullable(aaiPort).filter(p -> !p.toString().isEmpty())
+                    .orElse(aaiClientConfiguration.aaiPort()))
             .aaiIgnoreSslCertificateErrors(
                 Optional.ofNullable(aaiIgnoreSslCertificateErrors).filter(p -> !p.toString().isEmpty())
                     .orElse(aaiClientConfiguration.aaiIgnoreSslCertificateErrors()))
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfigTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfigTest.java
index 71c996b..6d1c4b9 100644
--- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfigTest.java
+++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfigTest.java
@@ -50,10 +50,10 @@
 
     private static final String PRH_ENDPOINTS = "prh_endpoints.json";
     private static final String jsonString = "{\"configs\":{\"aai\":{\"aaiClientConfiguration\":{\"aaiHost\":"
-        + "\"localhost\",\"aaiHostPortNumber\":8080,\"aaiIgnoreSslCertificateErrors\":true,\"aaiProtocol\":"
+        + "\"localhost\",\"aaiPort\":8080,\"aaiIgnoreSslCertificateErrors\":true,\"aaiProtocol\":"
         + "\"https\",\"aaiUserName\":\"admin\",\"aaiUserPassword\":\"admin\",\"aaiBasePath\":\"/aai/v11\","
         + "\"aaiPnfPath\":\"/network/pnfs/pnf\",\"aaiHeaders\":{\"X-FromAppId\":\"prh\",\"X-TransactionId\":\"9999\","
-        + "\"Accept\":\"application/json\",\"Real-Time\":\"true\",\"Authorization\":\"Basic QUFJOkFBSQ==\"}}},"
+        + "\"Accept\":\"application/json\",\"Real-Time\":\"true\",\"Content-Type\":\"application/merge-patch+json\",\"Authorization\":\"Basic QUFJOkFBSQ==\"}}},"
         + "\"dmaap\":{\"dmaapConsumerConfiguration\":{\"consumerGroup\":\"other\",\"consumerId\":\"1\","
         + "\"dmaapContentType\":\"application/json\",\"dmaapHostName\":\"localhost\",\"dmaapPortNumber\":2222,"
         + "\"dmaapProtocol\":\"http\",\"dmaapTopicName\":\"temp\",\"dmaapUserName\":\"admin\",\"dmaapUserPassword\""
@@ -62,10 +62,10 @@
         + "\"dmaapTopicName\":\"temp\",\"dmaapUserName\":\"admin\",\"dmaapUserPassword\":\"admin\"}}}}";
 
     private static final String incorrectJsonString = "{\"configs\":{\"aai\":{\"aaiClientConfiguration\":{\"aaiHost\":"
-        + "\"localhost\",\"aaiHostPortNumber\":8080,\"aaiIgnoreSslCertificateErrors\":true,\"aaiProtocol\":\"https\","
+        + "\"localhost\",\"aaiPort\":8080,\"aaiIgnoreSslCertificateErrors\":true,\"aaiProtocol\":\"https\","
         + "\"aaiUserName\":\"admin\",\"aaiUserPassword\":\"admin\",\"aaiBasePath\":\"/aai/v11\",\"aaiPnfPath\":"
         + "\"/network/pnfs/pnf\",\"aaiHeaders\":{\"X-FromAppId\":\"prh\",\"X-TransactionId\":\"9999\",\"Accept\":"
-        + "\"application/json\",\"Real-Time\":\"true\",\"Authorization\":\"Basic QUFJOkFBSQ==\"}}},\"dmaap\""
+        + "\"application/json\",\"Real-Time\":\"true\",\"Content-Type\":\"application/merge-patch+json\",\"Authorization\":\"Basic QUFJOkFBSQ==\"}}},\"dmaap\""
         + ":{\"dmaapConsumerConfiguration\":{\"consumerGroup\":\"other\",\"consumerId\":\"1\",\"dmaapContentType\""
         + ":\"application/json\",\"dmaapHostName\":\"localhost\",\"dmaapPortNumber\":2222,\"dmaapProtocol\":\"http\""
         + ",\"dmaapTopicName\":\"temp\",\"dmaapUserName\":\"admin\",\"dmaapUserPassword\":\"admin\",\"messageLimit\""
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiConsumerTaskImplTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiConsumerTaskImplTest.java
index 8af562b..ea458a0 100644
--- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiConsumerTaskImplTest.java
+++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiConsumerTaskImplTest.java
@@ -67,7 +67,7 @@
     static void setUp() {
         aaiClientConfiguration = new ImmutableAaiClientConfiguration.Builder()
             .aaiHost(AAI_HOST)
-            .aaiHostPortNumber(PORT)
+            .aaiPort(PORT)
             .aaiProtocol(PROTOCOL)
             .aaiUserName(USER_NAME_PASSWORD)
             .aaiUserPassword(USER_NAME_PASSWORD)
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImplTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImplTest.java
index 5e60bf0..9020612 100644
--- a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImplTest.java
+++ b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImplTest.java
@@ -71,7 +71,7 @@
     static void setUp() {
         aaiClientConfiguration = new ImmutableAaiClientConfiguration.Builder()
             .aaiHost(AAI_HOST)
-            .aaiHostPortNumber(PORT)
+            .aaiPort(PORT)
             .aaiProtocol(PROTOCOL)
             .aaiUserName(USER_NAME_PASSWORD)
             .aaiUserPassword(USER_NAME_PASSWORD)
diff --git a/prh-app-server/src/test/resources/prh_endpoints.json b/prh-app-server/src/test/resources/prh_endpoints.json
index b45ce48..84ad4fc 100644
--- a/prh-app-server/src/test/resources/prh_endpoints.json
+++ b/prh-app-server/src/test/resources/prh_endpoints.json
@@ -3,7 +3,7 @@
     "aai": {
       "aaiClientConfiguration": {
         "aaiHost": "localhost",
-        "aaiHostPortNumber": 8080,
+        "aaiPort": 8080,
         "aaiIgnoreSSLCertificateErrors": true,
         "aaiProtocol": "https",
         "aaiUserName": "AAI",
@@ -14,7 +14,8 @@
           "X-FromAppId": "prh",
           "X-TransactionId": "9999",
           "Accept": "application/json",
-          "Real-Time": "true"
+          "Real-Time": "true",
+          "Content-Type":"application/merge-patch+json"
         }
       }
     },
diff --git a/prh-dmaap-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/DMaaPProducerReactiveHttpClient.java b/prh-dmaap-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/DMaaPProducerReactiveHttpClient.java
index 8be69cd..0738847 100644
--- a/prh-dmaap-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/DMaaPProducerReactiveHttpClient.java
+++ b/prh-dmaap-client/src/main/java/org/onap/dcaegen2/services/prh/service/producer/DMaaPProducerReactiveHttpClient.java
@@ -60,7 +60,7 @@
     /**
      * Function for calling DMaaP HTTP producer - post request to DMaaP.
      *
-     * @param consumerDmaapModelMono - object which will be sended to DMaaP
+     * @param consumerDmaapModelMono - object which will be sent to DMaaP
      * @return status code of operation
      */
     public Mono<String> getDMaaPProducerResponse(Mono<ConsumerDmaapModel> consumerDmaapModelMono) {