From 616b0760dca131ec703d667d27c256d109944b2b Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Thu, 1 Jul 2021 07:50:45 +0100 Subject: Add Junits for kubernetes participant module Overall coverage for the module: 85% Issue-ID: POLICY-3241 Signed-off-by: zrrmmua Change-Id: I00c7866ae598b9768d1616468a4c9bfe4cc76166 --- .../participant-impl-kubernetes/pom.xml | 10 + .../participant/kubernetes/Application.java | 3 + .../kubernetes/configurations/BeanFactory.java | 71 ------- .../configurations/ParticipantConfig.java | 71 +++++++ .../kubernetes/controller/ChartController.java | 3 +- .../handler/ControlLoopElementHandler.java | 3 + .../participant/kubernetes/helm/HelmClient.java | 62 ++++-- .../participant/kubernetes/models/ChartList.java | 4 +- .../parameters/ParticipantK8sParameters.java | 2 +- .../kubernetes/service/ChartService.java | 3 +- .../participant/kubernetes/service/ChartStore.java | 7 +- .../handler/ControlLoopElementHandlerTest.java | 130 ++++++++++++ .../helm/HelmClientTest.java | 122 +++++++++++ .../parameters/CommonTestData.java | 152 ++++++++++++++ .../parameters/ParticipantK8sParametersTest.java | 88 ++++++++ .../rest/ChartControllerTest.java | 230 +++++++++++++++++++++ .../service/ChartServiceTest.java | 147 +++++++++++++ .../service/ChartStoreTest.java | 170 +++++++++++++++ .../utils/TestUtils.java | 43 ++++ .../src/test/resources/ChartList.json | 15 ++ .../src/test/resources/KubernetesHelm.yaml | 154 -------------- .../src/test/resources/application_test.properties | 26 +++ .../resources/servicetemplates/KubernetesHelm.yaml | 154 ++++++++++++++ 23 files changed, 1414 insertions(+), 256 deletions(-) delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/handler/ControlLoopElementHandlerTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/helm/HelmClientTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/CommonTestData.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/ParticipantK8sParametersTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/rest/ChartControllerTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartServiceTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartStoreTest.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/utils/TestUtils.java create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json delete mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties create mode 100644 participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml (limited to 'participant/participant-impl/participant-impl-kubernetes') diff --git a/participant/participant-impl/participant-impl-kubernetes/pom.xml b/participant/participant-impl/participant-impl-kubernetes/pom.xml index 15e8e90ec..ebaa7a198 100644 --- a/participant/participant-impl/participant-impl-kubernetes/pom.xml +++ b/participant/participant-impl/participant-impl-kubernetes/pom.xml @@ -32,6 +32,16 @@ ${project.artifactId} Kubernetes participant, that allows k8s pods to partake in control loops + + + + org.mockito + mockito-inline + 3.8.0 + test + + + diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java index 37ecf4e6f..5d9d203fe 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java @@ -23,12 +23,15 @@ package org.onap.policy.clamp.controlloop.participant.kubernetes; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; /** * Starter. * */ @SpringBootApplication +@ComponentScan({"org.onap.policy.clamp.controlloop.participant.kubernetes", + "org.onap.policy.clamp.controlloop.participant.intermediary"}) @ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.kubernetes.parameters") public class Application { /** diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java deleted file mode 100644 index 3199d0cd9..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * Copyright (C) 2021 Nordix Foundation. 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.policy.clamp.controlloop.participant.kubernetes.configurations; - -import org.apache.catalina.connector.Connector; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.boot.web.servlet.server.ServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.multipart.MultipartResolver; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; - -/** - * Bean Factory class for helm client. - */ -@Configuration -public class BeanFactory { - - @Value("${server.http-port}") - private int httpPort = 0; - - /** - * Method to create servlet container bean. - * @return webserver factory - */ - @Bean - public ServletWebServerFactory servletContainer() { - var tomcat = new TomcatServletWebServerFactory(); - if (httpPort > 0) { - tomcat.addAdditionalTomcatConnectors(getHttpConnector(httpPort)); - } - return tomcat; - } - - private static Connector getHttpConnector(int httpPort) { - var connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); - connector.setScheme("http"); - connector.setPort(httpPort); - connector.setSecure(false); - return connector; - } - - /** - * Method to create multipartResolver bean. - * @return MultipartResolver - */ - @Bean(name = "multipartResolver") - public MultipartResolver multipartResolver() { - var multipartResolver = new CommonsMultipartResolver(); - multipartResolver.setMaxUploadSize(100000); - return multipartResolver; - } - -} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java new file mode 100644 index 000000000..94789a74f --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantConfig.java @@ -0,0 +1,71 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 Nordix Foundation. 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.policy.clamp.controlloop.participant.kubernetes.configurations; + +import org.apache.catalina.connector.Connector; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +/** + * Bean Factory class for helm client. + */ +@Configuration +public class ParticipantConfig { + + @Value("${server.http-port}") + private int httpPort = 0; + + /** + * Method to create servlet container bean. + * @return webserver factory + */ + @Bean + public ServletWebServerFactory servletContainer() { + var tomcat = new TomcatServletWebServerFactory(); + if (httpPort > 0) { + tomcat.addAdditionalTomcatConnectors(getHttpConnector(httpPort)); + } + return tomcat; + } + + private static Connector getHttpConnector(int httpPort) { + var connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); + connector.setScheme("http"); + connector.setPort(httpPort); + connector.setSecure(false); + return connector; + } + + /** + * Method to create multipartResolver bean. + * @return MultipartResolver + */ + @Bean(name = "multipartResolver") + public MultipartResolver multipartResolver() { + var multipartResolver = new CommonsMultipartResolver(); + multipartResolver.setMaxUploadSize(100000); + return multipartResolver; + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java index 5560e47a8..23605e641 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java @@ -149,13 +149,12 @@ public class ChartController { * @param name name of the chart * @param version version of the chart * @return Status of operation - * @throws ServiceException in case of error. */ @DeleteMapping(path = "/charts/{name}/{version}") @ApiOperation(value = "Delete the chart") @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")}) public ResponseEntity deleteChart(@PathVariable("name") String name, - @PathVariable("version") String version) throws ServiceException { + @PathVariable("version") String version) { ChartInfo chart = chartService.getChart(name, version); if (chart == null) { diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java index 6257c3d19..4f654832d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java @@ -26,6 +26,8 @@ import java.lang.invoke.MethodHandles; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; import lombok.Setter; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; @@ -57,6 +59,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { private ParticipantIntermediaryApi intermediaryApi; // Map of CLElement Id and installed Helm charts + @Getter(AccessLevel.PACKAGE) private final Map chartMap = new HashMap<>(); /** diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java index 343a44617..90d7218da 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java @@ -75,12 +75,33 @@ public class HelmClient { */ public String findChartRepository(ChartInfo chart) throws ServiceException, IOException { updateHelmRepo(); - logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartName()); - String repository = null; + String repository = verifyConfiguredRepo(chart); + if (repository != null) { + return repository; + } + var localHelmChartDir = chartStore.getAppPath(chart.getChartName(), chart.getVersion()).toString(); + logger.info("Chart not found in helm repositories, verifying local repo {} ", localHelmChartDir); + if (verifyLocalHelmRepo(localHelmChartDir + "/" + chart.getChartName())) { + repository = localHelmChartDir; + } - var process = helmRepoVerifyCommand(chart.getChartName()).start(); + return repository; + } - try (var reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + /** + * Verify helm chart in configured repositories. + * @param chart chartInfo + * @return repo name + * @throws IOException incase of error + * @throws ServiceException incase of error + */ + public String verifyConfiguredRepo(ChartInfo chart) throws IOException, ServiceException { + logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartName()); + String repository = null; + var builder = helmRepoVerifyCommand(chart.getChartName()); + String output = executeCommand(builder); + try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output, + StandardCharsets.UTF_8)))) { String line = reader.readLine(); while (line != null) { if (line.contains(chart.getChartName())) { @@ -91,13 +112,6 @@ public class HelmClient { line = reader.readLine(); } } - - var localHelmChartDir = chartStore.getAppPath(chart.getChartName(), chart.getVersion()).toString(); - logger.info("Chart not found in helm repositories, verifying local repo {} ", localHelmChartDir); - if (verifyLocalHelmRepo(localHelmChartDir + "/" + chart.getChartName())) { - repository = localHelmChartDir; - } - return repository; } @@ -111,7 +125,13 @@ public class HelmClient { executeCommand(prepareUnInstallCommand(chart)); } - static String executeCommand(ProcessBuilder processBuilder) throws ServiceException { + /** + * Execute helm cli bash commands . + * @param processBuilder processbuilder + * @return string output + * @throws ServiceException incase of error. + */ + public static String executeCommand(ProcessBuilder processBuilder) throws ServiceException { var commandStr = toString(processBuilder); try { @@ -123,13 +143,15 @@ public class HelmClient { var error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8); throw new ServiceException("Command execution failed: " + commandStr + " " + error); } + var output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); logger.debug("Command <{}> execution, output: {}", commandStr, output); return output; + } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new ServiceException("Failed to execute the Command: " + commandStr + ", the command was interrupted", - ie); + ie); } catch (Exception exc) { throw new ServiceException("Failed to execute the Command: " + commandStr, exc); } @@ -140,12 +162,12 @@ public class HelmClient { // @formatter:off List helmArguments = new ArrayList<>( Arrays.asList( - "helm", - "install", chart.getReleaseName(), chart.getRepository() + "/" + chart.getChartName(), - "--version", chart.getVersion(), - "--namespace", chart.getNamespace() + "helm", + "install", chart.getReleaseName(), chart.getRepository() + "/" + chart.getChartName(), + "--version", chart.getVersion(), + "--namespace", chart.getNamespace() ) - ); + ); // @formatter:on // Verify if values.yaml available for the chart @@ -176,9 +198,7 @@ public class HelmClient { private void updateHelmRepo() throws ServiceException { logger.info("Updating local helm repositories before verifying the chart"); - List helmArguments = Arrays.asList("helm", "repo", "update"); - - executeCommand(new ProcessBuilder().command(helmArguments)); + executeCommand(new ProcessBuilder().command("helm", "repo", "update")); logger.debug("Helm repositories updated successfully"); } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java index c86bff58a..7f46bbde5 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java @@ -18,7 +18,7 @@ package org.onap.policy.clamp.controlloop.participant.kubernetes.models; -import java.util.Collection; +import java.util.List; import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -27,5 +27,5 @@ import lombok.Setter; @Setter @Builder public class ChartList { - private Collection charts; + private List charts; } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java index a5731da74..3b2b3732b 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java @@ -20,13 +20,13 @@ package org.onap.policy.clamp.controlloop.participant.kubernetes.parameters; +import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; -import org.onap.policy.common.parameters.annotations.Valid; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.validation.annotation.Validated; diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java index 29a49a9ff..adb6cf0d1 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java @@ -53,9 +53,8 @@ public class ChartService { * @param name name of the app * @param version version of the app * @return chart - * @throws ServiceException in case of error. */ - public ChartInfo getChart(String name, String version) throws ServiceException { + public ChartInfo getChart(String name, String version) { return chartStore.getChart(name, version); } diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java index dcdff62f5..03b35161d 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java @@ -33,6 +33,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import lombok.AccessLevel; +import lombok.Getter; import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; @@ -52,9 +54,8 @@ public class ChartStore { private final ParticipantK8sParameters participantK8sParameters; - /** - * The chartStore map contains chart name as key & ChartInfo as value. - */ + // ChartStore map contains chart name as key & ChartInfo as value. + @Getter(AccessLevel.PACKAGE) private Map localChartMap = new ConcurrentHashMap<>(); /** diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/handler/ControlLoopElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/handler/ControlLoopElementHandlerTest.java new file mode 100644 index 000000000..f3d27a63c --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/handler/ControlLoopElementHandlerTest.java @@ -0,0 +1,130 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.UUID; +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.Mock; +import org.mockito.Mockito; +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.models.controlloop.concepts.ControlLoopState; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; +import org.onap.policy.clamp.controlloop.participant.kubernetes.utils.TestUtils; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; + + +@ExtendWith(SpringExtension.class) +class ControlLoopElementHandlerTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static final String KEY_NAME = "org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement"; + private static List charts; + private static ToscaServiceTemplate toscaServiceTemplate; + + + @InjectMocks + private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); + + @Mock + private ChartService chartService; + + @Mock + private ParticipantIntermediaryApi participantIntermediaryApi; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + toscaServiceTemplate = TestUtils.testControlLoopRead(); + } + + + @Test + void test_ControlLoopElementStateChange() throws ServiceException { + UUID controlLoopElementId1 = UUID.randomUUID(); + UUID controlLoopElementId2 = UUID.randomUUID(); + + controlLoopElementHandler.getChartMap().put(controlLoopElementId1, charts.get(0)); + controlLoopElementHandler.getChartMap().put(controlLoopElementId2, charts.get(1)); + + doNothing().when(chartService).uninstallChart(charts.get(0)); + + controlLoopElementHandler.controlLoopElementStateChange(controlLoopElementId1, ControlLoopState.PASSIVE, + ControlLoopOrderedState.UNINITIALISED); + + doThrow(new ServiceException("Error uninstalling the chart")).when(chartService) + .uninstallChart(charts.get(0)); + + assertDoesNotThrow(() -> controlLoopElementHandler + .controlLoopElementStateChange(controlLoopElementId1, ControlLoopState.PASSIVE, + ControlLoopOrderedState.UNINITIALISED)); + + assertDoesNotThrow(() -> controlLoopElementHandler + .controlLoopElementStateChange(controlLoopElementId1, ControlLoopState.PASSIVE, + ControlLoopOrderedState.RUNNING)); + + } + + @Test + void test_ControlLoopElementUpdate() throws PfModelException, IOException, ServiceException { + + UUID elementId1 = UUID.randomUUID(); + ControlLoopElement element = new ControlLoopElement(); + element.setId(elementId1); + element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1")); + element.setOrderedState(ControlLoopOrderedState.PASSIVE); + + controlLoopElementHandler.controlLoopElementUpdate(element, toscaServiceTemplate); + + assertThat(controlLoopElementHandler.getChartMap()).hasSize(1).containsKey(elementId1); + + doThrow(new ServiceException("Error installing the chart")).when(chartService) + .installChart(Mockito.any()); + + UUID elementId2 = UUID.randomUUID(); + element.setId(elementId2); + controlLoopElementHandler.controlLoopElementUpdate(element, toscaServiceTemplate); + + assertThat(controlLoopElementHandler.getChartMap().containsKey(elementId2)).isFalse(); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/helm/HelmClientTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/helm/HelmClientTest.java new file mode 100644 index 000000000..5f8b7dc78 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/helm/HelmClientTest.java @@ -0,0 +1,122 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.helm; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mockStatic; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +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.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartStore; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.test.context.junit.jupiter.SpringExtension; + + +@ExtendWith(SpringExtension.class) +class HelmClientTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @InjectMocks + @Spy + private HelmClient helmClient = new HelmClient(); + + @Mock + ChartStore chartStore; + + private static MockedStatic mockedClient; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + //Mock static method for bash command execution + mockedClient = mockStatic(HelmClient.class); + } + + @Test + void test_installChart() throws IOException { + mockedClient.when(() -> HelmClient.executeCommand(any())) + .thenReturn("success"); + doReturn(new File("/target/tmp/override.yaml")).when(chartStore) + .getOverrideFile(any()); + assertDoesNotThrow(() -> helmClient.installChart(charts.get(0))); + } + + @Test + void test_findChartRepository() throws IOException, ServiceException { + mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) + .thenReturn("nginx-stable/nginx-ingress\t0.9.3\t1.11.3" + + " \tNGINX Ingress Controller"); + String configuredRepo = helmClient.findChartRepository(charts.get(1)); + + assertThat(configuredRepo).isEqualTo("nginx-stable"); + + doReturn(Path.of("/target/tmp/dummyChart/1.0")).when(chartStore).getAppPath(charts.get(1).getChartName(), + charts.get(1).getVersion()); + + doReturn(null).when(helmClient).verifyConfiguredRepo(charts.get(1)); + + String localRepoName = helmClient.findChartRepository(charts.get(1)); + assertNotNull(localRepoName); + assertThat(localRepoName).endsWith(charts.get(0).getVersion()); + } + + @Test + void test_uninstallChart() throws ServiceException { + helmClient.uninstallChart(charts.get(0)); + mockedClient.when(() -> HelmClient.executeCommand(any())).thenThrow(new ServiceException("error in execution")); + + assertThatThrownBy(() -> helmClient.uninstallChart(charts.get(0))) + .isInstanceOf(ServiceException.class); + } + + @Test + void test_verifyConfiguredRepoForInvalidChart() throws IOException, ServiceException { + mockedClient.when(() -> HelmClient.executeCommand(Mockito.any())) + .thenReturn(""); + String configuredRepo = helmClient.verifyConfiguredRepo(charts.get(1)); + assertNull(configuredRepo); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/CommonTestData.java new file mode 100644 index 000000000..d8d477d1b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/CommonTestData.java @@ -0,0 +1,152 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.parameters; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +public class CommonTestData { + + public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List TOPIC_PARAMS = Arrays.asList(getTopicParams()); + public static final Coder CODER = new StandardCoder(); + + + /** + * Get ParticipantK8sParameters. + * + * @return ParticipantK8sParameters + */ + public ParticipantK8sParameters getParticipantK8sParameters() { + try { + return CODER.convert(getParticipantK8sParametersMap(PARTICIPANT_GROUP_NAME), + ParticipantK8sParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantK8sParameters from map", e); + } + } + + /** + * Returns a property map for a ParticipantK8sParameters map for test cases. + * + * @param name name of the parameters + * + * @return a property map suitable for constructing an object + */ + public Map getParticipantK8sParametersMap(final String name) { + final Map map = new TreeMap<>(); + + map.put("name", name); + map.put("intermediaryParameters", getIntermediaryParametersMap(false)); + map.put("localChartDirectory", getLocalChartDir()); + map.put("infoFileName", getInfoFileName()); + return map; + } + + + /** + * Returns string value of local chart Directory. + * @return a string value + */ + public String getLocalChartDir() { + return "/var/helm-manager/local-charts"; + } + + /** + * Returns string value of Info file name. + * @return string value + */ + public String getInfoFileName() { + return "CHART-INFO.json"; + } + + + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getIntermediaryParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "Participant parameters"); + map.put("reportingTimeInterval", TIME_INTERVAL); + map.put("description", DESCRIPTION); + map.put("participantId", getParticipantId()); + map.put("participantType", getParticipantId()); + map.put("clampControlLoopTopics", getTopicParametersMap(false)); + } + + return map; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); + participantId.setName("K8sParticipant0"); + participantId.setVersion("1.0.0"); + return participantId; + } + + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map getTopicParametersMap(final boolean isEmpty) { + final Map map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/ParticipantK8sParametersTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/ParticipantK8sParametersTest.java new file mode 100644 index 000000000..177d7bc23 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/parameters/ParticipantK8sParametersTest.java @@ -0,0 +1,88 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.parameters; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import org.junit.jupiter.api.Test; + +class ParticipantK8sParametersTest { + + private CommonTestData commonTestData = new CommonTestData(); + private ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + @Test + void testParticipantPolicyParameters() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNullOrEmpty(); + } + + @Test + void testParticipantK8sParameters_NullTopicSinks() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSinks(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantK8sParameters_NullTopicSources() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().getClampControlLoopTopics().setTopicSources(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testParticipantK8sParameters_BlankLocalChartDirParameter() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setLocalChartDirectory(" "); + Set> violations = validatorFactory.getValidator() + .validate(participantParameters); + assertThat(violations.size()).isEqualTo(1); + } + + @Test + void testParticipantK8sParameters_BlankInfoFileParameter() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setInfoFileName(""); + Set> violations = validatorFactory.getValidator() + .validate(participantParameters); + assertThat(violations.size()).isEqualTo(1); + } + + @Test + void testNoIntermediaryParameters() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.setIntermediaryParameters(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + + @Test + void testNoParticipantId() { + final ParticipantK8sParameters participantParameters = commonTestData.getParticipantK8sParameters(); + participantParameters.getIntermediaryParameters().setParticipantId(null); + assertThat(validatorFactory.getValidator().validate(participantParameters)).isNotEmpty(); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/rest/ChartControllerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/rest/ChartControllerTest.java new file mode 100644 index 000000000..1a1bdae5b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/rest/ChartControllerTest.java @@ -0,0 +1,230 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.rest; + +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.File; +import java.util.List; +import org.json.JSONObject; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.controlloop.participant.kubernetes.controller.ChartController; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.RequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + + +@ExtendWith(SpringExtension.class) +@WebMvcTest(value = ChartController.class) +@EnableConfigurationProperties(value = ParticipantK8sParameters.class) +class ChartControllerTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + private static String DEFAULT_CHART_URL = "/helm/charts"; + private static String INSTALL_CHART_URL = "/helm/install"; + private static String UNINSTALL_CHART_URL = "/helm/uninstall/"; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private ChartService chartService; + + @Autowired + private WebApplicationContext context; + + /** + * Read input chart info json. + * @throws Exception incase of error. + */ + @BeforeAll + static void setupParams() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + /** + * Mock service layer in Controller. + * @throws Exception incase of error. + */ + @BeforeEach + void mockServiceClass() { + when(chartService.getAllCharts()).thenReturn(charts); + when(chartService.getChart(charts.get(0).getChartName(), charts.get(0).getVersion())) + .thenReturn(charts.get(0)); + + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + } + + /** + * Test endpoint for retrieving all charts. + * @throws Exception incase of error. + */ + @Test + void retrieveAllCharts() throws Exception { + RequestBuilder requestBuilder; + requestBuilder = MockMvcRequestBuilders.get(DEFAULT_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.charts.[0].chartName", is("HelloWorld"))); + } + + /** + * Test endpoint for installing a chart. + * @throws Exception incase of error. + */ + @Test + void installChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful installation for void install method + doNothing().when(chartService).installChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) + .content(getInstallationJson(charts.get(0).getChartName(), charts.get(0).getVersion())) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isCreated()); + + //Install Invalid chart, expects HTTP status NOT_FOUND + requestBuilder = MockMvcRequestBuilders.post(INSTALL_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE) + .content(getInstallationJson("invalidName", "invalidVersion")) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + } + + /** + * Test endpoint for uninstalling a chart. + * @throws Exception incase of error. + */ + @Test + void uninstallChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful scenario for void uninstall method + doNothing().when(chartService).uninstallChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + charts.get(0).getChartName() + + "/" + charts.get(0).getVersion()).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); + + //Invalid chart + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" + + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + } + + /** + * Test endpoint for chart onboarding. + * @throws Exception incase of error. + */ + @Test + void onboardChart() throws Exception { + RequestBuilder requestBuilder; + MockMultipartFile chartFile = new MockMultipartFile("chart", "hello.tgz", + MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); + + MockMultipartFile overrideFile = new MockMultipartFile("values", "values.yaml", + MediaType.TEXT_PLAIN_VALUE, "Dummy data".getBytes()); + + //Mocking successful scenario for void uninstall method + when(chartService.saveChart(charts.get(0), chartFile, null)).thenReturn(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.multipart(DEFAULT_CHART_URL) + .file(chartFile).file(overrideFile).param("info", getChartInfoJson()); + + mockMvc.perform(requestBuilder).andExpect(status().isOk()); + } + + /** + * Test endpoint for deleting a chart. + * @throws Exception incase of error. + */ + @Test + void deleteChart() throws Exception { + RequestBuilder requestBuilder; + + //Mocking successful scenario for void uninstall method + doNothing().when(chartService).deleteChart(charts.get(0)); + + requestBuilder = MockMvcRequestBuilders.delete(DEFAULT_CHART_URL + "/" + charts.get(0).getChartName() + + "/" + charts.get(0).getVersion()).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNoContent()); + //Invalid chart + requestBuilder = MockMvcRequestBuilders.delete(UNINSTALL_CHART_URL + "invalidName" + + "/" + "invalidVersion").accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE); + + mockMvc.perform(requestBuilder).andExpect(status().isNotFound()); + + } + + private String getInstallationJson(String name, String version) { + JSONObject jsonObj = new JSONObject(); + jsonObj.put("name", name); + jsonObj.put("version", version); + return jsonObj.toString(); + } + + private String getChartInfoJson() { + JSONObject jsonObj = new JSONObject(); + jsonObj.put("chartName", charts.get(0).getChartName()); + jsonObj.put("version", charts.get(0).getVersion()); + jsonObj.put("namespace", charts.get(0).getNamespace()); + jsonObj.put("repository", charts.get(0).getRepository()); + jsonObj.put("releaseName", charts.get(0).getReleaseName()); + return jsonObj.toString(); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartServiceTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartServiceTest.java new file mode 100644 index 000000000..957a69a08 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartServiceTest.java @@ -0,0 +1,147 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +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.Mock; +import org.mockito.Spy; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.HelmClient; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class ChartServiceTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @InjectMocks + @Spy + private ChartService chartService = new ChartService(); + + @Mock + private ChartStore chartStore; + + @Mock + private HelmClient helmClient; + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + @Test + void test_getAllCharts() { + assertThat(chartService.getAllCharts()).isEmpty(); + + doReturn(charts).when(chartStore).getAllCharts(); + Collection result = chartService.getAllCharts(); + assertNotNull(result); + assertThat(result).containsAll(charts); + } + + @Test + void test_getChart() { + assertNull(chartService.getChart("dummyName", "dummyversion")); + + doReturn(charts.get(0)).when(chartStore).getChart(any(), any()); + ChartInfo chart = chartService.getChart(charts.get(0).getChartName(), + charts.get(0).getVersion()); + assertNotNull(chart); + assertThat(chart.getNamespace()).isEqualTo(charts.get(0).getNamespace()); + } + + @Test + void test_saveChart() throws IOException, ServiceException { + doThrow(IOException.class).when(chartStore).saveChart(charts.get(0), null, null); + assertThatThrownBy(() -> chartService.saveChart(charts.get(0), null, null)) + .isInstanceOf(IOException.class); + + MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); + + doReturn(charts.get(0)).when(chartStore).saveChart(any(), any(), any()); + + ChartInfo chart = chartService.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + assertNotNull(chart); + assertThat(chart.getChartName()).isEqualTo(charts.get(0).getChartName()); + + } + + @Test + void test_installChart() throws IOException, ServiceException { + assertDoesNotThrow(() -> chartService.installChart(charts.get(0))); + doThrow(ServiceException.class).when(helmClient).installChart(any()); + assertThatThrownBy(() -> chartService.installChart(charts.get(0))).isInstanceOf(ServiceException.class); + + doReturn("dummyRepoName").when(chartService).findChartRepo(any()); + doNothing().when(helmClient).installChart(any()); + chartService.installChart(charts.get(1)); + assertEquals("dummyRepoName", charts.get(1).getRepository()); + + ChartInfo testChart = charts.get(1); + testChart.setRepository(null); + doReturn(null).when(chartService).findChartRepo(any()); + chartService.installChart(charts.get(1)); + } + + @Test + void test_UninstallChart() throws ServiceException { + assertDoesNotThrow(() -> chartService.uninstallChart(charts.get(0))); + doThrow(ServiceException.class).when(helmClient).uninstallChart(any()); + assertThatThrownBy(() -> chartService.uninstallChart(charts.get(0))).isInstanceOf(ServiceException.class); + } + + @Test + void test_findChartRepo() throws IOException, ServiceException { + assertDoesNotThrow(() -> chartService.findChartRepo(charts.get(0))); + doReturn("dummyRepoName").when(helmClient).findChartRepository(any()); + assertEquals("dummyRepoName", chartService.findChartRepo(charts.get(1))); + + doThrow(ServiceException.class).when(helmClient).findChartRepository(any()); + assertThatThrownBy(() -> chartService.findChartRepo(charts.get(0))).isInstanceOf(ServiceException.class); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartStoreTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartStoreTest.java new file mode 100644 index 000000000..2d05a7a0e --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/service/ChartStoreTest.java @@ -0,0 +1,170 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.util.FileSystemUtils; + + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class ChartStoreTest { + + private static final Coder CODER = new StandardCoder(); + private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; + private static List charts; + + @Mock + private ParticipantK8sParameters parameters; + + private ChartStore chartStore; + + + @BeforeAll + static void init() throws CoderException { + charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts(); + } + + //Overriding the local chart dir parameter to a temp folder under target for testing java FILE IO operations. + @BeforeEach + void setup() { + Mockito.doReturn("target/tmp/").when(parameters).getLocalChartDirectory(); + Mockito.doReturn("info.json").when(parameters).getInfoFileName(); + chartStore = new ChartStore(parameters); + } + + //Clean up the 'tmp' dir after each test case. + @AfterEach + void cleanUp() throws IOException { + FileSystemUtils.deleteRecursively(Path.of(parameters.getLocalChartDirectory())); + chartStore.getLocalChartMap().clear(); + } + + @Test + void test_getHelmChartFile() { + File file = chartStore.getHelmChartFile(charts.get(0)); + assertNotNull(file); + assertThat(file.getPath()).endsWith(charts.get(0).getChartName()); + } + + @Test + void test_getOverrideFile() { + File file = chartStore.getOverrideFile(charts.get(0)); + assertNotNull(file); + assertThat(file.getPath()).endsWith("values.yaml"); + } + + @Test + void test_saveChart() throws IOException, ServiceException { + MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes()); + ChartInfo testChart = charts.get(0); + testChart.setChartName("testChart"); + ChartInfo result = chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + + assertThat(result.getChartName()).isEqualTo("testChart"); + assertThat(chartStore.getLocalChartMap()).hasSize(1); + + assertThatThrownBy(() -> chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile)) + .isInstanceOf(ServiceException.class); + } + + + @Test + void test_getChart() { + assertNull(chartStore.getChart(charts.get(0).getChartName(), charts.get(0).getVersion())); + chartStore.getLocalChartMap().put(charts.get(0).getChartName() + "_" + charts.get(0).getVersion(), + charts.get(0)); + ChartInfo chart = chartStore.getChart(charts.get(0).getChartName(), charts.get(0).getVersion()); + assertThat(chart.getChartName()).isEqualTo(charts.get(0).getChartName()); + } + + @Test + void test_getAllChart() { + // When the chart store is empty before adding any charts + assertThat(chartStore.getAllCharts()).isEmpty(); + + for (ChartInfo chart : charts) { + chartStore.getLocalChartMap().put(chart.getChartName() + "_" + chart.getVersion(), chart); + } + List retrievedChartList = chartStore.getAllCharts(); + assertThat(retrievedChartList).isNotEmpty(); + assertThat(retrievedChartList.size()).isEqualTo(charts.size()); + } + + @Test + void test_deleteChart() { + chartStore.getLocalChartMap().put(charts.get(0).getChartName() + "_" + charts.get(0).getVersion(), + charts.get(0)); + assertThat(chartStore.getLocalChartMap()).hasSize(1); + chartStore.deleteChart(charts.get(0)); + assertThat(chartStore.getLocalChartMap()).isEmpty(); + } + + @Test + void test_getAppPath() { + Path path = chartStore.getAppPath(charts.get(0).getChartName(), charts.get(0).getVersion()); + assertNotNull(path); + assertThat(path.toString()).endsWith(charts.get(0).getVersion()); + assertThat(path.toString()).startsWith("target"); + } + + @Test + void test_chartSoreInstantiationWithExistingChartFiles() throws IOException, ServiceException { + MockMultipartFile mockChartFile = new MockMultipartFile("HelmChartFile", "dummyData".getBytes()); + MockMultipartFile mockOverrideFile = new MockMultipartFile("overrideFile.yaml", "dummyData".getBytes()); + ChartInfo testChart = charts.get(0); + testChart.setChartName("dummyChart"); + + //Creating a dummy chart in local dir. + chartStore.saveChart(charts.get(0), mockChartFile, mockOverrideFile); + + //Instantiating a new chartStore object with pre available chart in local. + ChartStore chartStore2 = new ChartStore(parameters); + assertThat(chartStore2.getLocalChartMap()).hasSize(1).containsKey("dummyChart_" + charts.get(0).getVersion()); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/utils/TestUtils.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/utils/TestUtils.java new file mode 100644 index 000000000..8585e9d11 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/utils/TestUtils.java @@ -0,0 +1,43 @@ +/*- + * ============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 org.onap.policy.clamp.controlloop.participant.kubernetes.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; + +public class TestUtils { + + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final String TOSCA_TEMPLATE_YAML = "src/test/resources/servicetemplates/KubernetesHelm.yaml"; + + + public static ToscaServiceTemplate testControlLoopRead() { + return testControlLoopYamlSerialization(TOSCA_TEMPLATE_YAML); + } + + + private static ToscaServiceTemplate testControlLoopYamlSerialization(String controlLoopFilePath) { + String controlLoopString = ResourceUtils.getResourceAsString(controlLoopFilePath); + ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(controlLoopString, ToscaServiceTemplate.class); + return serviceTemplate; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json new file mode 100644 index 000000000..4e355c38e --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json @@ -0,0 +1,15 @@ +{ + "charts" : [ + { + "chartName" : "HelloWorld", + "version" : "1.0", + "namespace" : "onap", + "repository" : "chartMuseum" + }, + { + "chartName" : "nginx", + "version" : "1.1", + "namespace" : "onap" + } + ] +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml deleted file mode 100644 index 3212b5ad2..000000000 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml +++ /dev/null @@ -1,154 +0,0 @@ -# ============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 -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.K8SMicroserviceControlLoopElement: - version: 1.0.1 - derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement - properties: - chart: - type: string - required: true - configs: - type: list - required: false - requirements: - type: string - requred: false - templates: - type: list - required: false - entry_schema: - values: - type: string - requred: true -topology_template: - node_templates: - org.onap.k8s.controlloop.K8SControlLoopParticipant: - version: 2.3.4 - type: org.onap.policy.clamp.controlloop.Participant - type_version: 1.0.1 - description: Participant for K8S - properties: - provider: ONAP - - org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement: - # Chart from any chart repository configured on helm client. - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the K8S microservice for Hello World - properties: - provider: ONAP - participant_id: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant - version: 2.3.4 - chart: - release_name: helloworld - chart_name: hello - version: 0.1.0 - repository: chartMuseum - namespace: onap - - org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement: - # Chart from local file system - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the K8S microservice for PMSH - properties: - provider: ONAP - participant_id: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant - version: 2.3.4 - chart: - release_name: pmshmicroservice - chart_name: test - version: 1.0.1 - namespace: onap - - org.onap.domain.database.Local_K8SMicroserviceControlLoopElement: - # Chart installation without passing repository name - version: 1.2.3 - type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement - type_version: 1.0.0 - description: Control loop element for the K8S microservice for local chart - properties: - provider: ONAP - participant_id: - name: org.onap.k8s.controlloop.K8SControlLoopParticipant - version: 2.3.4 - chart: - release_name: nginxms - chart_name: nginx-ingress - version: 0.9.1 - namespace: onap - - 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 Hello World - properties: - provider: ONAP - elements: - - name: org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement - version: 1.2.3 - - name: org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement - version: 1.2.3 - - name: org.onap.domain.database.Local_K8SMicroserviceControlLoopElement - version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties new file mode 100644 index 000000000..188623af0 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/application_test.properties @@ -0,0 +1,26 @@ +spring.security.user.name=healthcheck +spring.security.user.password=zb!XztG34 + +server.servlet.context-path=/onap/participantsim +server.error.path=/error +server.http-port=8083 + +participant.name=ControlLoopParticipant Kubernetes Test +participant.intermediaryParameters.name=Participant parameters +participant.intermediaryParameters.reportingTimeInterval=120000 +participant.intermediaryParameters.description=Participant Description +participant.intermediaryParameters.participantId.name=K8sParticipant0 +participant.intermediaryParameters.participantId.version=1.0.0 +participant.intermediaryParameters.participantType.name=org.onap.k8s.controlloop.K8SControlLoopParticipant +participant.intermediaryParameters.participantType.version=2.3.4 +participant.intermediaryParameters.clampControlLoopTopics.name=ControlLoop Topics +participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topic=POLICY-CLRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].servers[0]=localhost +participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchTimeout=15000 +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[1].topic=POLICY-NOTIFICATION +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[1].servers[0]=localhost +participant.intermediaryParameters.clampControlLoopTopics.topicSinks[1].topicCommInfrastructure=dmaap diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml new file mode 100644 index 000000000..3212b5ad2 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/servicetemplates/KubernetesHelm.yaml @@ -0,0 +1,154 @@ +# ============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 +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.K8SMicroserviceControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + chart: + type: string + required: true + configs: + type: list + required: false + requirements: + type: string + requred: false + templates: + type: list + required: false + entry_schema: + values: + type: string + requred: true +topology_template: + node_templates: + org.onap.k8s.controlloop.K8SControlLoopParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for K8S + properties: + provider: ONAP + + org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement: + # Chart from any chart repository configured on helm client. + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for Hello World + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: helloworld + chart_name: hello + version: 0.1.0 + repository: chartMuseum + namespace: onap + + org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement: + # Chart from local file system + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for PMSH + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: pmshmicroservice + chart_name: test + version: 1.0.1 + namespace: onap + + org.onap.domain.database.Local_K8SMicroserviceControlLoopElement: + # Chart installation without passing repository name + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for local chart + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: nginxms + chart_name: nginx-ingress + version: 0.9.1 + namespace: onap + + 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 Hello World + properties: + provider: ONAP + elements: + - name: org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement + version: 1.2.3 + - name: org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement + version: 1.2.3 + - name: org.onap.domain.database.Local_K8SMicroserviceControlLoopElement + version: 1.2.3 -- cgit 1.2.3-korg