# ============LICENSE_START=======================================================
-# Copyright (C) 2022-2024 Nordix Foundation.
+# Copyright (C) 2022-2024,2026 OpenInfra Foundation Europe. 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.
repository: nexus3.onap.org:10001
name: onap/policy-clamp-acm-element-impl
pullPolicy: IfNotPresent
- tag: "8.0.1"
+ tag: "8.2.2"
nameOverride: "ac-element-impl"
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. 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.
import org.onap.policy.models.base.PfModelException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
private static final Coder CODER = new StandardCoder();
private final ChartService chartService;
+ private final PodStatusValidator podStatusValidator;
- public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, ChartService chartService) {
+ /**
+ * Constructor.
+ *
+ * @param intermediaryApi the ParticipantIntermediaryApi
+ * @param chartService the ChartService
+ * @param podStatusValidator the PodStatusValidator
+ */
+ public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, ChartService chartService,
+ PodStatusValidator podStatusValidator) {
super(intermediaryApi);
this.chartService = chartService;
+ this.podStatusValidator = podStatusValidator;
}
int podStatusCheckInterval, InstanceElementDto instanceElement) throws InterruptedException,
PfModelException {
- var result = new PodStatusValidator(chart, timeout, podStatusCheckInterval);
- result.run();
+ podStatusValidator.run(timeout, podStatusCheckInterval, chart);
LOGGER.info("Pod Status Validator Completed");
intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, elementId,
DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
/*-
* ========================LICENSE_START=================================
- * Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
+ * Copyright (C) 2021-2026 OpenInfra Foundation Europe. All rights reserved.
* ======================================================================
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ======================================================================
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
-import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Client to talk with Helm cli. Supports helm3 + version
*/
@Component
-@NoArgsConstructor
+@RequiredArgsConstructor
public class HelmClient {
- private ChartStore chartStore;
+ private final ChartStore chartStore;
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String PATH_DELIMITER = "/";
private static final String COMMAND_HELM = "/usr/local/bin/helm";
public static final String COMMAND_KUBECTL = "/usr/local/bin/kubectl";
- @Autowired
- public HelmClient(ChartStore chartStore) {
- this.chartStore = chartStore;
- }
-
/**
* Install a chart.
*
return false;
}
-
/**
* Finds helm chart repository for the chart.
*
*/
public String verifyConfiguredRepo(ChartInfo chart) throws ServiceException {
logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartId().getName());
- String repository;
var builder = helmRepoVerifyCommand(chart.getChartId().getName());
- String output = executeCommand(builder);
- repository = verifyOutput(output, chart.getChartId().getName());
- return repository;
+ var output = executeCommand(builder);
+ return verifyOutput(output, chart.getChartId().getName());
}
/**
executeCommand(prepareUnInstallCommand(chart));
}
-
/**
* Execute helm cli bash commands.
*
private boolean checkNamespaceExists(String namespace) throws ServiceException {
logger.info("Check if namespace {} exists on the cluster", namespace);
- String output = executeCommand(prepareVerifyNamespaceCommand(namespace));
+ var output = executeCommand(prepareVerifyNamespaceCommand(namespace));
return !output.isEmpty();
}
try {
logger.debug("Verify the repo already exist in helm repositories");
var helmArguments = List.of(COMMAND_SH, "-c", COMMAND_HELM + " repo list | grep " + repo.getRepoName());
- String response = executeCommand(new ProcessBuilder().command(helmArguments));
+ var response = executeCommand(new ProcessBuilder().command(helmArguments));
if (StringUtils.isEmpty(response)) {
return false;
}
/*-
* ========================LICENSE_START=================================
- * Copyright (C) 2021-2024 Nordix Foundation. All rights reserved.
+ * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. 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.
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
+import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.models.base.PfModelException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
-
+@Component
+@RequiredArgsConstructor
public class PodStatusValidator {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final int statusCheckInterval;
-
- //Timeout for the thread to exit.
- private final int timeout;
-
- private ChartInfo chart;
-
- private HelmClient client = new HelmClient();
-
- /**
- * Constructor for PodStatusValidator.
- *
- * @param chart chartInfo
- * @param timeout timeout for the thread to exit
- * @param statusCheckInterval Interval to check pod status
- */
- public PodStatusValidator(ChartInfo chart, int timeout, int statusCheckInterval) {
- this.chart = chart;
- this.timeout = timeout;
- this.statusCheckInterval = statusCheckInterval;
- }
+ private final HelmClient client;
/**
* Run the execution.
*
* @throws InterruptedException in case of an exception
- * @throws ServiceException in case of an exception
+ * @throws PfModelException in case of an exception
*/
- public void run() throws InterruptedException, PfModelException {
+ public void run(int timeout, int statusCheckInterval, ChartInfo chart)
+ throws InterruptedException, PfModelException {
logger.info("Polling the status of deployed pods for the chart {}", chart.getChartId().getName());
try {
- verifyPodStatus();
+ verifyPodStatus(timeout, statusCheckInterval, chart);
} catch (IOException | ServiceException e) {
throw new PfModelException(Response.Status.BAD_REQUEST, "Error verifying the status of the pod. Exiting");
}
}
- private void verifyPodStatus() throws ServiceException, IOException, InterruptedException, PfModelException {
+ private void verifyPodStatus(int timeout, int statusCheckInterval, ChartInfo chart)
+ throws ServiceException, IOException, InterruptedException, PfModelException {
var isVerified = false;
long endTime = System.currentTimeMillis() + (timeout * 1000L);
while (!isVerified && System.currentTimeMillis() < endTime) {
var output = client.executeCommand(verifyPodStatusCommand(chart));
- var podStatusMap = mapPodStatus(output);
+ var podStatusMap = mapPodStatus(chart, output);
isVerified = !podStatusMap.isEmpty()
&& podStatusMap.values().stream().allMatch("Running"::equals);
if (!isVerified) {
private ProcessBuilder verifyPodStatusCommand(ChartInfo chart) {
String cmd = HelmClient.COMMAND_KUBECTL
- + " get pods --namespace " + chart.getNamespace() + " | grep " + getPodName();
+ + " get pods --namespace " + chart.getNamespace() + " | grep " + getPodName(chart);
return new ProcessBuilder(HelmClient.COMMAND_SH, "-c", cmd);
}
- private String getPodName() {
+ private String getPodName(ChartInfo chart) {
return StringUtils.isNotEmpty(chart.getPodName()) ? chart.getPodName() : chart.getChartId().getName();
}
- private Map<String, String> mapPodStatus(String output) throws IOException {
+ private Map<String, String> mapPodStatus(ChartInfo chart, String output) throws IOException {
Map<String, String> podStatusMap = new HashMap<>();
- var podName = getPodName();
+ var podName = getPodName(chart);
try (var reader = new BufferedReader(new InputStreamReader(IOUtils.toInputStream(output,
StandardCharsets.UTF_8)))) {
var line = reader.readLine();
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2022 Nordix Foundation.
+ * Copyright (C) 2022, 2026 OpenInfra Foundation Europe. 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.
* ============LICENSE_END=========================================================
*/
-package org.onap.policy.clamp.acm.participant.kubernetes.configurations;
+package org.onap.policy.clamp.acm.participant.kubernetes.parameters;
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.List;
import lombok.Data;
-import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-@Component
@ConfigurationProperties(prefix = "helm")
@Data
public class HelmRepositoryConfig {
- private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ private String repos = "[]";
- private List<HelmRepository> repos = new ArrayList<>();
-
- private List<String> protocols = new ArrayList<>();
+ private String protocols = "";
}
/*-
* ========================LICENSE_START=================================
- * Copyright (C) 2021-2022, 2025 OpenInfra Foundation Europe. All rights reserved.
+ * Copyright (C) 2021-2022, 2025-2026 OpenInfra Foundation Europe. 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.
import java.io.IOException;
import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import lombok.NoArgsConstructor;
-import org.onap.policy.clamp.acm.participant.kubernetes.configurations.HelmRepositoryConfig;
+import lombok.RequiredArgsConstructor;
import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository;
+import org.onap.policy.clamp.acm.participant.kubernetes.parameters.HelmRepositoryConfig;
+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.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
-@NoArgsConstructor
+@RequiredArgsConstructor
public class ChartService {
private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private ChartStore chartStore;
+ private final ChartStore chartStore;
- private HelmClient helmClient;
+ private final HelmClient helmClient;
- private HelmRepositoryConfig helmRepositoryConfig;
+ private final HelmRepositoryConfig helmRepositoryConfig;
- /**
- * Instantiates the ChartService with the specified dependencies.
- *
- * @param chartStore the store for managing Helm chart information
- * @param helmClient the client for interacting with Helm
- * @param helmRepositoryConfig the configuration for Helm repositories
- */
- @Autowired
- public ChartService(ChartStore chartStore, HelmClient helmClient, HelmRepositoryConfig helmRepositoryConfig) {
- this.chartStore = chartStore;
- this.helmClient = helmClient;
- this.helmRepositoryConfig = helmRepositoryConfig;
- }
+ private static final Coder coder = new StandardCoder();
/**
* Get all the installed charts.
chartStore.deleteChart(chart);
}
+ private static class Repositories extends ArrayList<HelmRepository> {}
+
/**
* Install a helm chart.
* @param chart name and version.
public boolean installChart(ChartInfo chart) throws ServiceException, IOException {
boolean permittedRepo = false;
if (chart.getRepository() == null) {
- String repoName = findChartRepo(chart);
+ var repoName = findChartRepo(chart);
if (repoName == null) {
logger.error("Chart repository could not be found. Skipping chart Installation "
+ "for the chart {} ", chart.getChartId().getName());
return false;
} else {
- HelmRepository repo = HelmRepository.builder().repoName(repoName).build();
+ var repo = HelmRepository.builder().repoName(repoName).build();
chart.setRepository(repo);
}
} else {
// Add a remote repository if passed via TOSCA
// and check whether the repo is permitted
- for (HelmRepository repo : helmRepositoryConfig.getRepos()) {
+ Repositories repos = null;
+ try {
+ repos = coder.decode(helmRepositoryConfig.getRepos(), Repositories.class);
+ } catch (CoderException e) {
+ throw new ServiceException(e.getMessage());
+ }
+ for (var repo : repos) {
+ var protocols = Arrays.stream(helmRepositoryConfig.getProtocols().split(",")).toList();
if (repo.getAddress().equals(chart.getRepository().getAddress())
- && helmRepositoryConfig.getProtocols()
- .contains(chart.getRepository().getAddress().split(":")[0])) {
+ && protocols.contains(chart.getRepository().getAddress().split(":")[0])) {
configureRepository(chart.getRepository());
permittedRepo = true;
break;
enabled: false
# Update the config here for permitting repositories and protocols
helm:
- repos:
- -
- repoName: kong
- address: https://charts.konghq.com
- -
- repoName: bitnami
- address: https://charts.bitnami.com/bitnami
-
- protocols:
- - http
- - https
+ repos: [{"repoName": "kong", "address": "https://charts.konghq.com"},{"repoName": "bitnami", "address": "https://charts.bitnami.com/bitnami"}]
+ protocols: http,https
tracing:
enabled: ${allowTracing:false}
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2024,2026 OpenInfra Foundation Europe. All rights reserved.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.UUID;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto;
import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
+import org.onap.policy.clamp.acm.participant.kubernetes.helm.PodStatusValidator;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList;
import org.onap.policy.clamp.acm.participant.kubernetes.parameters.CommonTestData;
"org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement";
private final CommonTestData commonTestData = new CommonTestData();
-
-
@BeforeAll
static void init() throws CoderException {
charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
@Test
void test_AutomationCompositionElementStateChange() throws ServiceException, PfModelException {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- doNothing().when(chartService).uninstallChart(charts.get(0));
-
- ObjectMapper objectMapper = new ObjectMapper();
+ var objectMapper = new ObjectMapper();
Map<String, Object> inPropertiesMap = objectMapper.convertValue(charts.get(0), new TypeReference<>() {});
- automationCompositionElementHandler.undeploy(commonTestData.createCompositionElementDto(),
+ acElementHandler.undeploy(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(Map.of("chart", inPropertiesMap)));
doThrow(new ServiceException("Error uninstalling the chart")).when(chartService).uninstallChart(charts.get(0));
- assertDoesNotThrow(() -> automationCompositionElementHandler
- .undeploy(commonTestData.createCompositionElementDto(),
+ assertDoesNotThrow(() -> acElementHandler.undeploy(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(inPropertiesMap)));
}
@Test
void test_AutomationCompositionElementUpdate()
- throws PfModelException, IOException, ServiceException, InterruptedException {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- spy(new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService));
+ throws PfModelException, IOException, ServiceException {
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class),
+ chartService, mock(PodStatusValidator.class));
- doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt(),
- any());
var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
var instanceElementDto = commonTestData.createInstanceElementDto(nodeTemplatesMap
.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
var compositionElementDto = commonTestData.createCompositionElementDto();
doReturn(false).when(chartService).installChart(any());
- assertThrows(PfModelException.class, () -> automationCompositionElementHandler.deploy(compositionElementDto,
- instanceElementDto));
+ assertThrows(PfModelException.class, () -> acElementHandler.deploy(compositionElementDto, instanceElementDto));
doReturn(true).when(chartService).installChart(any());
- automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto);
-
- doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(Mockito.any());
+ acElementHandler.deploy(compositionElementDto, instanceElementDto);
- assertThrows(PfModelException.class,
- () -> automationCompositionElementHandler.deploy(compositionElementDto, instanceElementDto));
+ doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(any());
- }
-
- @Test
- void test_checkPodStatus() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
-
- var chartInfo = charts.get(0);
- var automationCompositionId = UUID.randomUUID();
- assertThrows(PfModelException.class, () -> automationCompositionElementHandler
- .checkPodStatus(automationCompositionId, UUID.randomUUID(), chartInfo, 1, 1,
- commonTestData.createInstanceElementDto(Map.of())));
+ assertThrows(PfModelException.class, () -> acElementHandler.deploy(compositionElementDto, instanceElementDto));
}
@Test
void testUpdate() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
assertDoesNotThrow(
- () -> automationCompositionElementHandler.update(commonTestData.createCompositionElementDto(),
+ () -> acElementHandler.update(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(Map.of()),
commonTestData.createInstanceElementDto(Map.of())));
}
@Test
void testLock() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler.lock(commonTestData.createCompositionElementDto(),
+ assertDoesNotThrow(() -> acElementHandler.lock(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(Map.of())));
}
@Test
void testUnlock() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler
- .unlock(commonTestData.createCompositionElementDto(),
+ assertDoesNotThrow(() -> acElementHandler.unlock(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(Map.of())));
}
@Test
void testDelete() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler
- .delete(commonTestData.createCompositionElementDto(),
+ assertDoesNotThrow(() -> acElementHandler.delete(commonTestData.createCompositionElementDto(),
commonTestData.createInstanceElementDto(Map.of())));
}
@Test
void testPrime() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler.prime(new CompositionDto(UUID.randomUUID(),
- Map.of(), Map.of())));
+ assertDoesNotThrow(() -> acElementHandler.prime(new CompositionDto(UUID.randomUUID(), Map.of(), Map.of())));
}
@Test
void testDeprime() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(new CompositionDto(UUID.randomUUID(),
- Map.of(), Map.of())));
+ assertDoesNotThrow(() -> acElementHandler.deprime(new CompositionDto(UUID.randomUUID(), Map.of(), Map.of())));
}
@Test
void testMigrate() {
- var chartService = Mockito.mock(ChartService.class);
- var automationCompositionElementHandler =
- new AutomationCompositionElementHandler(mock(ParticipantIntermediaryApi.class), chartService);
+ var chartService = mock(ChartService.class);
+ var acElementHandler = new AutomationCompositionElementHandler(
+ mock(ParticipantIntermediaryApi.class), chartService, mock(PodStatusValidator.class));
- assertDoesNotThrow(() -> automationCompositionElementHandler
- .migrate(commonTestData.createCompositionElementDto(),
+ assertDoesNotThrow(() -> acElementHandler.migrate(commonTestData.createCompositionElementDto(),
commonTestData.createCompositionElementDto(), commonTestData.createInstanceElementDto(Map.of()),
commonTestData.createInstanceElementDto(Map.of()), 0));
}
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021,2025 OpenInfra Foundation Europe. All rights reserved.
+ * Copyright (C) 2021,2025-2026 OpenInfra Foundation Europe. All rights reserved.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import java.io.File;
import java.io.IOException;
import org.junit.jupiter.api.AfterAll;
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.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.acm.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.test.context.junit.jupiter.SpringExtension;
import org.springframework.util.FileSystemUtils;
-@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<ChartInfo> charts;
- @InjectMocks
- @Spy
- private HelmClient helmClient = new HelmClient();
-
- @Mock
- ChartStore chartStore;
-
- @Mock
- HelmRepository repo;
-
-
@BeforeAll
static void init() throws CoderException {
charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
@Test
void test_installChart() throws ServiceException {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = spy(new HelmClient(chartStore));
doReturn("success").when(helmClient).executeCommand(any());
doReturn(new File("/target/tmp/override.yaml")).when(chartStore)
.getOverrideFile(any());
doReturn("").when(helmClient).executeCommand(any());
assertDoesNotThrow(() -> helmClient.installChart(chartinfo));
-
}
@Test
void test_addRepository() throws ServiceException {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = spy(new HelmClient(chartStore));
doReturn("").when(helmClient).executeCommand(any());
- when(repo.getRepoName()).thenReturn("RepoName");
- when(repo.getAddress()).thenReturn("http://localhost:8080");
+
+ var repo = new HelmRepository();
+ repo.setRepoName("RepoName");
+ repo.setAddress("http://localhost:8080");
assertDoesNotThrow(() -> helmClient.addRepository(repo));
doReturn("failed").when(helmClient).executeCommand(any());
@Test
void test_findChartRepository() throws IOException, ServiceException {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = spy(new HelmClient(chartStore));
String tmpPath = "target/tmp/dummyChart/1.0/";
doReturn("nginx-stable/nginx-ingress\t0.9.3\t1.11.3"
+ " \tNGINX Ingress Controller").when(helmClient).executeCommand(any());
@Test
void test_uninstallChart() throws ServiceException {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = spy(new HelmClient(chartStore));
doReturn("success").when(helmClient).executeCommand(any());
helmClient.uninstallChart(charts.get(0));
doThrow(ServiceException.class).when(helmClient).executeCommand(any());
@Test
void test_verifyConfiguredRepoForInvalidChart() throws ServiceException {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = spy(new HelmClient(chartStore));
doReturn("").when(helmClient).executeCommand(any());
String configuredRepo = helmClient.verifyConfiguredRepo(charts.get(1));
assertNull(configuredRepo);
}
-
}
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022,2024 Nordix Foundation.
+ * Copyright (C) 2021-2022,2024,2026 OpenInfra Foundation Europe. All rights reserved.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import java.io.File;
-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.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList;
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.springframework.test.context.junit.jupiter.SpringExtension;
-@ExtendWith(SpringExtension.class)
class PodStatusValidatorTest {
private static final Coder CODER = new StandardCoder();
private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json";
private static final int TIMEOUT = 2;
private static final int STATUS_CHECK_INTERVAL = 1;
- private static List<ChartInfo> charts;
-
- @InjectMocks
- private PodStatusValidator podStatusValidator = new PodStatusValidator(charts.get(0), TIMEOUT,
- STATUS_CHECK_INTERVAL);
-
- @InjectMocks
- private PodStatusValidator podValidatorWithPodName = new PodStatusValidator(charts.get(2), TIMEOUT,
- STATUS_CHECK_INTERVAL);
-
-
- @Mock
- private HelmClient client;
+ private static ChartInfo chart0;
+ private static ChartInfo chart2;
@BeforeAll
static void init() throws CoderException {
- charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
+ var charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
+ chart0 = charts.get(0);
+ chart2 = charts.get(2);
}
-
@Test
void test_RunningPodState() throws ServiceException {
+ var client = mock(HelmClient.class);
+ var podStatusValidator = new PodStatusValidator(client);
String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nHelloWorld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h";
doReturn(runningPod).when(client).executeCommand(any());
- assertDoesNotThrow(() -> podStatusValidator.run());
+ assertDoesNotThrow(() -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart0));
}
@Test
void test_InvalidPodState() throws ServiceException {
+ var client = mock(HelmClient.class);
+ var podStatusValidator = new PodStatusValidator(client);
String invalidPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\nhellofromdocker-54777df9f8-qpzqr\t1/1\tInit\t0\t9h";
doReturn(invalidPod).when(client).executeCommand(any());
- assertThrows(PfModelException.class, () -> podStatusValidator.run());
+ assertThrows(PfModelException.class,
+ () -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart0));
}
// Use case scenario: Hard coded pod name
@Test
void test_RunningPodStateWithPodName() throws ServiceException {
+ var client = mock(HelmClient.class);
+ var podStatusValidator = new PodStatusValidator(client);
String runningPod = "NAME\tREADY\tSTATUS\tRESTARTS\tAGE\r\nhelloallworld-54777df9f8-qpzqr\t1/1\tRunning\t0\t9h";
doReturn(runningPod).when(client).executeCommand(any());
- assertDoesNotThrow(() -> podValidatorWithPodName.run());
+ assertDoesNotThrow(() -> podStatusValidator.run(TIMEOUT, STATUS_CHECK_INTERVAL, chart2));
}
}
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation.
+ * Copyright (C) 2021-2022,2026 OpenInfra Foundation Europe. All rights reserved.
* Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
-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.acm.participant.kubernetes.configurations.HelmRepositoryConfig;
import org.onap.policy.clamp.acm.participant.kubernetes.exception.ServiceException;
import org.onap.policy.clamp.acm.participant.kubernetes.helm.HelmClient;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartInfo;
import org.onap.policy.clamp.acm.participant.kubernetes.models.ChartList;
import org.onap.policy.clamp.acm.participant.kubernetes.models.HelmRepository;
+import org.onap.policy.clamp.acm.participant.kubernetes.parameters.HelmRepositoryConfig;
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<ChartInfo> charts;
- @InjectMocks
- @Spy
- private ChartService chartService = new ChartService();
-
- @Mock
- private ChartStore chartStore;
-
- @Mock
- private HelmClient helmClient;
-
- @Mock
- private HelmRepositoryConfig helmRepositoryConfig;
-
@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();
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig());
+ assertThat(chartService.getAllCharts()).isEmpty();
doReturn(charts).when(chartStore).getAllCharts();
- Collection<ChartInfo> result = chartService.getAllCharts();
+ var result = chartService.getAllCharts();
assertNotNull(result);
assertThat(result).containsAll(charts);
}
@Test
void test_getChart() {
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig());
assertNull(chartService.getChart("dummyName", "dummyversion"));
- doReturn(charts.get(0)).when(chartStore).getChart(any(), any());
- ChartInfo chart = chartService.getChart(charts.get(0).getChartId().getName(),
- charts.get(0).getChartId().getVersion());
+ var chart0 = charts.get(0);
+ doReturn(chart0).when(chartStore).getChart(any(), any());
+ var chart = chartService.getChart(chart0.getChartId().getName(), chart0.getChartId().getVersion());
assertNotNull(chart);
- assertThat(chart.getNamespace()).isEqualTo(charts.get(0).getNamespace());
+ assertThat(chart.getNamespace()).isEqualTo(chart0.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))
+ var chart0 = charts.get(0);
+ var chartStore = mock(ChartStore.class);
+ doThrow(IOException.class).when(chartStore).saveChart(chart0, null, null);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig());
+ assertThatThrownBy(() -> chartService.saveChart(chart0, null, null))
.isInstanceOf(IOException.class);
- MockMultipartFile mockChartFile = new MockMultipartFile("chart", "dummy".getBytes());
- MockMultipartFile mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes());
+ var mockChartFile = new MockMultipartFile("chart", "dummy".getBytes());
+ var mockOverrideFile = new MockMultipartFile("override", "dummy".getBytes());
- doReturn(charts.get(0)).when(chartStore).saveChart(any(), any(), any());
+ doReturn(chart0).when(chartStore).saveChart(any(), any(), any());
- ChartInfo chart = chartService.saveChart(charts.get(0), mockChartFile, mockOverrideFile);
+ var chart = chartService.saveChart(chart0, mockChartFile, mockOverrideFile);
assertNotNull(chart);
- assertThat(chart.getChartId().getName()).isEqualTo(charts.get(0).getChartId().getName());
+ assertThat(chart.getChartId().getName()).isEqualTo(chart0.getChartId().getName());
+ }
+ @Test
+ void test_FailInstallChart() throws IOException, ServiceException {
+ var helmRepositoryConfig = new HelmRepositoryConfig();
+ helmRepositoryConfig.setRepos("[]");
+ helmRepositoryConfig.setProtocols("http,https");
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig);
+ doReturn("dummyRepoName").when(helmClient).findChartRepository(any());
+ var testChart = charts.get(1);
+ var result = chartService.installChart(testChart);
+ assertTrue(result);
+ }
+
+ @Test
+ void test_FailEncodeInstallChart() {
+ var helmRepositoryConfig = new HelmRepositoryConfig();
+ helmRepositoryConfig.setRepos("[");
+ helmRepositoryConfig.setProtocols("http,https");
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig);
+ var chart0 = charts.get(0);
+ assertThatThrownBy(() -> chartService.installChart(chart0)).isInstanceOf(ServiceException.class);
}
@Test
- void test_installChart() throws IOException, ServiceException {
- List<HelmRepository> helmRepositoryList = new ArrayList<>();
- helmRepositoryList.add(HelmRepository.builder().address("https://localhost:8080").build());
- doReturn(helmRepositoryList).when(helmRepositoryConfig).getRepos();
- doReturn(List.of("http", "https")).when(helmRepositoryConfig).getProtocols();
- assertDoesNotThrow(() -> chartService.installChart(charts.get(0)));
+ void test_installChart() throws IOException, ServiceException, CoderException {
+ var helmRepositoryConfig = new HelmRepositoryConfig();
+ var repos = List.of(HelmRepository.builder().address("https://localhost:8080").build());
+ helmRepositoryConfig.setRepos(CODER.encode(repos));
+ helmRepositoryConfig.setProtocols("http,https");
+ var chart0 = charts.get(0);
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, helmRepositoryConfig);
+ assertDoesNotThrow(() -> chartService.installChart(chart0));
+
doThrow(ServiceException.class).when(helmClient).installChart(any());
- assertThatThrownBy(() -> chartService.installChart(charts.get(0))).isInstanceOf(ServiceException.class);
+ assertThatThrownBy(() -> chartService.installChart(chart0)).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().getRepoName());
+ doReturn("dummyRepoName").when(helmClient).findChartRepository(any());
+ var testChart = charts.get(1);
+ chartService.installChart(testChart);
+ assertEquals("dummyRepoName", testChart.getRepository().getRepoName());
- ChartInfo testChart = charts.get(1);
testChart.setRepository(null);
- doReturn(null).when(chartService).findChartRepo(any());
- chartService.installChart(charts.get(1));
+ doReturn(null).when(helmClient).findChartRepository(any());
+ chartService.installChart(testChart);
+
+ chartService.deleteChart(testChart);
+ verify(chartStore).deleteChart(testChart);
}
@Test
void test_UninstallChart() throws ServiceException {
- assertDoesNotThrow(() -> chartService.uninstallChart(charts.get(0)));
+ var chart0 = charts.get(0);
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig());
+ assertDoesNotThrow(() -> chartService.uninstallChart(chart0));
doThrow(ServiceException.class).when(helmClient).uninstallChart(any());
- assertThatThrownBy(() -> chartService.uninstallChart(charts.get(0))).isInstanceOf(ServiceException.class);
+ assertThatThrownBy(() -> chartService.uninstallChart(chart0)).isInstanceOf(ServiceException.class);
}
@Test
void test_findChartRepo() throws IOException, ServiceException {
- assertDoesNotThrow(() -> chartService.findChartRepo(charts.get(0)));
+ var chart0 = charts.get(0);
+ var chartStore = mock(ChartStore.class);
+ var helmClient = mock(HelmClient.class);
+ var chartService = new ChartService(chartStore, helmClient, new HelmRepositoryConfig());
+ assertDoesNotThrow(() -> chartService.findChartRepo(chart0));
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);
+ assertThatThrownBy(() -> chartService.findChartRepo(chart0)).isInstanceOf(ServiceException.class);
}
}