From 4b1062c01ea444f429ca7c51153c2cea5692ed80 Mon Sep 17 00:00:00 2001 From: Piotr Jaszczyk Date: Tue, 26 Feb 2019 15:08:37 +0100 Subject: CBS lookup algorithm Implement CBS lookup algorithm as docummented on https://wiki.onap.org/display/DW/MicroServices+Onboarding+in+ONAP#MicroServicesOnboardinginONAP-CodesnippettofetchconfigurationfromConfigbindingservice Change-Id: Ib465c5fd44b853ba46e152259744dbdd775872a0 Issue-ID: DCAEGEN2-1233 Signed-off-by: Piotr Jaszczyk --- .../rest/services/cbs/client/api/CbsClient.java | 22 ++++- .../services/cbs/client/api/CbsClientFactory.java | 13 ++- .../services/cbs/client/api/EnvProperties.java | 79 +++++++++++++++ .../client/http/configuration/CloudHttpClient.java | 109 --------------------- .../client/http/configuration/EnvProperties.java | 48 --------- .../services/cbs/client/impl/CbsClientImpl.java | 12 ++- .../rest/services/cbs/client/impl/CbsLookup.java | 72 ++++++++++++++ .../cbs/client/impl/adapters/CloudHttpClient.java | 108 ++++++++++++++++++++ .../client/providers/CloudConfigurationClient.java | 4 +- .../providers/CloudConfigurationProvider.java | 2 +- .../ReactiveCloudConfigurationProvider.java | 4 +- .../services/cbs/client/api/EnvPropertiesTest.java | 37 +++++++ .../services/cbs/client/impl/CbsLookupTest.java | 94 ++++++++++++++++++ .../ReactiveCloudConfigurationProviderTest.java | 6 +- .../src/test/resources/consul_cbs_service.json | 23 +++++ 15 files changed, 461 insertions(+), 172 deletions(-) create mode 100644 rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvProperties.java delete mode 100644 rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/CloudHttpClient.java delete mode 100644 rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/EnvProperties.java create mode 100644 rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookup.java create mode 100644 rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/adapters/CloudHttpClient.java create mode 100644 rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvPropertiesTest.java create mode 100644 rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookupTest.java create mode 100644 rest-services/cbs-client/src/test/resources/consul_cbs_service.json (limited to 'rest-services') diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClient.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClient.java index 0f50fca8..73789268 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClient.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/CbsClient.java @@ -19,7 +19,10 @@ */ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.time.Duration; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.jetbrains.annotations.NotNull; @@ -37,9 +40,24 @@ public interface CbsClient { *

* Returns a {@link Mono} that publishes new configuration after CBS client retrieves one. * - * @param serviceComponentName url key under which CBS client should look for configuration * @return reactive stream of configuration * @since 1.1.2 */ - @NotNull Mono get(String serviceComponentName); + @NotNull Mono get(); + + + /** + * Poll for configuration. + * + * Will call {@link #get()} after {@code initialDelay} every {@code period}. Resulting entries may or may not be + * changed, ie. items in the stream might be the same until change is made in CBS. + * + * @param initialDelay delay after first request attempt + * @param period frequency of update checks + * @return stream of configuration states + */ + default Flux get(Duration initialDelay, Duration period) { + return Flux.interval(initialDelay, period) + .flatMap(i -> get()); + } } 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 f81cd6b5..c1b14343 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 @@ -21,6 +21,8 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api; import org.jetbrains.annotations.NotNull; 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.impl.adapters.CloudHttpClient; import reactor.core.publisher.Mono; /** @@ -40,11 +42,16 @@ public class CbsClientFactory { * client configured with found address. Created client will be published in returned Mono instance. *

* + * @param env required environment properties * @return non-null {@link Mono} of {@link CbsClient} instance * @since 1.1.2 */ - @NotNull - public static Mono createCbsClient() { - return Mono.just(new CbsClientImpl()); + public static @NotNull Mono createCbsClient(EnvProperties env) { + return Mono.defer(() -> { + final CloudHttpClient httpClient = new CloudHttpClient(); + final CbsLookup lookup = new CbsLookup(httpClient); + return lookup.lookup(env) + .map(addr -> new CbsClientImpl(httpClient, env.appName())); + }); } } diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvProperties.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvProperties.java new file mode 100644 index 00000000..e794fe6d --- /dev/null +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvProperties.java @@ -0,0 +1,79 @@ +/* + * ============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; + +import org.immutables.value.Value; + +/** + * Immutable object which helps with construction of cloudRequestObject for specified Client. For usage take a look in + * CloudConfigurationClient.class + * + * @author Przemysław Wąsala on 11/16/18 + * @version 1.0.0 can be passed to ReactiveCloudConfigurationProvider, can be constructed out of + * org.onap.dcaegen2.services.sdk library. + * @since 1.0.0 + */ +@Value.Immutable(prehash = true) +public interface EnvProperties { + + /** + * Name of environment variable containing Consul host name. + */ + String ENV_CONSUL_HOST = "CONSUL_HOST"; + + /** + * Name of environment variable containing Config Binding Service service name as registered in Consul + * services API. + */ + String ENV_CBS_NAME = "CONFIG_BINDING_SERVICE"; + + /** + * Name of environment variable containing current application name. + */ + String ENV_APP_NAME = "HOSTNAME"; + + @Value.Parameter + String consulHost(); + + @Value.Parameter + Integer consulPort(); + + @Value.Parameter + String cbsName(); + + @Value.Parameter + String appName(); + + /** + * Creates EnvProperties from system environment variables. + * + * @return an instance of EnvProperties + * @throws NullPointerException when at least one of required parameters is missing + */ + static EnvProperties fromEnvironment() { + return ImmutableEnvProperties.builder() + .consulHost(System.getenv(ENV_CONSUL_HOST)) + .consulPort(8050) + .cbsName(System.getenv(ENV_CBS_NAME)) + .appName(System.getenv(ENV_APP_NAME)) + .build(); + } +} diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/CloudHttpClient.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/CloudHttpClient.java deleted file mode 100644 index d97edb3b..00000000 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/CloudHttpClient.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ============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.cbs.client.http.configuration; - -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; -import java.util.function.BiConsumer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Mono; -import reactor.netty.Connection; -import reactor.netty.http.client.HttpClient; -import reactor.netty.http.client.HttpClientRequest; -import reactor.netty.http.client.HttpClientResponse; - - -/** - * @author Przemysław Wąsala on 11/15/18 - */ - -public class CloudHttpClient { - - private static final Logger LOGGER = LoggerFactory.getLogger(CloudHttpClient.class); - - private final Gson gson; - private final HttpClient httpClient; - - - public CloudHttpClient() { - this(HttpClient.create().doOnRequest(logRequest()).doOnResponse(logResponse())); - } - - - CloudHttpClient(HttpClient httpClient) { - this.gson = new Gson(); - this.httpClient = httpClient; - } - - - public Mono callHttpGet(String url, Class genericClassDeclaration) { - return httpClient - .baseUrl(url) - .doOnResponseError(doOnError()) - .get() - .responseSingle( - (httpClientResponse, content) -> getJsonFromRequest(content.toString(), genericClassDeclaration)); - } - - private BiConsumer doOnError() { - return (httpClientResponse, throwable) -> { - Mono.error(getException(httpClientResponse)); - }; - } - - - private RuntimeException getException(HttpClientResponse response) { - return new RuntimeException(String.format("Request for cloud config failed: HTTP %d", - response.status().code())); - } - - private Mono getJsonFromRequest(String body, Class genericClassDeclaration) { - try { - return Mono.just(parseJson(body, genericClassDeclaration)); - } catch (JsonSyntaxException | IllegalStateException e) { - return Mono.error(e); - } - } - - private T parseJson(String body, Class genericClassDeclaration) { - return gson.fromJson(body, genericClassDeclaration); - } - - - private static BiConsumer logRequest() { - return (httpClientRequest, connection) -> { - LOGGER.debug("Request: {} {}", httpClientRequest.method(), httpClientRequest.uri()); - httpClientRequest.requestHeaders().forEach(stringStringEntry -> { - LOGGER.trace("{}={}", stringStringEntry.getKey(), stringStringEntry.getValue()); - }); - - }; - } - - private static BiConsumer logResponse() { - return (httpClientresponse, connection) -> { - LOGGER.debug("Response status: {}", httpClientresponse.status()); - }; - } - - -} diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/EnvProperties.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/EnvProperties.java deleted file mode 100644 index 2438a2b8..00000000 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/http/configuration/EnvProperties.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ============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.cbs.client.http.configuration; - -import org.immutables.value.Value; - -/** - * Immutable object which helps with construction of cloudRequestObject for specified Client. For usage take a look in - * CloudConfigurationClient.class - * - * @author Przemysław Wąsala on 11/16/18 - * @version 1.0.0 can be passed to ReactiveCloudConfigurationProvider, can be constructed out of - * org.onap.dcaegen2.services.sdk library. - * @since 1.0.0 - */ -@Value.Immutable(prehash = true) -public interface EnvProperties { - - @Value.Parameter - String consulHost(); - - @Value.Parameter - Integer consulPort(); - - @Value.Parameter - String cbsName(); - - @Value.Parameter - String appName(); -} 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 7bd80ed7..1df42c69 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 @@ -22,13 +22,21 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl; import com.google.gson.JsonObject; import org.jetbrains.annotations.NotNull; import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.CbsClient; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.adapters.CloudHttpClient; import reactor.core.publisher.Mono; public class CbsClientImpl implements CbsClient { + private final CloudHttpClient httpClient; + private final String serviceName; + + public CbsClientImpl( + CloudHttpClient httpClient, String serviceName) { + this.httpClient = httpClient; + this.serviceName = serviceName; + } - @NotNull @Override - public Mono get(String serviceComponentName) { + public @NotNull Mono get() { return Mono.empty(); } } diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookup.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookup.java new file mode 100644 index 00000000..ca7058f6 --- /dev/null +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookup.java @@ -0,0 +1,72 @@ +/* + * ============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.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import java.net.InetSocketAddress; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.adapters.CloudHttpClient; +import reactor.core.publisher.Mono; + +/** + * @author Piotr Jaszczyk + * @since February 2019 + */ +public class CbsLookup { + + private static final String CONSUL_JSON_SERVICE_ADDRESS = "ServiceAddress"; + private static final String CONSUL_JSON_SERVICE_PORT = "ServicePort"; + private final CloudHttpClient httpClient; + + public CbsLookup(CloudHttpClient httpClient) { + this.httpClient = httpClient; + } + + public Mono lookup(EnvProperties env) { + return Mono.fromCallable(() -> createConsulUrl(env)) + .flatMap(this::fetchHttpData) + .flatMap(this::firstService) + .map(this::parseServiceEntry); + } + + private String createConsulUrl(EnvProperties env) { + return String.format("http://%s:%s/v1/catalog/service/%s", env.consulHost(), env.consulPort(), env.cbsName()); + } + + private Mono fetchHttpData(String consulUrl) { + return httpClient.callHttpGet(consulUrl, JsonArray.class); + } + + private Mono firstService(JsonArray services) { + return services.size() == 0 + ? Mono.empty() + : Mono.just(services.get(0).getAsJsonObject()); + } + + private InetSocketAddress parseServiceEntry(JsonObject service) { + return InetSocketAddress.createUnresolved( + service.get(CONSUL_JSON_SERVICE_ADDRESS).getAsString(), + service.get(CONSUL_JSON_SERVICE_PORT).getAsInt()); + } + +} + diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/adapters/CloudHttpClient.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/adapters/CloudHttpClient.java new file mode 100644 index 00000000..264a392e --- /dev/null +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/adapters/CloudHttpClient.java @@ -0,0 +1,108 @@ +/* + * ============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.impl.adapters; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import java.util.function.BiConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Mono; +import reactor.netty.Connection; +import reactor.netty.http.client.HttpClient; +import reactor.netty.http.client.HttpClientRequest; +import reactor.netty.http.client.HttpClientResponse; + +/** + * @author Przemysław Wąsala on 11/15/18 + */ + +public class CloudHttpClient { + + private static final Logger LOGGER = LoggerFactory.getLogger(CloudHttpClient.class); + + private final Gson gson; + private final HttpClient httpClient; + + + public CloudHttpClient() { + this(HttpClient.create().doOnRequest(logRequest()).doOnResponse(logResponse())); + } + + + CloudHttpClient(HttpClient httpClient) { + this.gson = new Gson(); + this.httpClient = httpClient; + } + + + public Mono callHttpGet(String url, Class genericClassDeclaration) { + return httpClient + .baseUrl(url) + .doOnResponseError(doOnError()) + .get() + .responseSingle( + (httpClientResponse, content) -> getJsonFromRequest(content.toString(), genericClassDeclaration)); + } + + private BiConsumer doOnError() { + return (httpClientResponse, throwable) -> { + Mono.error(getException(httpClientResponse)); + }; + } + + + private RuntimeException getException(HttpClientResponse response) { + return new RuntimeException(String.format("Request for cloud config failed: HTTP %d", + response.status().code())); + } + + private Mono getJsonFromRequest(String body, Class genericClassDeclaration) { + try { + return Mono.just(parseJson(body, genericClassDeclaration)); + } catch (JsonSyntaxException | IllegalStateException e) { + return Mono.error(e); + } + } + + private T parseJson(String body, Class genericClassDeclaration) { + return gson.fromJson(body, genericClassDeclaration); + } + + + private static BiConsumer logRequest() { + return (httpClientRequest, connection) -> { + LOGGER.debug("Request: {} {}", httpClientRequest.method(), httpClientRequest.uri()); + httpClientRequest.requestHeaders().forEach(stringStringEntry -> { + LOGGER.trace("{}={}", stringStringEntry.getKey(), stringStringEntry.getValue()); + }); + + }; + } + + private static BiConsumer logResponse() { + return (httpClientresponse, connection) -> { + LOGGER.debug("Response status: {}", httpClientresponse.status()); + }; + } + + +} diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java index 594db6d0..8a1abe36 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationClient.java @@ -22,8 +22,8 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.providers; import com.google.gson.JsonObject; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.ImmutableEnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.ImmutableEnvProperties; import reactor.core.publisher.Mono; /** diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationProvider.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationProvider.java index f8486f6f..e1105344 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationProvider.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/CloudConfigurationProvider.java @@ -22,7 +22,7 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.providers; import com.google.gson.JsonObject; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; import reactor.core.publisher.Mono; /** diff --git a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java index 88665e75..5606a2d1 100644 --- a/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java +++ b/rest-services/cbs-client/src/main/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProvider.java @@ -23,8 +23,8 @@ package org.onap.dcaegen2.services.sdk.rest.services.cbs.client.providers; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.CloudHttpClient; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.adapters.CloudHttpClient; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; import org.onap.dcaegen2.services.sdk.rest.services.uri.URI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvPropertiesTest.java b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvPropertiesTest.java new file mode 100644 index 00000000..b48543d2 --- /dev/null +++ b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/api/EnvPropertiesTest.java @@ -0,0 +1,37 @@ +/* + * ============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; + + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import org.junit.jupiter.api.Test; + +/** + * @author Piotr Jaszczyk + * @since February 2019 + */ +class EnvPropertiesTest { + @Test + void fromEnvironmentShouldFailWhenEnvVariablesAreMissing() { + assertThatExceptionOfType(NullPointerException.class).isThrownBy(EnvProperties::fromEnvironment); + } +} \ No newline at end of file diff --git a/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookupTest.java b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookupTest.java new file mode 100644 index 00000000..e7513852 --- /dev/null +++ b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/impl/CbsLookupTest.java @@ -0,0 +1,94 @@ +/* + * ============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.impl; + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import org.junit.jupiter.api.Test; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.ImmutableEnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.adapters.CloudHttpClient; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +/** + * @author Piotr Jaszczyk + * @since February 2019 + */ +class CbsLookupTest { + + private final EnvProperties env = ImmutableEnvProperties.builder() + .cbsName("cbs-service") + .consulHost("consul.local") + .consulPort(8050) + .appName("whatever").build(); + private final CloudHttpClient httpClient = mock(CloudHttpClient.class); + private final CbsLookup cut = new CbsLookup(httpClient); + + @Test + void lookupShouldReturnValidConfiguration() { + // given + givenConsulResponse(parseResource("/consul_cbs_service.json").getAsJsonArray()); + + // when + final InetSocketAddress result = cut.lookup(env).block(); + + // then + assertThat(result.getHostString()).isEqualTo("config-binding-service"); + assertThat(result.getPort()).isEqualTo(10000); + } + + @Test + void lookupShouldReturnEmptyResultWhenServiceArrayIsEmpty() { + // given + givenConsulResponse(new JsonArray()); + + // when + final Mono result = cut.lookup(env); + + // then + StepVerifier.create(result).verifyComplete(); + } + + private JsonElement parseResource(String resource) { + return new JsonParser().parse(new InputStreamReader(CbsLookupTest.class.getResourceAsStream(resource))); + } + + private void givenConsulResponse(JsonArray jsonArray) { + final String url = "http://" + + env.consulHost() + + ":" + + env.consulPort() + + "/v1/catalog/service/" + + env.cbsName(); + given(httpClient.callHttpGet(url, JsonArray.class)) + .willReturn(Mono.just(jsonArray)); + } + +} \ No newline at end of file diff --git a/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProviderTest.java b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProviderTest.java index 5d6ef6bc..4e8782b6 100644 --- a/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProviderTest.java +++ b/rest-services/cbs-client/src/test/java/org/onap/dcaegen2/services/sdk/rest/services/cbs/client/providers/ReactiveCloudConfigurationProviderTest.java @@ -27,9 +27,9 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import org.junit.jupiter.api.Test; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.CloudHttpClient; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.EnvProperties; -import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.http.configuration.ImmutableEnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.ImmutableEnvProperties; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.impl.adapters.CloudHttpClient; +import org.onap.dcaegen2.services.sdk.rest.services.cbs.client.api.EnvProperties; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/rest-services/cbs-client/src/test/resources/consul_cbs_service.json b/rest-services/cbs-client/src/test/resources/consul_cbs_service.json new file mode 100644 index 00000000..49b1df20 --- /dev/null +++ b/rest-services/cbs-client/src/test/resources/consul_cbs_service.json @@ -0,0 +1,23 @@ +[ + { + "Address": "10.42.102.75", + "CreateIndex": 1097, + "Datacenter": "dc1", + "ID": "2a69de1b-4c2d-a958-5058-639acc926fde", + "ModifyIndex": 1097, + "Node": "dcae-bootstrap", + "NodeMeta": { + "consul-network-segment": "" + }, + "ServiceAddress": "config-binding-service", + "ServiceEnableTagOverride": false, + "ServiceID": "dcae-cbs0", + "ServiceName": "config_binding_service", + "ServicePort": 10000, + "ServiceTags": [], + "TaggedAddresses": { + "lan": "10.42.102.75", + "wan": "10.42.102.75" + } + } +] -- cgit 1.2.3-korg