From 346105ffbbbfd785c47161019326aa88e6b9bfb6 Mon Sep 17 00:00:00 2001 From: micdzied Date: Tue, 27 Nov 2018 11:28:45 +0100 Subject: add dmaap client module Change-Id: I443a6e8be3b8a6897fc73dc8f1511772ec1d8833 Issue-ID: DCAEGEN2-994 Signed-off-by: micdzied --- .../client/config/DmaapConsumerConfiguration.java | 66 ++++++++++++ .../dmaap/client/config/DmaapCustomConfig.java | 95 +++++++++++++++++ .../client/config/DmaapPublisherConfiguration.java | 44 ++++++++ .../ConsumerReactiveHttpClientFactory.java | 43 ++++++++ .../consumer/DMaaPConsumerReactiveHttpClient.java | 104 +++++++++++++++++++ .../consumer/DMaaPReactiveWebClientFactory.java | 103 ++++++++++++++++++ .../producer/DMaaPPublisherReactiveHttpClient.java | 102 ++++++++++++++++++ .../service/producer/DmaaPRestTemplateFactory.java | 115 +++++++++++++++++++++ .../PublisherReactiveHttpClientFactory.java | 39 +++++++ .../config/DmaapConsumerConfigurationTest.java | 83 +++++++++++++++ .../config/DmaapPublisherConfigurationTest.java | 73 +++++++++++++ .../ConsumerReactiveHttpClientFactoryTest.java | 42 ++++++++ .../DMaaPConsumerReactiveHttpClientTest.java | 111 ++++++++++++++++++++ .../DMaaPReactiveWebClientFactoryTest.java | 86 +++++++++++++++ .../DMaaPPublisherReactiveHttpClientTest.java | 94 +++++++++++++++++ .../producer/DmaaPRestTemplateFactoryTest.java | 61 +++++++++++ .../PublisherReactiveHttpClientFactoryTest.java | 41 ++++++++ .../src/test/resources/keystore.password | 1 + .../src/test/resources/logback-test.xml | 21 ++++ .../src/test/resources/org.onap.dcae.jks | Bin 0 -> 4512 bytes .../src/test/resources/org.onap.dcae.trust.jks | Bin 0 -> 1413 bytes .../src/test/resources/truststore.password | 1 + 22 files changed, 1325 insertions(+) create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapConsumerConfiguration.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapCustomConfig.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapPublisherConfiguration.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactory.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClient.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactory.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClient.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactory.java create mode 100644 rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactory.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapConsumerConfigurationTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapPublisherConfigurationTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactoryTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClientTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactoryTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClientTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactoryTest.java create mode 100644 rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactoryTest.java create mode 100644 rest-services/dmaap-client/src/test/resources/keystore.password create mode 100644 rest-services/dmaap-client/src/test/resources/logback-test.xml create mode 100644 rest-services/dmaap-client/src/test/resources/org.onap.dcae.jks create mode 100644 rest-services/dmaap-client/src/test/resources/org.onap.dcae.trust.jks create mode 100644 rest-services/dmaap-client/src/test/resources/truststore.password (limited to 'rest-services/dmaap-client/src') diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapConsumerConfiguration.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapConsumerConfiguration.java new file mode 100644 index 00000000..f7107f7c --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapConsumerConfiguration.java @@ -0,0 +1,66 @@ +/* + * ============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.dmaap.client.config; + +import org.immutables.gson.Gson; +import org.immutables.value.Value; +import org.springframework.stereotype.Component; + +/** + * @author Przemysław Wąsala on 3/23/18 + */ +@Component +@Value.Immutable(prehash = true) +@Value.Style(builder = "new") +@Gson.TypeAdapters +public abstract class DmaapConsumerConfiguration implements DmaapCustomConfig { + + private static final long serialVersionUID = 1L; + + public static DmaapConsumerConfiguration.Builder builder() { + return ImmutableDmaapConsumerConfiguration.builder(); + } + + @Value.Parameter + public abstract String consumerId(); + + @Value.Parameter + public abstract String consumerGroup(); + + @Value.Parameter + public abstract Integer timeoutMs(); + + @Value.Parameter + public abstract Integer messageLimit(); + + public interface Builder extends + DmaapCustomConfig.Builder { + + Builder consumerId(String consumerId); + + Builder consumerGroup(String consumerGroup); + + Builder timeoutMs(Integer timeoutMs); + + Builder messageLimit(Integer messageLimit); + } + +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapCustomConfig.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapCustomConfig.java new file mode 100644 index 00000000..efeaa85f --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapCustomConfig.java @@ -0,0 +1,95 @@ +/* + * ============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.dmaap.client.config; + +import java.io.Serializable; +import org.immutables.value.Value; + +/** + * @author Przemysław Wąsala on 3/28/18 + */ +public interface DmaapCustomConfig extends Serializable { + + @Value.Parameter + String dmaapHostName(); + + @Value.Parameter + Integer dmaapPortNumber(); + + @Value.Parameter + String dmaapTopicName(); + + @Value.Parameter + String dmaapProtocol(); + + @Value.Parameter + String dmaapUserName(); + + @Value.Parameter + String dmaapUserPassword(); + + @Value.Parameter + String dmaapContentType(); + + @Value.Parameter + String trustStorePath(); + + @Value.Parameter + String trustStorePasswordPath(); + + @Value.Parameter + String keyStorePath(); + + @Value.Parameter + String keyStorePasswordPath(); + + @Value.Parameter + Boolean enableDmaapCertAuth(); + + interface Builder> { + + B dmaapHostName(String dmaapHostName); + + B dmaapPortNumber(Integer dmaapPortNumber); + + B dmaapTopicName(String dmaapTopicName); + + B dmaapProtocol(String dmaapProtocol); + + B dmaapUserName(String dmaapUserName); + + B dmaapUserPassword(String dmaapUserPassword); + + B dmaapContentType(String dmaapContentType); + + B trustStorePath(String trustStorePath); + + B trustStorePasswordPath(String trustStorePasswordPath); + + B keyStorePath(String keyStore); + + B keyStorePasswordPath(String keyStorePass); + + B enableDmaapCertAuth(Boolean enableDmaapCertAuth); + + T build(); + } +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapPublisherConfiguration.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapPublisherConfiguration.java new file mode 100644 index 00000000..3866f9b4 --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/config/DmaapPublisherConfiguration.java @@ -0,0 +1,44 @@ +/* + * ============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.dmaap.client.config; + +import org.immutables.gson.Gson; +import org.immutables.value.Value; + +/** + * @author Przemysław Wąsala on 3/23/18 + */ +@Value.Immutable(prehash = true) +@Value.Style(builder = "new") +@Gson.TypeAdapters +public abstract class DmaapPublisherConfiguration implements DmaapCustomConfig { + + private static final long serialVersionUID = 1L; + + public static DmaapPublisherConfiguration.Builder builder() { + return ImmutableDmaapPublisherConfiguration.builder(); + } + + interface Builder extends + DmaapCustomConfig.Builder { + + } +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactory.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactory.java new file mode 100644 index 00000000..7fd1021f --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactory.java @@ -0,0 +1,43 @@ +/* + * ============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.dmaap.client.service.consumer; + +import javax.net.ssl.SSLException; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; + +/** + * @author Przemysław Wąsala on 6/26/18 + */ +public class ConsumerReactiveHttpClientFactory { + + private final DMaaPReactiveWebClientFactory reactiveWebClientFactory; + + public ConsumerReactiveHttpClientFactory(DMaaPReactiveWebClientFactory reactiveWebClientFactory) { + this.reactiveWebClientFactory = reactiveWebClientFactory; + } + + public DMaaPConsumerReactiveHttpClient create(DmaapConsumerConfiguration consumerConfiguration) + throws SSLException { + return new DMaaPConsumerReactiveHttpClient(consumerConfiguration, + reactiveWebClientFactory.build(consumerConfiguration)); + } + +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClient.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClient.java new file mode 100644 index 00000000..f0172704 --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClient.java @@ -0,0 +1,104 @@ +/* + * ============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.dmaap.client.service.consumer; + +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; + +import java.net.URI; +import java.util.UUID; +import java.util.function.Consumer; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; +import org.slf4j.MDC; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.DefaultUriBuilderFactory; +import reactor.core.publisher.Mono; + +/** + * @author Przemysław Wąsala on 6/26/18 + */ +public class DMaaPConsumerReactiveHttpClient { + + private final String dmaapHostName; + private final String dmaapProtocol; + private final Integer dmaapPortNumber; + private final String dmaapTopicName; + private final String consumerGroup; + private final String consumerId; + private final String contentType; + private final WebClient webClient; + + /** + * Constructor of DMaaPConsumerReactiveHttpClient. + * + * @param consumerConfiguration - DMaaP consumer configuration object + */ + DMaaPConsumerReactiveHttpClient(DmaapConsumerConfiguration consumerConfiguration, WebClient webClient) { + this.dmaapHostName = consumerConfiguration.dmaapHostName(); + this.dmaapProtocol = consumerConfiguration.dmaapProtocol(); + this.dmaapPortNumber = consumerConfiguration.dmaapPortNumber(); + this.dmaapTopicName = consumerConfiguration.dmaapTopicName(); + this.consumerGroup = consumerConfiguration.consumerGroup(); + this.consumerId = consumerConfiguration.consumerId(); + this.contentType = consumerConfiguration.dmaapContentType(); + this.webClient = webClient; + } + + /** + * Function for calling DMaaP HTTP consumer - consuming messages from Kafka/DMaaP from topic. + * + * @return reactive response from DMaaP in string format + */ + public Mono getDMaaPConsumerResponse() { + return webClient + .get() + .uri(getUri()) + .headers(getHeaders()) + .retrieve() + .onStatus(HttpStatus::is4xxClientError, clientResponse -> + Mono.error(new RuntimeException("DmaaPConsumer HTTP " + clientResponse.statusCode())) + ) + .onStatus(HttpStatus::is5xxServerError, clientResponse -> + Mono.error(new RuntimeException("DmaaPConsumer HTTP " + clientResponse.statusCode()))) + .bodyToMono(String.class); + } + + private Consumer getHeaders() { + return httpHeaders -> { + httpHeaders.set(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID)); + httpHeaders.set(X_INVOCATION_ID, UUID.randomUUID().toString()); + httpHeaders.set(HttpHeaders.CONTENT_TYPE, contentType); + }; + } + + private String createRequestPath() { + return dmaapTopicName + "/" + consumerGroup + "/" + consumerId; + } + + + URI getUri() { + return new DefaultUriBuilderFactory().builder().scheme(dmaapProtocol).host(dmaapHostName).port(dmaapPortNumber) + .path(createRequestPath()).build(); + } +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactory.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactory.java new file mode 100644 index 00000000..b1f2ab02 --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactory.java @@ -0,0 +1,103 @@ +/* + * ============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.dmaap.client.service.consumer; + +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.RESPONSE_CODE; +import static org.onap.dcaegen2.services.sdk.rest.services.model.logging.MdcVariables.SERVICE_NAME; + +import io.netty.handler.ssl.SslContext; +import javax.net.ssl.SSLException; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.ssl.SslFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.http.client.reactive.ClientHttpConnector; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; + +/** + * @author Przemysław Wąsala on 7/4/18 + */ +public class DMaaPReactiveWebClientFactory { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final SslFactory sslFactory; + + public DMaaPReactiveWebClientFactory() { + this(new SslFactory()); + } + + DMaaPReactiveWebClientFactory(SslFactory sslFactory) { + this.sslFactory = sslFactory; + } + + /** + * Construct Reactive WebClient with appropriate settings. + * + * @return WebClient + */ + public WebClient build(DmaapConsumerConfiguration consumerConfiguration) throws SSLException { + SslContext sslContext = createSslContext(consumerConfiguration); + ClientHttpConnector reactorClientHttpConnector = new ReactorClientHttpConnector( + HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext))); + return WebClient.builder() + .clientConnector(reactorClientHttpConnector) + .filter(logRequest()) + .filter(logResponse()) + .build(); + } + + private SslContext createSslContext(DmaapConsumerConfiguration consumerConfiguration) throws SSLException { + if (consumerConfiguration.enableDmaapCertAuth()) { + return sslFactory.createSecureContext( + consumerConfiguration.keyStorePath(), consumerConfiguration.keyStorePasswordPath(), + consumerConfiguration.trustStorePath(), consumerConfiguration.trustStorePasswordPath() + ); + } + return sslFactory.createInsecureContext(); + } + + private ExchangeFilterFunction logResponse() { + return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + MDC.put(RESPONSE_CODE, String.valueOf(clientResponse.statusCode())); + logger.info("Response Status {}", clientResponse.statusCode()); + MDC.remove(RESPONSE_CODE); + return Mono.just(clientResponse); + }); + } + + private ExchangeFilterFunction logRequest() { + return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + MDC.put(SERVICE_NAME, String.valueOf(clientRequest.url())); + logger.info("Request: {} {}", clientRequest.method(), clientRequest.url()); + clientRequest.headers() + .forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); + MDC.remove(SERVICE_NAME); + return Mono.just(clientRequest); + }); + } + +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClient.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClient.java new file mode 100644 index 00000000..43a0b4cc --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClient.java @@ -0,0 +1,102 @@ +/* + * ============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.dmaap.client.service.producer; + +import static org.onap.dcaegen2.services.sdk.rest.services.model.CommonFunctions.createJsonBody; +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; + +import java.net.URI; +import java.util.UUID; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.model.ConsumerDmaapModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriBuilderFactory; +import reactor.core.publisher.Mono; + + +/** + * @author Przemysław Wąsala on 7/4/18 + */ +public class DMaaPPublisherReactiveHttpClient { + + private final Logger logger = LoggerFactory.getLogger(DMaaPPublisherReactiveHttpClient.class); + private final String dmaapHostName; + private final Integer dmaapPortNumber; + private final String dmaapProtocol; + private final String dmaapTopicName; + private final String dmaapContentType; + private final Mono restTemplateMono; + + /** + * Constructor DMaaPPublisherReactiveHttpClient. + * + * @param dmaapPublisherConfiguration - DMaaP producer configuration object + */ + DMaaPPublisherReactiveHttpClient(DmaapPublisherConfiguration dmaapPublisherConfiguration, + Mono restTemplateMono) { + this.dmaapHostName = dmaapPublisherConfiguration.dmaapHostName(); + this.dmaapProtocol = dmaapPublisherConfiguration.dmaapProtocol(); + this.dmaapPortNumber = dmaapPublisherConfiguration.dmaapPortNumber(); + this.dmaapTopicName = dmaapPublisherConfiguration.dmaapTopicName(); + this.dmaapContentType = dmaapPublisherConfiguration.dmaapContentType(); + this.restTemplateMono = restTemplateMono; + } + + /** + * Function for calling DMaaP HTTP producer - post request to DMaaP. + * + * @param consumerDmaapModelMono - object which will be sent to DMaaP + * @return status code of operation + */ + + public Mono> getDMaaPProducerResponse(ConsumerDmaapModel consumerDmaapModelMono) { + return Mono.defer(() -> { + HttpEntity request = new HttpEntity<>(createJsonBody(consumerDmaapModelMono), getAllHeaders()); + logger.info("Request: {} {}", getUri(), request); + return restTemplateMono.map( + restTemplate -> restTemplate.exchange(getUri(), HttpMethod.POST, request, String.class)); + }); + } + + private HttpHeaders getAllHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.set(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID)); + headers.set(X_INVOCATION_ID, UUID.randomUUID().toString()); + headers.set(HttpHeaders.CONTENT_TYPE, dmaapContentType); + return headers; + + } + + URI getUri() { + return new DefaultUriBuilderFactory().builder().scheme(dmaapProtocol).host(dmaapHostName).port(dmaapPortNumber) + .path(dmaapTopicName).build(); + } + +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactory.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactory.java new file mode 100644 index 00000000..fe2b2c10 --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactory.java @@ -0,0 +1,115 @@ +/* + * ============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.dmaap.client.service.producer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import javax.net.ssl.SSLContext; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; +import reactor.core.publisher.Mono; + +public class DmaaPRestTemplateFactory { + + /** + * Function for creating RestTemplate object. + * + * @param publisherConfiguration - DMaaP publisher configuration object + * @return RestTemplate with correct ssl configuration + */ + public Mono build(DmaapPublisherConfiguration publisherConfiguration) { + if (publisherConfiguration.enableDmaapCertAuth()) { + return createRestTemplateWithSslSetup(publisherConfiguration); + } + + return Mono.just(new RestTemplate()); + } + + private Mono createRestTemplateWithSslSetup(DmaapPublisherConfiguration publisherConfiguration) { + try { + RestTemplateBuilder builder = new RestTemplateBuilder(); + + SSLContext sslContext = createSslContext(publisherConfiguration, + loadPasswordFromFile(publisherConfiguration.keyStorePasswordPath()), + loadPasswordFromFile(publisherConfiguration.trustStorePasswordPath())); + + return Mono.just(builder + .requestFactory(() -> createRequestFactory(sslContext)).build()); + + } catch (GeneralSecurityException | IOException e) { + return Mono.error(e); + } + } + + private SSLContext createSslContext(DmaapPublisherConfiguration publisherConfiguration, + String keyStorePassword, String trustStorePassword) + throws IOException, GeneralSecurityException { + return new SSLContextBuilder() + .loadKeyMaterial( + keyStore(publisherConfiguration.keyStorePath(), keyStorePassword), + keyStorePassword.toCharArray()) + .loadTrustMaterial( + getFile(publisherConfiguration.trustStorePath()), trustStorePassword.toCharArray()) + .build(); + } + + private HttpComponentsClientHttpRequestFactory createRequestFactory(SSLContext sslContext) { + SSLConnectionSocketFactory socketFactory = + new SSLConnectionSocketFactory(sslContext); + HttpClient httpClient = HttpClients.custom() + .setSSLSocketFactory(socketFactory).build(); + + return new HttpComponentsClientHttpRequestFactory(httpClient); + } + + private KeyStore keyStore(String keyStoreFile, String keyStorePassword) + throws GeneralSecurityException, IOException { + KeyStore ks = KeyStore.getInstance("jks"); + ks.load(getResource(keyStoreFile), keyStorePassword.toCharArray()); + return ks; + } + + private File getFile(String fileName) { + return new File(fileName); + } + + private InputStream getResource(String fileName) throws FileNotFoundException { + return new FileInputStream(fileName); + } + + private String loadPasswordFromFile(String path) throws IOException { + return new String(Files.readAllBytes(Paths.get(path))); + } + +} diff --git a/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactory.java b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactory.java new file mode 100644 index 00000000..e5f3e19e --- /dev/null +++ b/rest-services/dmaap-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactory.java @@ -0,0 +1,39 @@ +/* + * ============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.dmaap.client.service.producer; + +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; + + +public class PublisherReactiveHttpClientFactory { + + private final DmaaPRestTemplateFactory restTemplateFactory; + + public PublisherReactiveHttpClientFactory(DmaaPRestTemplateFactory restTemplateFactory) { + this.restTemplateFactory = restTemplateFactory; + } + + public DMaaPPublisherReactiveHttpClient create(DmaapPublisherConfiguration publisherConfiguration) { + return new DMaaPPublisherReactiveHttpClient(publisherConfiguration, + restTemplateFactory.build(publisherConfiguration)); + } + +} diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapConsumerConfigurationTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapConsumerConfigurationTest.java new file mode 100644 index 00000000..d0210929 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapConsumerConfigurationTest.java @@ -0,0 +1,83 @@ +/* + * ============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.dmaap.client.service.config; + +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.ImmutableDmaapConsumerConfiguration; + +class DmaapConsumerConfigurationTest { + + @Test + void builder_shouldBuildConfigurationObject() { + + // Given + DmaapConsumerConfiguration configuration; + String consumerId = "1"; + String dmaapHostName = "localhost"; + Integer dmaapPortNumber = 2222; + String dmaapTopicName = "temp"; + String dmaapProtocol = "http"; + String dmaapUserName = "admin"; + String dmaapUserPassword = "admin"; + String dmaapContentType = "application/json"; + String consumerGroup = "other"; + Integer timeoutMs = 1000; + Integer messageLimit = 1000; + String trustStorePath = "trustStorePath"; + String trustStorePasswordPath = "trustStorePasswordPath"; + String keyStorePath = "keyStorePath"; + String keyStorePasswordPath = "keyStorePasswordPath"; + Boolean enableDmaapCertAuth = true; + + // When + configuration = new ImmutableDmaapConsumerConfiguration.Builder() + .consumerId(consumerId) + .dmaapHostName(dmaapHostName) + .dmaapPortNumber(dmaapPortNumber) + .dmaapTopicName(dmaapTopicName) + .dmaapProtocol(dmaapProtocol) + .dmaapUserName(dmaapUserName) + .dmaapUserPassword(dmaapUserPassword) + .dmaapContentType(dmaapContentType) + .consumerGroup(consumerGroup) + .timeoutMs(timeoutMs) + .messageLimit(messageLimit) + .trustStorePath(trustStorePath) + .trustStorePasswordPath(trustStorePasswordPath) + .keyStorePath(keyStorePath) + .keyStorePasswordPath(keyStorePasswordPath) + .enableDmaapCertAuth(enableDmaapCertAuth) + .build(); + + // Then + assertEquals("DmaapConsumerConfiguration{" + + "consumerId=1, consumerGroup=other, timeoutMs=1000, messageLimit=1000, dmaapHostName=localhost, " + + "dmaapPortNumber=2222, dmaapTopicName=temp, dmaapProtocol=http, dmaapUserName=admin, " + + "dmaapUserPassword=admin, dmaapContentType=application/json, " + + "trustStorePath=trustStorePath, trustStorePasswordPath=trustStorePasswordPath, " + + "keyStorePath=keyStorePath, keyStorePasswordPath=keyStorePasswordPath, enableDmaapCertAuth=true}", + configuration.toString()); + + } +} diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapPublisherConfigurationTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapPublisherConfigurationTest.java new file mode 100644 index 00000000..7128777a --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/config/DmaapPublisherConfigurationTest.java @@ -0,0 +1,73 @@ +/* + * ============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.dmaap.client.service.config; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.ImmutableDmaapPublisherConfiguration; + +class DmaapPublisherConfigurationTest { + + + @Test + void builder_shouldBuildConfigurationObject() { + + // Given + DmaapPublisherConfiguration configuration; + String dmaapHostName = "localhost"; + Integer dmaapPortNumber = 2222; + String dmaapTopicName = "temp"; + String dmaapProtocol = "http"; + String dmaapUserName = "admin"; + String dmaapUserPassword = "admin"; + String dmaapContentType = "application/json"; + String trustStorePath = "trustStorePath"; + String trustStorePasswordPath = "trustStorePasswordPath"; + String keyStorePath = "keyStorePath"; + String keyStorePasswordPath = "keyStorePasswordPath"; + Boolean enableDmaapCertAuth = true; + + // When + configuration = new ImmutableDmaapPublisherConfiguration.Builder() + .dmaapHostName(dmaapHostName) + .dmaapPortNumber(dmaapPortNumber) + .dmaapTopicName(dmaapTopicName) + .dmaapProtocol(dmaapProtocol) + .dmaapUserName(dmaapUserName) + .dmaapUserPassword(dmaapUserPassword) + .dmaapContentType(dmaapContentType) + .trustStorePath(trustStorePath) + .trustStorePasswordPath(trustStorePasswordPath) + .keyStorePath(keyStorePath) + .keyStorePasswordPath(keyStorePasswordPath) + .enableDmaapCertAuth(enableDmaapCertAuth) + .build(); + + // Then + assertEquals("DmaapPublisherConfiguration{dmaapHostName=localhost, dmaapPortNumber=2222, " + + "dmaapTopicName=temp, dmaapProtocol=http, dmaapUserName=admin, dmaapUserPassword=admin, " + + "dmaapContentType=application/json, trustStorePath=trustStorePath, " + + "trustStorePasswordPath=trustStorePasswordPath, keyStorePath=keyStorePath, " + + "keyStorePasswordPath=keyStorePasswordPath, enableDmaapCertAuth=true}", configuration.toString()); + } +} diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactoryTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactoryTest.java new file mode 100644 index 00000000..75eafcb6 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/ConsumerReactiveHttpClientFactoryTest.java @@ -0,0 +1,42 @@ +/* + * ============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.dmaap.client.service.consumer; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; + +class ConsumerReactiveHttpClientFactoryTest { + + private DmaapConsumerConfiguration dmaapConsumerConfiguration = mock(DmaapConsumerConfiguration.class); + private DMaaPReactiveWebClientFactory reactiveWebClientFactory = mock(DMaaPReactiveWebClientFactory.class); + private ConsumerReactiveHttpClientFactory httpClientFactory = + new ConsumerReactiveHttpClientFactory(reactiveWebClientFactory); + + @Test + void create_shouldReturnNotNullFactoryInstance() throws Exception { + Assertions.assertNotNull(httpClientFactory.create(dmaapConsumerConfiguration)); + verify(reactiveWebClientFactory).build(dmaapConsumerConfiguration); + } +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClientTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClientTest.java new file mode 100644 index 00000000..9a4a130c --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPConsumerReactiveHttpClientTest.java @@ -0,0 +1,111 @@ +/* + * ============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.dmaap.client.service.consumer; + +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 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.dmaap.client.config.DmaapConsumerConfiguration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec; +import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +/** + * @author Przemysław Wąsala on 6/27/18 + */ +class DMaaPConsumerReactiveHttpClientTest { + + private static final String JSON_MESSAGE = "{ \"responseFromDmaap\": \"Success\"}"; + private DMaaPConsumerReactiveHttpClient dmaapConsumerReactiveHttpClient; + private DmaapConsumerConfiguration consumerConfigurationMock = mock(DmaapConsumerConfiguration.class); + private Mono expectedResult = Mono.empty(); + private WebClient webClient; + private RequestHeadersUriSpec requestHeadersSpec; + private ResponseSpec responseSpec; + + + @BeforeEach + void setUp() { + when(consumerConfigurationMock.dmaapHostName()).thenReturn("54.45.33.2"); + when(consumerConfigurationMock.dmaapProtocol()).thenReturn("https"); + when(consumerConfigurationMock.dmaapPortNumber()).thenReturn(1234); + when(consumerConfigurationMock.dmaapUserName()).thenReturn("PRH"); + when(consumerConfigurationMock.dmaapUserPassword()).thenReturn("PRH"); + when(consumerConfigurationMock.dmaapContentType()).thenReturn("application/json"); + when(consumerConfigurationMock.dmaapTopicName()).thenReturn("unauthenticated.SEC_OTHER_OUTPUT"); + when(consumerConfigurationMock.consumerGroup()).thenReturn("OpenDCAE-c12"); + when(consumerConfigurationMock.consumerId()).thenReturn("c12"); + + webClient = spy(WebClient.builder() + .defaultHeader(HttpHeaders.CONTENT_TYPE, consumerConfigurationMock.dmaapContentType()) + .filter(basicAuthentication(consumerConfigurationMock.dmaapUserName(), + consumerConfigurationMock.dmaapUserPassword())) + .build()); + dmaapConsumerReactiveHttpClient = new DMaaPConsumerReactiveHttpClient(consumerConfigurationMock, webClient); + requestHeadersSpec = mock(RequestHeadersUriSpec.class); + responseSpec = mock(ResponseSpec.class); + } + + + @Test + void getHttpResponse_Success() { + //given + expectedResult = Mono.just(JSON_MESSAGE); + + //when + mockDependantObjects(); + doReturn(expectedResult).when(responseSpec).bodyToMono(String.class); + Mono response = dmaapConsumerReactiveHttpClient.getDMaaPConsumerResponse(); + + //then + StepVerifier.create(response).expectSubscription() + .expectNextMatches(results -> { + Assertions.assertEquals(results, expectedResult.block()); + return true; + }).verifyComplete(); + } + + @Test + void getAppropriateUri_whenPassingCorrectedPathForPnf() { + Assertions.assertEquals(dmaapConsumerReactiveHttpClient.getUri(), + URI.create("https://54.45.33.2:1234/unauthenticated.SEC_OTHER_OUTPUT/OpenDCAE-c12/c12")); + } + + private void mockDependantObjects() { + when(webClient.get()).thenReturn(requestHeadersSpec); + when(requestHeadersSpec.uri((URI) any())).thenReturn(requestHeadersSpec); + when(requestHeadersSpec.headers(any())).thenReturn(requestHeadersSpec); + when(requestHeadersSpec.retrieve()).thenReturn(responseSpec); + doReturn(responseSpec).when(responseSpec).onStatus(any(), any()); + } + +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactoryTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactoryTest.java new file mode 100644 index 00000000..d28bc5d7 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/consumer/DMaaPReactiveWebClientFactoryTest.java @@ -0,0 +1,86 @@ +/* + * ============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.dmaap.client.service.consumer; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapConsumerConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.ssl.SslFactory; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * @author Przemysław Wąsala on 7/5/18 + */ +class DMaaPReactiveWebClientFactoryTest { + + private static final String KEY_STORE = "keyStore"; + private static final String KEY_STORE_PASS = "keyStorePass"; + private static final String TRUST_STORE = "trustStore"; + private static final String TRUST_STORE_PASS = "trustStorePass"; + private SslFactory sslFactory = mock(SslFactory.class); + private DMaaPReactiveWebClientFactory webClientFactory = new DMaaPReactiveWebClientFactory(sslFactory); + + @Test + void builder_shouldBuildDMaaPReactiveWebClientwithInsecureSslContext() throws Exception { + //given + DmaapConsumerConfiguration dmaapConsumerConfiguration = givenDmaapConfigurationWithSslDisabled(); + + //when + WebClient dmaapReactiveWebClient = webClientFactory.build(dmaapConsumerConfiguration); + + //then + Assertions.assertNotNull(dmaapReactiveWebClient); + verify(sslFactory).createInsecureContext(); + } + + @Test + void builder_shouldBuildDMaaPReactiveWebClientwithSecureSslContext() throws Exception { + //given + DmaapConsumerConfiguration dmaapConsumerConfiguration = givenDmaapConfigurationWithSslEnabled(); + + //when + WebClient dmaapReactiveWebClient = webClientFactory.build(dmaapConsumerConfiguration); + + //then + Assertions.assertNotNull(dmaapReactiveWebClient); + verify(sslFactory).createSecureContext(KEY_STORE, KEY_STORE_PASS, TRUST_STORE, TRUST_STORE_PASS); + } + + private DmaapConsumerConfiguration givenDmaapConfigurationWithSslDisabled() { + DmaapConsumerConfiguration dmaapConsumerConfiguration = mock(DmaapConsumerConfiguration.class); + when(dmaapConsumerConfiguration.enableDmaapCertAuth()).thenReturn(false); + return dmaapConsumerConfiguration; + } + + private DmaapConsumerConfiguration givenDmaapConfigurationWithSslEnabled() { + DmaapConsumerConfiguration dmaapConsumerConfiguration = mock(DmaapConsumerConfiguration.class); + when(dmaapConsumerConfiguration.enableDmaapCertAuth()).thenReturn(true); + when(dmaapConsumerConfiguration.keyStorePath()).thenReturn(KEY_STORE); + when(dmaapConsumerConfiguration.keyStorePasswordPath()).thenReturn(KEY_STORE_PASS); + when(dmaapConsumerConfiguration.trustStorePath()).thenReturn(TRUST_STORE); + when(dmaapConsumerConfiguration.trustStorePasswordPath()).thenReturn(TRUST_STORE_PASS); + return dmaapConsumerConfiguration; + } +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClientTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClientTest.java new file mode 100644 index 00000000..ac743266 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DMaaPPublisherReactiveHttpClientTest.java @@ -0,0 +1,94 @@ +/* + * ============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.dmaap.client.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.when; + +import java.net.URI; +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.dmaap.client.config.DmaapPublisherConfiguration; +import org.onap.dcaegen2.services.sdk.rest.services.model.ConsumerDmaapModel; +import org.onap.dcaegen2.services.sdk.rest.services.model.ImmutableConsumerDmaapModel; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +/** + * @author Przemysław Wąsala on 7/4/18 + */ + +class DMaaPPublisherReactiveHttpClientTest { + + private DMaaPPublisherReactiveHttpClient dmaapPublisherReactiveHttpClient; + private DmaapPublisherConfiguration dmaapPublisherConfigurationMock = mock( + DmaapPublisherConfiguration.class); + private ConsumerDmaapModel consumerDmaapModel = ImmutableConsumerDmaapModel.builder() + .correlationId("NOKnhfsadhff") + .ipv4("256.22.33.155") + .ipv6("200J:0db8:85a3:0000:0000:8a2e:0370:7334") + .build(); + private RestTemplate restTemplate = mock(RestTemplate.class); + + + @BeforeEach + void setUp() { + when(dmaapPublisherConfigurationMock.dmaapHostName()).thenReturn("54.45.33.2"); + when(dmaapPublisherConfigurationMock.dmaapProtocol()).thenReturn("https"); + when(dmaapPublisherConfigurationMock.dmaapPortNumber()).thenReturn(1234); + when(dmaapPublisherConfigurationMock.dmaapUserName()).thenReturn("PRH"); + when(dmaapPublisherConfigurationMock.dmaapUserPassword()).thenReturn("PRH"); + when(dmaapPublisherConfigurationMock.dmaapContentType()).thenReturn("application/json"); + when(dmaapPublisherConfigurationMock.dmaapTopicName()).thenReturn("unauthenticated.PNF_READY"); + dmaapPublisherReactiveHttpClient = + new DMaaPPublisherReactiveHttpClient(dmaapPublisherConfigurationMock, Mono.just(restTemplate)); + + } + + @Test + void getHttpResponse_Success() { + //given + int responseSuccess = 200; + ResponseEntity mockedResponseEntity = mock(ResponseEntity.class); + //when + when(mockedResponseEntity.getStatusCode()).thenReturn(HttpStatus.valueOf(responseSuccess)); + doReturn(mockedResponseEntity).when(restTemplate) + .exchange(any(URI.class), any(HttpMethod.class), any(HttpEntity.class), (Class) any()); + + //then + StepVerifier.create(dmaapPublisherReactiveHttpClient.getDMaaPProducerResponse(consumerDmaapModel)) + .expectSubscription().expectNext(mockedResponseEntity).verifyComplete(); + } + + @Test + void getAppropriateUri_whenPassingCorrectedPathForPnf() { + Assertions.assertEquals(dmaapPublisherReactiveHttpClient.getUri(), + URI.create("https://54.45.33.2:1234/unauthenticated.PNF_READY")); + } +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactoryTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactoryTest.java new file mode 100644 index 00000000..bd3b07e9 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/DmaaPRestTemplateFactoryTest.java @@ -0,0 +1,61 @@ +/* + * ============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.dmaap.client.service.producer; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; + + +class DmaaPRestTemplateFactoryTest { + + private static final String KEY_STORE = "org.onap.dcae.jks"; + private static final String KEYSTORE_PASSWORD = "keystore.password"; + private static final String TRUSTSTORE_PASSWORD = "truststore.password"; + private static final String TRUST_STORE = "org.onap.dcae.trust.jks"; + private DmaapPublisherConfiguration publisherConfiguration = mock(DmaapPublisherConfiguration.class); + private DmaaPRestTemplateFactory factory = new DmaaPRestTemplateFactory(); + + @Test + void build_shouldCreateRestTemplateWithoutSslConfiguration() { + when(publisherConfiguration.enableDmaapCertAuth()).thenReturn(false); + + Assertions.assertNotNull(factory.build(publisherConfiguration).block()); + } + + @Test + void build_shouldCreateRestTemplateWithSslConfiguration() { + when(publisherConfiguration.enableDmaapCertAuth()).thenReturn(true); + when(publisherConfiguration.keyStorePath()).thenReturn(getPath(KEY_STORE)); + when(publisherConfiguration.keyStorePasswordPath()).thenReturn(getPath(KEYSTORE_PASSWORD)); + when(publisherConfiguration.trustStorePath()).thenReturn(getPath(TRUST_STORE)); + when(publisherConfiguration.trustStorePasswordPath()).thenReturn(getPath(TRUSTSTORE_PASSWORD)); + + Assertions.assertNotNull(factory.build(publisherConfiguration).block()); + } + + private String getPath(String fileName) { + return this.getClass().getClassLoader().getResource(fileName).getPath(); + } +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactoryTest.java b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactoryTest.java new file mode 100644 index 00000000..faed10d9 --- /dev/null +++ b/rest-services/dmaap-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/dmaap/client/service/producer/PublisherReactiveHttpClientFactoryTest.java @@ -0,0 +1,41 @@ +/* + * ============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.dmaap.client.service.producer; + +import static org.mockito.Mockito.mock; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration; + + +class PublisherReactiveHttpClientFactoryTest { + + private DmaaPRestTemplateFactory restTemplateFactory = mock(DmaaPRestTemplateFactory.class); + private DmaapPublisherConfiguration dmaapPublisherConfiguration = mock(DmaapPublisherConfiguration.class); + private PublisherReactiveHttpClientFactory httpClientFactory = + new PublisherReactiveHttpClientFactory(restTemplateFactory); + + @Test + void create_shouldReturnNotNullFactoryInstance() { + Assertions.assertNotNull(httpClientFactory.create(dmaapPublisherConfiguration)); + } +} \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/resources/keystore.password b/rest-services/dmaap-client/src/test/resources/keystore.password new file mode 100644 index 00000000..39823872 --- /dev/null +++ b/rest-services/dmaap-client/src/test/resources/keystore.password @@ -0,0 +1 @@ +mYHC98!qX}7h?W}jRv}MIXTJ \ No newline at end of file diff --git a/rest-services/dmaap-client/src/test/resources/logback-test.xml b/rest-services/dmaap-client/src/test/resources/logback-test.xml new file mode 100644 index 00000000..c1f00665 --- /dev/null +++ b/rest-services/dmaap-client/src/test/resources/logback-test.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/rest-services/dmaap-client/src/test/resources/org.onap.dcae.jks b/rest-services/dmaap-client/src/test/resources/org.onap.dcae.jks new file mode 100644 index 00000000..e74ce64f Binary files /dev/null and b/rest-services/dmaap-client/src/test/resources/org.onap.dcae.jks differ diff --git a/rest-services/dmaap-client/src/test/resources/org.onap.dcae.trust.jks b/rest-services/dmaap-client/src/test/resources/org.onap.dcae.trust.jks new file mode 100644 index 00000000..10103cfb Binary files /dev/null and b/rest-services/dmaap-client/src/test/resources/org.onap.dcae.trust.jks differ diff --git a/rest-services/dmaap-client/src/test/resources/truststore.password b/rest-services/dmaap-client/src/test/resources/truststore.password new file mode 100644 index 00000000..168e64bd --- /dev/null +++ b/rest-services/dmaap-client/src/test/resources/truststore.password @@ -0,0 +1 @@ +*TQH?Lnszprs4LmlAj38yds( \ No newline at end of file -- cgit 1.2.3-korg