Refactor of AAI HTTP Clients 83/79783/2
authorMarcin Migdal <marcin.migdal@nokia.com>
Wed, 6 Mar 2019 09:59:32 +0000 (10:59 +0100)
committerpwielebs <piotr.wielebski@nokia.com>
Wed, 6 Mar 2019 15:22:36 +0000 (16:22 +0100)
Change-Id: I020fb8342e70c159392aef913183bed94796a7ba
Issue-ID: DCAEGEN2-1277
Signed-off-by: pwielebs <piotr.wielebski@nokia.com>
rest-services/aai-client/pom.xml
rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/AaiHttpClientFactory.java
rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/get/AaiHttpGetClient.java
rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiHttpPatchClient.java

index 87ac847..037f183 100644 (file)
       <artifactId>common-dependency</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.onap.dcaegen2.services.sdk.security</groupId>
+      <artifactId>ssl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
index d304756..5e11745 100644 (file)
 
 package org.onap.dcaegen2.services.sdk.rest.services.aai.client.service;
 
-import io.netty.handler.codec.http.HttpHeaders;
 import io.netty.handler.ssl.SslContext;
+import io.vavr.control.Try;
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.get.AaiHttpGetClient;
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.patch.AaiHttpPatchClient;
-import org.onap.dcaegen2.services.sdk.rest.services.model.JsonBodyBuilder;
-import org.onap.dcaegen2.services.sdk.rest.services.ssl.SslFactory;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.model.logging.ImmutableRequestDiagnosticContext;
+import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext;
+import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeys;
+import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeysStore;
+import org.onap.dcaegen2.services.sdk.security.ssl.Passwords;
+import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys;
+import org.onap.dcaegen2.services.sdk.security.ssl.SslFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import reactor.netty.Connection;
-import reactor.netty.http.client.HttpClient;
-import reactor.netty.http.client.HttpClientRequest;
-import reactor.netty.http.client.HttpClientResponse;
 
-import javax.net.ssl.SSLException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Base64;
-import java.util.Map;
-import java.util.function.BiConsumer;
+import java.util.UUID;
 
 public class AaiHttpClientFactory {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AaiHttpClientFactory.class);
 
     private final AaiClientConfiguration configuration;
-    private final SslFactory sslFactory;
+    private final SslFactory sslFactory = new SslFactory();
 
 
-    public AaiHttpClientFactory(SslFactory sslFactory, AaiClientConfiguration configuration) {
+    public AaiHttpClientFactory(AaiClientConfiguration configuration) {
         this.configuration = configuration;
-        this.sslFactory = sslFactory;
     }
 
-    public AaiHttpClient<String> get() throws SSLException {
-        return new AaiHttpGetClient(configuration).createAaiHttpClient(build());
-    }
-
-    public AaiHttpClient<Integer> patch(JsonBodyBuilder jsonBodyBuilder) throws SSLException {
-        return new AaiHttpPatchClient(configuration, jsonBodyBuilder).createAaiHttpClient(build());
-    }
-
-    private HttpClient build() throws SSLException {
+    public CloudHttpClient build() {
         LOGGER.debug("Setting ssl context");
-
-        SslContext sslContext = createSslContext();
-
-        return HttpClient.create()
-                .secure(sslContextSpec -> sslContextSpec.sslContext(sslContext))
-                .headers(this::settingHeaders)
-                .doOnRequest(logRequest())
-                .doOnResponse(logResponse());
+        return new CloudHttpClient(createSslContext());
     }
 
-    private SslContext createSslContext() throws SSLException {
+    private SslContext createSslContext() {
         if (configuration.enableAaiCertAuth()) {
-            return sslFactory.createSecureContext(
-                    configuration.keyStorePath(),
-                    configuration.keyStorePasswordPath(),
-                    configuration.trustStorePath(),
-                    configuration.trustStorePasswordPath()
-            );
+            final SecurityKeys collectorSecurityKeys = ImmutableSecurityKeys.builder()
+                    .keyStore(ImmutableSecurityKeysStore.of(resource(configuration.keyStorePath()).get()))
+                    .keyStorePassword(Passwords.fromResource(configuration.keyStorePasswordPath()))
+                    .trustStore(ImmutableSecurityKeysStore.of(resource(configuration.trustStorePath()).get()))
+                    .trustStorePassword(Passwords.fromResource(configuration.trustStorePasswordPath()))
+                    .build();
+            return sslFactory.createSecureClientContext(collectorSecurityKeys);
         }
-        return sslFactory.createInsecureContext();
+        return sslFactory.createInsecureClientContext();
     }
 
-    private HttpHeaders settingHeaders(HttpHeaders httpHeaders) {
-        httpHeaders.add("Authorization", "Basic " + performBasicAuthentication());
-        for(Map.Entry<String,String> header : configuration.aaiHeaders().entrySet())
-            httpHeaders.add(header.getKey(), header.getValue());
-        return httpHeaders;
+    private Try<Path> resource(String resource) {
+        return Try.of(() -> Paths.get(Passwords.class.getResource(resource).toURI()));
     }
 
-    private String performBasicAuthentication() {
-        return Base64.getEncoder().encodeToString(
-                (configuration.aaiUserName() + ":" + configuration.aaiUserPassword()).getBytes()
-        );
+    public static String performBasicAuthentication(String userName, String password) {
+        return Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());
     }
 
-    private static BiConsumer<HttpClientRequest, Connection> logRequest() {
-        return (httpClientRequest, connection) -> {
-            LOGGER.info("Request: {} {}", httpClientRequest.method(), httpClientRequest.uri());
-            httpClientRequest.requestHeaders().forEach(stringStringEntry ->
-                    LOGGER.info("{}={}", stringStringEntry.getKey(), stringStringEntry.getValue())
-            );
-        };
+    public static RequestDiagnosticContext createRequestDiagnosticContext() {
+        return ImmutableRequestDiagnosticContext.builder()
+                .invocationId(UUID.randomUUID()).requestId(UUID.randomUUID()).build();
     }
 
-    private static BiConsumer<? super HttpClientResponse, ? super Connection>  logResponse() {
-        return (httpClientResponse, connection) ->
-                LOGGER.info("ResponseStatus {}", httpClientResponse.status().code());
-    }
 }
index 7feffdd..07987d2 100644 (file)
@@ -22,42 +22,46 @@ package org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.get
 
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
 import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
 import org.onap.dcaegen2.services.sdk.rest.services.uri.URI;
 import reactor.core.publisher.Mono;
-import reactor.netty.http.client.HttpClient;
+
+import static org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory.createRequestDiagnosticContext;
+import static org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory.performBasicAuthentication;
 
 
 public final class AaiHttpGetClient implements AaiHttpClient<String> {
 
-    private HttpClient httpClient;
+    private CloudHttpClient httpGetClient;
     private final AaiClientConfiguration configuration;
 
 
     public AaiHttpGetClient(AaiClientConfiguration configuration) {
         this.configuration = configuration;
+        addAuthorizationBasicHeader();
     }
 
     @Override
     public Mono<String> getAaiResponse(AaiModel aaiModel) {
-        return httpClient
-                .baseUrl(getUri(aaiModel.getCorrelationId()))
-                .get()
-                .responseContent()
-                .aggregate()
-                .asString();
+        return httpGetClient.get(getUri(aaiModel.getCorrelationId()), createRequestDiagnosticContext(), configuration.aaiHeaders(), String.class);
     }
 
-    public AaiHttpGetClient createAaiHttpClient(HttpClient httpClient) {
-        this.httpClient = httpClient;
+    public AaiHttpGetClient createAaiHttpClient(CloudHttpClient httpGetClient) {
+        this.httpGetClient = httpGetClient;
         return this;
     }
 
-    String getUri(String pnfName) {
+    private String getUri(String pnfName) {
         return new URI.URIBuilder()
                 .scheme(configuration.aaiProtocol())
                 .host(configuration.aaiHost())
                 .port(configuration.aaiPort())
                 .path(configuration.aaiBasePath() + configuration.aaiPnfPath() + "/" + pnfName).build().toString();
     }
+
+    private void addAuthorizationBasicHeader() {
+        configuration.aaiHeaders().put("Authorization",
+                "Basic " + performBasicAuthentication(configuration.aaiUserName(), configuration.aaiUserPassword()));
+    }
 }
index 51000b0..cfaec6f 100644 (file)
 
 package org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.patch;
 
-import io.netty.handler.codec.http.HttpHeaders;
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
 import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
 import org.onap.dcaegen2.services.sdk.rest.services.model.JsonBodyBuilder;
 import org.onap.dcaegen2.services.sdk.rest.services.uri.URI;
-import org.slf4j.MDC;
 import reactor.core.publisher.Mono;
-import reactor.netty.ByteBufFlux;
-import reactor.netty.http.client.HttpClient;
 
-import java.util.UUID;
-import java.util.function.Consumer;
+import static org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory.createRequestDiagnosticContext;
+import static org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory.performBasicAuthentication;
 
-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 final class AaiHttpPatchClient implements AaiHttpClient<Integer> {
 
-    private HttpClient httpClient;
+    private CloudHttpClient httpPatchClient;
     private final AaiClientConfiguration configuration;
     private final JsonBodyBuilder jsonBodyBuilder;
 
@@ -48,24 +42,20 @@ public final class AaiHttpPatchClient implements AaiHttpClient<Integer> {
     public AaiHttpPatchClient(final AaiClientConfiguration configuration, JsonBodyBuilder jsonBodyBuilder) {
         this.configuration = configuration;
         this.jsonBodyBuilder = jsonBodyBuilder;
+        addAuthorizationBasicHeader();
     }
 
-
     public Mono<Integer> getAaiResponse(AaiModel aaiModel) {
-        return httpClient
-                .headers(addHeaders())
-                .baseUrl(getUri(aaiModel.getCorrelationId()))
-                .patch()
-                .send(ByteBufFlux.fromString(Mono.just(jsonBodyBuilder.createJsonBody(aaiModel))))
-                .responseSingle((res, content) -> Mono.just(res.status().code()));
+        return httpPatchClient
+                .patch(getUri(aaiModel.getCorrelationId()), createRequestDiagnosticContext(), configuration.aaiHeaders(), jsonBodyBuilder, aaiModel);
     }
 
-    public AaiHttpPatchClient createAaiHttpClient(HttpClient httpClient) {
-        this.httpClient = httpClient;
+    public AaiHttpPatchClient createAaiHttpClient(CloudHttpClient httpPatchClient) {
+        this.httpPatchClient = httpPatchClient;
         return this;
     }
 
-    String getUri(String pnfName) {
+    private String getUri(String pnfName) {
         return new URI.URIBuilder()
                 .scheme(configuration.aaiProtocol())
                 .host(configuration.aaiHost())
@@ -73,10 +63,8 @@ public final class AaiHttpPatchClient implements AaiHttpClient<Integer> {
                 .path(configuration.aaiBasePath() + configuration.aaiPnfPath() + "/" + pnfName).build().toString();
     }
 
-    private Consumer<? super HttpHeaders> addHeaders() {
-        return h -> {
-            h.add(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID));
-            h.add(X_INVOCATION_ID, UUID.randomUUID().toString());
-        };
+    private void addAuthorizationBasicHeader() {
+        configuration.aaiHeaders().put("Authorization",
+                "Basic " + performBasicAuthentication(configuration.aaiUserName(), configuration.aaiUserPassword()));
     }
 }