From 3666e89b3411e84b138279cccc8130df60c81f4c Mon Sep 17 00:00:00 2001 From: Marcin Migdal Date: Wed, 6 Mar 2019 10:59:32 +0100 Subject: Refactor of AAI HTTP Clients Change-Id: I020fb8342e70c159392aef913183bed94796a7ba Issue-ID: DCAEGEN2-1277 Signed-off-by: pwielebs --- rest-services/aai-client/pom.xml | 6 ++ .../aai/client/service/AaiHttpClientFactory.java | 93 ++++++++-------------- .../client/service/http/get/AaiHttpGetClient.java | 26 +++--- .../service/http/patch/AaiHttpPatchClient.java | 38 +++------ 4 files changed, 66 insertions(+), 97 deletions(-) (limited to 'rest-services/aai-client') diff --git a/rest-services/aai-client/pom.xml b/rest-services/aai-client/pom.xml index 87ac8470..037f183d 100644 --- a/rest-services/aai-client/pom.xml +++ b/rest-services/aai-client/pom.xml @@ -23,6 +23,12 @@ common-dependency ${project.version} + + org.onap.dcaegen2.services.sdk.security + ssl + ${project.version} + + org.junit.jupiter junit-jupiter-engine diff --git a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/AaiHttpClientFactory.java b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/AaiHttpClientFactory.java index d3047561..5e117456 100644 --- a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/AaiHttpClientFactory.java +++ b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/AaiHttpClientFactory.java @@ -20,95 +20,66 @@ 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 get() throws SSLException { - return new AaiHttpGetClient(configuration).createAaiHttpClient(build()); - } - - public AaiHttpClient 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 header : configuration.aaiHeaders().entrySet()) - httpHeaders.add(header.getKey(), header.getValue()); - return httpHeaders; + private Try 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 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 logResponse() { - return (httpClientResponse, connection) -> - LOGGER.info("ResponseStatus {}", httpClientResponse.status().code()); - } } diff --git a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/get/AaiHttpGetClient.java b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/get/AaiHttpGetClient.java index 7feffddc..07987d2e 100644 --- a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/get/AaiHttpGetClient.java +++ b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/get/AaiHttpGetClient.java @@ -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 { - private HttpClient httpClient; + private CloudHttpClient httpGetClient; private final AaiClientConfiguration configuration; public AaiHttpGetClient(AaiClientConfiguration configuration) { this.configuration = configuration; + addAuthorizationBasicHeader(); } @Override public Mono 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())); + } } diff --git a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiHttpPatchClient.java b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiHttpPatchClient.java index 51000b09..cfaec6ff 100644 --- a/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiHttpPatchClient.java +++ b/rest-services/aai-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/aai/client/service/http/patch/AaiHttpPatchClient.java @@ -20,27 +20,21 @@ 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 { - private HttpClient httpClient; + private CloudHttpClient httpPatchClient; private final AaiClientConfiguration configuration; private final JsonBodyBuilder jsonBodyBuilder; @@ -48,24 +42,20 @@ public final class AaiHttpPatchClient implements AaiHttpClient { public AaiHttpPatchClient(final AaiClientConfiguration configuration, JsonBodyBuilder jsonBodyBuilder) { this.configuration = configuration; this.jsonBodyBuilder = jsonBodyBuilder; + addAuthorizationBasicHeader(); } - public Mono 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 { .path(configuration.aaiBasePath() + configuration.aaiPnfPath() + "/" + pnfName).build().toString(); } - private Consumer 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())); } } -- cgit 1.2.3-korg