diff options
Diffstat (limited to 'rest-services/cbs-client/src/main/java')
4 files changed, 139 insertions, 17 deletions
diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClientFactory.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClientFactory.java index 821805fc..00aad603 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClientFactory.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClientFactory.java @@ -25,6 +25,7 @@ import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClientFa import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.CbsClientImpl; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.CbsLookup; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model.CbsClientConfiguration; +import org.onap.dcaegen2.services.sdk.security.ssl.TrustStoreKeys; import reactor.core.publisher.Mono; /** @@ -54,10 +55,16 @@ public class CbsClientFactory { */ public static @NotNull Mono<CbsClient> createCbsClient(CbsClientConfiguration configuration) { return Mono.defer(() -> { - final RxHttpClient httpClient = RxHttpClientFactory.create(); - final CbsLookup lookup = new CbsLookup(); - return lookup.lookup(configuration) - .map(addr -> new CbsClientImpl(httpClient, configuration.appName(), addr)); + final RxHttpClient httpClient = buildHttpClient(configuration.trustStoreKeys()); + final CbsLookup cbsLookup = new CbsLookup(); + return cbsLookup.lookup(configuration) + .map(addr -> new CbsClientImpl(httpClient, configuration.appName(), addr, configuration.protocol())); }); } + + private static RxHttpClient buildHttpClient(TrustStoreKeys trustStoreKeys) { + return trustStoreKeys != null + ? RxHttpClientFactory.create(trustStoreKeys) + : RxHttpClientFactory.create(); + } } diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/exceptions/CbsClientConfigurationException.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/exceptions/CbsClientConfigurationException.java new file mode 100644 index 00000000..a7c88a3d --- /dev/null +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/exceptions/CbsClientConfigurationException.java @@ -0,0 +1,29 @@ +/* + * ============LICENSE_START==================================== + * DCAEGEN2-SERVICES-SDK + * ========================================================= + * Copyright (C) 2019 Nokia. All rights reserved. + * ========================================================= + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================== + */ + +package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.exceptions; + +import org.jetbrains.annotations.NotNull; + +public class CbsClientConfigurationException extends RuntimeException { + public CbsClientConfigurationException(final @NotNull String message) { + super(message); + } +}
\ No newline at end of file diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsClientImpl.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsClientImpl.java index 6f37cd2b..a895f3a1 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsClientImpl.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsClientImpl.java @@ -20,9 +20,6 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl; import com.google.gson.JsonObject; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URL; import org.jetbrains.annotations.NotNull; import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod; import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse; @@ -34,17 +31,23 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Mono; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.URL; + public class CbsClientImpl implements CbsClient { private static final Logger LOGGER = LoggerFactory.getLogger(CbsClientImpl.class); private final RxHttpClient httpClient; private final String serviceName; private final InetSocketAddress cbsAddress; + private final String protocol; - public CbsClientImpl(RxHttpClient httpClient, String serviceName, InetSocketAddress cbsAddress) { + public CbsClientImpl(RxHttpClient httpClient, String serviceName, InetSocketAddress cbsAddress, String protocol) { this.httpClient = httpClient; this.serviceName = serviceName; this.cbsAddress = cbsAddress; + this.protocol = protocol; } @Override @@ -66,7 +69,7 @@ public class CbsClientImpl implements CbsClient { private URL constructUrl(CbsRequest request) { try { return new URL( - "http", + this.protocol, cbsAddress.getHostString(), cbsAddress.getPort(), request.requestPath().getForService(serviceName)); diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/model/CbsClientConfiguration.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/model/CbsClientConfiguration.java index e3c7d2ea..2fb07501 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/model/CbsClientConfiguration.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/model/CbsClientConfiguration.java @@ -22,6 +22,17 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.model; import org.immutables.value.Value; import org.jetbrains.annotations.Nullable; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.exceptions.CbsClientConfigurationException; +import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableTrustStoreKeys; +import org.onap.dcaegen2.services.sdk.security.ssl.Passwords; +import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeysStore; +import org.onap.dcaegen2.services.sdk.security.ssl.TrustStoreKeys; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Optional; /** * Immutable object which helps with construction of cloudRequestObject for specified Client. For usage take a look in @@ -34,6 +45,16 @@ import org.jetbrains.annotations.Nullable; */ @Value.Immutable(prehash = true) public interface CbsClientConfiguration { + Logger LOGGER = LoggerFactory.getLogger(CbsClientConfiguration.class); + + String TRUST_JKS = "trust.jks"; + String TRUST_PASS = "trust.pass"; + Integer PORT_FOR_CBS_OVER_TLS = 10443; + + /** + * Name of environment variable containing path to the cacert.pem file. + */ + String DCAE_CA_CERT_PATH = "DCAE_CA_CERTPATH"; /** * Name of environment variable containing Config Binding Service network hostname. @@ -50,6 +71,7 @@ public interface CbsClientConfiguration { */ String ENV_APP_NAME = "HOSTNAME"; + /** * Name of environment variable containing Consul host name. * @@ -80,18 +102,25 @@ public interface CbsClientConfiguration { @Value.Parameter String appName(); + @Value.Parameter + @Nullable + String protocol(); + + @Value.Default + default @Nullable TrustStoreKeys trustStoreKeys() { + return null; + } + @Value.Default @Deprecated default String consulHost() { return "consul-server"; } - @Value.Default @Deprecated default Integer consulPort() { return 8500; } - @Value.Default @Deprecated default String cbsName() { @@ -102,14 +131,68 @@ public interface CbsClientConfiguration { * Creates CbsClientConfiguration from system environment variables. * * @return an instance of CbsClientConfiguration - * @throws NullPointerException when at least one of required parameters is missing + * @throws CbsClientConfigurationException when at least one of required parameters is missing */ static CbsClientConfiguration fromEnvironment() { - return ImmutableCbsClientConfiguration.builder() - .consulHost(System.getenv(ENV_CONSUL_HOST)) - .hostname(System.getenv(ENV_CBS_HOSTNAME)) - .port(Integer.valueOf(System.getenv(ENV_CBS_PORT))) - .appName(System.getenv(ENV_APP_NAME)) + String pathToCaCert = System.getenv(DCAE_CA_CERT_PATH); + + ImmutableCbsClientConfiguration.Builder configBuilder = ImmutableCbsClientConfiguration.builder() + .hostname(getEnv(ENV_CBS_HOSTNAME)) + .appName(getEnv(ENV_APP_NAME)); + return Optional.ofNullable(pathToCaCert).filter(certPath -> !"".equals(certPath)) + .map(certPath -> createSslHttpConfig(configBuilder, certPath)) + .orElse(createPlainHttpConfig(configBuilder)); + } + + static CbsClientConfiguration createPlainHttpConfig(ImmutableCbsClientConfiguration.Builder configBuilder) { + LOGGER.info("CBS client will use plain http protocol."); + return configBuilder + .protocol("http") + .port(Integer.valueOf(getEnv(ENV_CBS_PORT))) + .build(); + } + + static CbsClientConfiguration createSslHttpConfig(ImmutableCbsClientConfiguration.Builder configBuilder, + String pathToCaCert) { + LOGGER.info("CBS client will use http over TLS."); + return configBuilder + .trustStoreKeys(crateSecurityKeysFromEnvironment(createPathToJksFile(pathToCaCert))) + .port(PORT_FOR_CBS_OVER_TLS) + .protocol("https") .build(); } + + static TrustStoreKeys crateSecurityKeysFromEnvironment(String pathToCerts) { + LOGGER.info("Path to cert files: {}", pathToCerts + "/"); + validateIfFilesExist(pathToCerts); + return ImmutableTrustStoreKeys.builder() + .trustStore(SecurityKeysStore.fromPath(Paths.get(pathToCerts + "/" + TRUST_JKS))) + .trustStorePassword(Passwords.fromPath(Paths.get(pathToCerts + "/" + TRUST_PASS))) + .build(); + } + + static String createPathToJksFile(String pathToCaCertPemFile) { + return pathToCaCertPemFile.substring(0, pathToCaCertPemFile.lastIndexOf("/")); + } + + static String getEnv(String envName) { + String envValue = System.getenv(envName); + validateEnv(envName, envValue); + return envValue; + } + + static void validateEnv(String envName, String envValue) { + if (envValue == null || "".equals(envValue)) { + throw new CbsClientConfigurationException("Cannot read " + envName + " from environment."); + } + } + + static void validateIfFilesExist(String pathToFile) { + boolean areFilesExist = Files.exists(Paths.get(pathToFile + "/" + TRUST_JKS)) && + Files.exists(Paths.get(pathToFile + "/" + TRUST_PASS)); + + if (!areFilesExist) { + throw new CbsClientConfigurationException("Required files do not exist in " + pathToFile + " directory."); + } + } } |