From 23e25e89619c732a687b44a5487afbb6badf613c Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Tue, 20 Jul 2021 07:57:41 +0100 Subject: Implement http participant in CLAMP Issue-ID: POLICY-3449 Signed-off-by: zrrmmua Change-Id: Ibfe23a6e98fb760a930b6080dc2291113b3cb4fa --- .../test/java/handler/ClElementHandlerTest.java | 63 +++++++ .../src/test/java/utils/CommonTestData.java | 146 +++++++++++++++ .../src/test/java/utils/ToscaUtils.java | 48 +++++ .../src/test/java/webclient/ClHttpClientTest.java | 85 +++++++++ .../src/test/resources/HttpParticipantConfig.yaml | 208 +++++++++++++++++++++ 5 files changed, 550 insertions(+) create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/utils/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/utils/ToscaUtils.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/java/webclient/ClHttpClientTest.java create mode 100644 participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml (limited to 'participant/participant-impl/participant-impl-http/src/test') diff --git a/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java new file mode 100644 index 000000000..10b8103cb --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package handler; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Spy; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import utils.CommonTestData; +import utils.ToscaUtils; + +@ExtendWith(SpringExtension.class) +class ClElementHandlerTest { + + @InjectMocks + @Spy + private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); + + private CommonTestData commonTestData = new CommonTestData(); + + private static ToscaServiceTemplate serviceTemplate; + + @BeforeAll + static void init() throws CoderException { + serviceTemplate = ToscaUtils.readControlLoopFromTosca(); + } + + @Test + void test_ControlLoopElementUpdate() { + doNothing().when(controlLoopElementHandler).invokeHttpClient(any()); + ControlLoopElement element = commonTestData.getControlLoopElement(); + assertDoesNotThrow(() -> controlLoopElementHandler + .controlLoopElementUpdate(element, serviceTemplate)); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/utils/CommonTestData.java b/participant/participant-impl/participant-impl-http/src/test/java/utils/CommonTestData.java new file mode 100644 index 000000000..84957edfa --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/utils/CommonTestData.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package utils; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; +import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigurationEntity; +import org.onap.policy.clamp.controlloop.participant.http.main.models.RestParams; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class CommonTestData { + + private static final Coder CODER = new StandardCoder(); + private static final String TEST_KEY_NAME = "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement"; + + + /** + * Get a controlLoop Element. + * @return controlLoopElement object + */ + public ControlLoopElement getControlLoopElement() { + ControlLoopElement element = new ControlLoopElement(); + element.setId(UUID.randomUUID()); + element.setDefinition(new ToscaConceptIdentifier(TEST_KEY_NAME, "1.0.1")); + element.setOrderedState(ControlLoopOrderedState.PASSIVE); + return element; + } + + /** + * Get query params. + * @return Map of query params + */ + public Map getQueryParams() { + return Map.of("name", "dummy", "version", "1.0"); + } + + /** + * Get path params. + * @return Map of path params + */ + public Map getPathParams() { + return Map.of("id", "123", "name", "dummy"); + } + + /** + * Rest params with GET request. + * @return RestParams obj + */ + public RestParams restParamsWithGet() { + return new RestParams( + new ToscaConceptIdentifier("getRequest", "1.0"), + "GET", + "get", + 200, + null, + getQueryParams(), + null + ); + } + + /** + * Rest params with POST request. + * @return RestParams obj + */ + public RestParams restParamsWithPost() { + return new RestParams( + new ToscaConceptIdentifier("postRequest", "1.0"), + "POST", + "post", + 200, + null, + getQueryParams(), + "Test body" + ); + } + + /** + * Rest params with POST request. + * @return RestParams obj + */ + public RestParams restParamsWithInvalidPost() { + return new RestParams( + new ToscaConceptIdentifier("postRequest", "1.0"), + "POST", + "post/{id}/{name}", + 200, + getPathParams(), + getQueryParams(), + "Test body" + ); + } + + /** + * Get invalid configuration entity. + * @return ConfigurationEntity obj + */ + public ConfigurationEntity getInvalidConfigurationEntity() { + return new ConfigurationEntity( + new ToscaConceptIdentifier("config1", "1.0.1"), + List.of(restParamsWithGet(), restParamsWithInvalidPost()) + ); + } + + /** + * Get configuration entity. + * @return ConfigurationEntity obj + */ + public ConfigurationEntity getConfigurationEntity() { + return new ConfigurationEntity( + new ToscaConceptIdentifier("config1", "1.0.1"), + List.of(restParamsWithGet(), restParamsWithPost()) + ); + } + + /** + * Get headers for config request. + * @return Map of headers + */ + public Map getHeaders() { + return Map.of("Content-Type", "application/json", "Accept", "application/json"); + } + +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/utils/ToscaUtils.java b/participant/participant-impl/participant-impl-http/src/test/java/utils/ToscaUtils.java new file mode 100644 index 000000000..cf71248c3 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/utils/ToscaUtils.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package utils; + +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +/** + * Util class for Test scope. + */ +public class ToscaUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/HttpParticipantConfig.yaml"; + + + /** + * Read a service template yaml. + * @return ToscaServiceTemplate + */ + public static ToscaServiceTemplate readControlLoopFromTosca() { + return serializeControlLoopYaml(TOSCA_TEMPLATE_YAML); + } + + private static ToscaServiceTemplate serializeControlLoopYaml(String controlLoopFilePath) { + String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); + return yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/java/webclient/ClHttpClientTest.java b/participant/participant-impl/participant-impl-http/src/test/java/webclient/ClHttpClientTest.java new file mode 100644 index 000000000..411974a04 --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/java/webclient/ClHttpClientTest.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package webclient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; +import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigurationEntity; +import org.onap.policy.clamp.controlloop.participant.http.main.webclient.ClHttpClient; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import utils.CommonTestData; + +@ExtendWith(SpringExtension.class) +class ClHttpClientTest { + + private CommonTestData commonTestData = new CommonTestData(); + + private String testBaseUrl = "https://httpbin.org"; + + private Map> responseMap = new HashMap<>(); + + + @Test + void test_validRequest() { + //Add valid rest requests POST, GET + ConfigurationEntity configurationEntity = commonTestData.getConfigurationEntity(); + + Map headers = commonTestData.getHeaders(); + ConfigRequest configRequest = new ConfigRequest(testBaseUrl, headers, + List.of(configurationEntity), 10); + + ClHttpClient client = new ClHttpClient(configRequest, responseMap); + assertDoesNotThrow(client::run); + assertThat(responseMap).hasSize(2).containsKey(commonTestData + .restParamsWithGet().getRestRequestId()); + + Pair restResponseMap = responseMap.get(commonTestData + .restParamsWithGet().getRestRequestId()); + assertThat(restResponseMap.getKey()).isEqualTo(200); + } + + @Test + void test_invalidRequest() { + //Add rest requests Invalid POST, Valid GET + ConfigurationEntity configurationEntity = commonTestData.getInvalidConfigurationEntity(); + + Map headers = commonTestData.getHeaders(); + ConfigRequest configRequest = new ConfigRequest(testBaseUrl, headers, + List.of(configurationEntity), 10); + + ClHttpClient client = new ClHttpClient(configRequest, responseMap); + assertDoesNotThrow(client::run); + assertThat(responseMap).hasSize(2).containsKey(commonTestData + .restParamsWithGet().getRestRequestId()); + Pair response = responseMap + .get(commonTestData.restParamsWithInvalidPost().getRestRequestId()); + assertThat(response.getKey()).isEqualTo(404); + } +} diff --git a/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml b/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml new file mode 100644 index 000000000..43d0c269c --- /dev/null +++ b/participant/participant-impl/participant-impl-http/src/test/resources/HttpParticipantConfig.yaml @@ -0,0 +1,208 @@ +# ============LICENSE_START======================================================= +# Copyright (C) 2021 Nordix Foundation. +# ================================================================================ +# 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. +# +# SPDX-License-Identifier: Apache-2.0 +# ============LICENSE_END========================================================= +tosca_definitions_version: tosca_simple_yaml_1_3 +data_types: + onap.datatypes.ToscaConceptIdentifier: + derived_from: tosca.datatypes.Root + properties: + name: + type: string + required: true + version: + type: string + required: true + + org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest: + version: 1.0.0 + derived_from: tosca.datatypes.Root + properties: + restRequestId: + type: onap.datatypes.ToscaConceptIdentifier + typeVersion: 1.0.0 + required: true + description: The name and version of a REST request to be sent to a REST endpoint + httpMethod: + type: string + required: true + constraints: + - valid_values: [POST, PUT, GET, DELETE] + description: The REST method to use + path: + type: string + required: true + description: The path of the REST request relative to the base URL + body: + type: string + required: false + description: The body of the REST request for PUT and POST requests + expectedResponse: + type: integer + required: true + constraints: + - in_range: [100, 599] + description: THe expected HTTP status code for the REST request + org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity: + version: 1.0.0 + derived_from: tosca.datatypes.Root + properties: + configurationEntityId: + type: onap.datatypes.ToscaConceptIdentifier + typeVersion: 1.0.0 + required: true + description: The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element + restSequence: + type: list + entry_schema: + type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest + typeVersion: 1.0.0 + description: A sequence of REST commands to send to the REST endpoint + + +node_types: + org.onap.policy.clamp.controlloop.Participant: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + org.onap.policy.clamp.controlloop.ControlLoopElement: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + participant_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.controlloop.ControlLoop: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + elements: + type: list + required: true + entry_schema: + type: onap.datatypes.ToscaConceptIdentifier + org.onap.policy.clamp.controlloop.HttpControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + baseUrl: + type: string + required: true + description: The base URL to be prepended to each path, identifies the host for the REST endpoints. + httpHeaders: + type: map + required: false + entry_schema: + type: string + description: HTTP headers to send on REST requests + configurationEntities: + type: map + required: true + entry_schema: + type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity + typeVersion: 1.0.0 + description: The connfiguration entities the Control Loop Element is managing and their associated REST requests +topology_template: + node_templates: + org.onap.k8s.controlloop.HttpControlLoopParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for Http requests + properties: + provider: ONAP + + org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement: + # Http config for PMSH. + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.HttpControlLoopElement + type_version: 1.0.1 + description: Control loop element for the http requests of PMSH microservice + properties: + provider: ONAP + participant_id: + name: org.onap.controlloop.HttpControlLoopParticipant + version: 2.3.4 + uninitializedToPassiveTimeout: 180 + baseUrl: https://httpbin.org + httpHeaders: + Content-Type: application/json + configurationEntities: + - configurationEntityId: + name: entity1 + version: 1.0.1 + restSequence: + - restRequestId: + name: request1 + version: 1.0.1 + httpMethod: POST + path: post + body: '{"name":"ob1","port_type"}' + expectedResponse: 200 + + - restRequestId: + name: request1 + version: 1.0.1 + httpMethod: GET + path: get + expectedResponse: 200 + + # Rest path with path params and query params + - configurationEntityId: + name: entity2 + version: 1.0.1 + restSequence: + - restRequestId: + name: request1 + version: 1.0.1 + httpMethod: POST + path: post/{id}/{name} + pathParams: + id: 123 + name: dummyName + body: this is a test body + expectedResponse: 200 + + - restRequestId: + name: request1 + version: 1.0.1 + httpMethod: GET + path: get + queryParams: + id: 123 + name: dummyName + expectedResponse: 200 + + + org.onap.domain.sample.GenericK8s_ControlLoopDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.0 + description: Control loop for HTTP request + properties: + provider: ONAP + elements: + - name: org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement + version: 1.2.3 -- cgit 1.2.3-korg