diff options
Diffstat (limited to 'participant')
15 files changed, 437 insertions, 42 deletions
diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java index cfe786865..86a864efc 100644 --- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java @@ -37,6 +37,7 @@ import org.apache.commons.lang3.tuple.Pair; 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.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.controlloop.participant.http.main.models.ConfigRequest; import org.onap.policy.clamp.controlloop.participant.http.main.webclient.ClHttpClient; import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; @@ -90,7 +91,26 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl @Override public void controlLoopElementStateChange(ToscaConceptIdentifier controlLoopId, UUID controlLoopElementId, ControlLoopState currentState, ControlLoopOrderedState newState) throws PfModelException { - // Implementation not needed for http participant + switch (newState) { + case UNINITIALISED: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.UNINITIALISED, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + case PASSIVE: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.PASSIVE, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + case RUNNING: + intermediaryApi.updateControlLoopElementState(controlLoopId, + controlLoopElementId, newState, ControlLoopState.RUNNING, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); + break; + default: + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); + break; + } } /** @@ -108,6 +128,9 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl .getValidator().validate(configRequest); if (violations.isEmpty()) { invokeHttpClient(configRequest); + intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), + ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, + ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); } else { LOGGER.error("Violations found in the config request parameters: {}", violations); throw new ValidationException("Constraint violations in the config request"); diff --git a/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java index 0de25072d..d1556ea08 100644 --- a/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.java @@ -29,9 +29,11 @@ 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.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; @@ -46,6 +48,9 @@ class ClElementHandlerTest { @Spy private ControlLoopElementHandler controlLoopElementHandler = new ControlLoopElementHandler(); + @Mock + private ParticipantIntermediaryApi participantIntermediaryApi; + private CommonTestData commonTestData = new CommonTestData(); private static ToscaServiceTemplate serviceTemplate; 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 a5d1f8841..e1e9195eb 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 @@ -103,7 +103,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { chartMap.remove(controlLoopElementId); podStatusMap.remove(chart.getReleaseName()); } catch (ServiceException se) { - LOGGER.warn("deletion of Helm deployment failed", se); + LOGGER.warn("Deletion of Helm deployment failed", se); } } break; @@ -118,7 +118,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); break; default: - LOGGER.warn("cannot transition from state {} to state {}", currentState, newState); + LOGGER.warn("Cannot transition from state {} to state {}", currentState, newState); break; } } @@ -148,7 +148,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { checkPodStatus(chartInfo, config.uninitializedToPassiveTimeout, config.podStatusCheckInterval); intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(), - ControlLoopOrderedState.PASSIVE, ControlLoopState.UNINITIALISED, + ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE); } catch (ServiceException | CoderException | IOException e) { 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 index fcac64dd6..bbb57c320 100644 --- 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 @@ -29,7 +29,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; +import org.apache.commons.io.FileUtils; import org.json.JSONObject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -65,9 +68,11 @@ class ChartControllerTest { private static final Coder CODER = new StandardCoder(); private static final String CHART_INFO_YAML = "src/test/resources/ChartList.json"; private static List<ChartInfo> charts; - private static String DEFAULT_CHART_URL = "/helm/charts"; + private static String RETRIEVE_CHART_URL = "/helm/charts"; private static String INSTALL_CHART_URL = "/helm/install"; private static String UNINSTALL_CHART_URL = "/helm/uninstall/"; + private static String ONBOARD_CHART_URL = "/helm/onboard/chart"; + private static String DELETE_CHART_URL = "/helm/chart"; @Autowired private MockMvc mockMvc; @@ -107,7 +112,7 @@ class ChartControllerTest { @Test void retrieveAllCharts() throws Exception { RequestBuilder requestBuilder; - requestBuilder = MockMvcRequestBuilders.get(DEFAULT_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); + requestBuilder = MockMvcRequestBuilders.get(RETRIEVE_CHART_URL).accept(MediaType.APPLICATION_JSON_VALUE); mockMvc.perform(requestBuilder).andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) @@ -180,7 +185,7 @@ class ChartControllerTest { //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) + requestBuilder = MockMvcRequestBuilders.multipart(ONBOARD_CHART_URL) .file(chartFile).file(overrideFile).param("info", getChartInfoJson()); mockMvc.perform(requestBuilder).andExpect(status().isOk()); @@ -197,7 +202,7 @@ class ChartControllerTest { //Mocking successful scenario for void uninstall method doNothing().when(chartService).deleteChart(charts.get(0)); - requestBuilder = MockMvcRequestBuilders.delete(DEFAULT_CHART_URL + "/" + charts.get(0) + requestBuilder = MockMvcRequestBuilders.delete(DELETE_CHART_URL + "/" + charts.get(0) .getChartId().getName() + "/" + charts.get(0).getChartId().getVersion()) .accept(MediaType.APPLICATION_JSON_VALUE) .contentType(MediaType.APPLICATION_JSON_VALUE); @@ -219,14 +224,8 @@ class ChartControllerTest { return jsonObj.toString(); } - private String getChartInfoJson() { - JSONObject jsonObj = new JSONObject(); - jsonObj.put("chartName", charts.get(0).getChartId().getName()); - jsonObj.put("version", charts.get(0).getChartId().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(); + private String getChartInfoJson() throws IOException { + return FileUtils.readFileToString(new File(CHART_INFO_YAML), StandardCharsets.UTF_8); } } 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 index 4c8b5b3b3..f1c8d19df 100644 --- 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 @@ -121,7 +121,7 @@ class ChartServiceTest { doReturn("dummyRepoName").when(chartService).findChartRepo(any()); doNothing().when(helmClient).installChart(any()); chartService.installChart(charts.get(1)); - assertEquals("dummyRepoName", charts.get(1).getRepository()); + assertEquals("dummyRepoName", charts.get(1).getRepository().getRepoName()); ChartInfo testChart = charts.get(1); testChart.setRepository(null); 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 index 2f4ec2827..9822846f3 100644 --- a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/ChartList.json @@ -6,7 +6,9 @@ "version" : "1.0" }, "namespace" : "onap", - "repository" : "chartMuseum", + "repository" : { + "repoName": "chartMuseum" + }, "releaseName" : "helloworld" }, { diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java index 891d67e2d..0cb4963ec 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java @@ -34,6 +34,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; /** * This interface is used by participant implementations to use the participant intermediary. @@ -57,6 +58,14 @@ public interface ParticipantIntermediaryApi { List<Participant> getParticipants(String name, String version); /** + * Get common properties of a controlloopelement. + * + * @param clElementDef the control loop element definition + * @return the common properties + */ + Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef); + + /** * Update the state of a participant. * * @param definition the definition of the participant to update the state on diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java index aa1febadd..43ac3464c 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java @@ -40,6 +40,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.api.Participan import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.springframework.stereotype.Component; /** @@ -77,6 +78,11 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp } @Override + public Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { + return participantHandler.getClElementDefinitionCommonProperties(clElementDef); + } + + @Override public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) { return participantHandler.updateParticipantState(definition, state); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java index 30a06ba22..40dc901db 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate; @@ -47,6 +49,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.Par import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -217,6 +220,15 @@ public class ControlLoopHandler { return; } + if (0 == updateMsg.getStartPhase()) { + handleClUpdatePhase0(updateMsg, clElementDefinitions); + } else { + handleClUpdatePhaseN(updateMsg, clElementDefinitions); + } + } + + private void handleClUpdatePhase0(ControlLoopUpdate updateMsg, + List<ControlLoopElementDefinition> clElementDefinitions) { var controlLoop = controlLoopMap.get(updateMsg.getControlLoopId()); // TODO: Updates to existing ControlLoops are not supported yet (Addition/Removal of ControlLoop @@ -242,30 +254,54 @@ public class ControlLoopHandler { var clElements = storeElementsOnThisParticipant(updateMsg.getParticipantUpdatesList()); + var clElementMap = prepareClElementMap(clElements); + controlLoop = new ControlLoop(); + controlLoop.setDefinition(updateMsg.getControlLoopId()); + controlLoop.setElements(clElementMap); + controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop); + + handleControlLoopElementUpdate(clElements, clElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getControlLoopId()); + } + + private void handleClUpdatePhaseN(ControlLoopUpdate updateMsg, + List<ControlLoopElementDefinition> clElementDefinitions) { + + var clElementList = updateMsg.getParticipantUpdatesList().stream() + .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) + .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); + + handleControlLoopElementUpdate(clElementList, clElementDefinitions, updateMsg.getStartPhase(), + updateMsg.getControlLoopId()); + } + + private void handleControlLoopElementUpdate(List<ControlLoopElement> clElements, + List<ControlLoopElementDefinition> clElementDefinitions, Integer startPhaseMsg, + ToscaConceptIdentifier controlLoopId) { try { for (var element : clElements) { - var clElementNodeTemplate = - getClElementNodeTemplate(clElementDefinitions, element.getDefinition()); - for (var clElementListener : listeners) { - clElementListener.controlLoopElementUpdate(updateMsg.getControlLoopId(), element, - clElementNodeTemplate); + var clElementNodeTemplate = getClElementNodeTemplate(clElementDefinitions, element.getDefinition()); + if (clElementNodeTemplate != null) { + int startPhase = ParticipantUtils.findStartPhase(clElementNodeTemplate.getProperties()); + if (startPhaseMsg.equals(startPhase)) { + for (var clElementListener : listeners) { + clElementListener.controlLoopElementUpdate(controlLoopId, element, clElementNodeTemplate); + } + } } } } catch (PfModelException e) { - LOGGER.debug("Control loop element update failed {}", updateMsg.getControlLoopId()); + LOGGER.debug("Control loop element update failed {}", controlLoopId); } - var clElementMap = prepareClElementMap(clElements); - controlLoop = new ControlLoop(); - controlLoop.setDefinition(updateMsg.getControlLoopId()); - controlLoop.setElements(clElementMap); - controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop); } private ToscaNodeTemplate getClElementNodeTemplate(List<ControlLoopElementDefinition> clElementDefinitions, ToscaConceptIdentifier clElementDefId) { + for (var clElementDefinition : clElementDefinitions) { - if (clElementDefinition.getClElementDefinitionId().equals(clElementDefId)) { + if (clElementDefId.getName().contains( + clElementDefinition.getClElementDefinitionId().getName())) { return clElementDefinition.getControlLoopElementToscaNodeTemplate(); } } @@ -273,14 +309,14 @@ public class ControlLoopHandler { } private List<ControlLoopElement> storeElementsOnThisParticipant(List<ParticipantUpdates> participantUpdates) { - var clElementMap = participantUpdates.stream() + var clElementList = participantUpdates.stream() .flatMap(participantUpdate -> participantUpdate.getControlLoopElementList().stream()) .filter(element -> participantType.equals(element.getParticipantType())).collect(Collectors.toList()); - for (var element : clElementMap) { + for (var element : clElementList) { elementsOnThisParticipant.put(element.getId(), element); } - return clElementMap; + return clElementList; } private Map<UUID, ControlLoopElement> prepareClElementMap(List<ControlLoopElement> clElements) { @@ -345,8 +381,8 @@ public class ControlLoopHandler { controlLoop.getElements().values().stream().forEach(clElement -> { for (var clElementListener : listeners) { try { - clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), - clElement.getId(), clElement.getState(), orderedState); + clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), clElement.getId(), + clElement.getState(), orderedState); } catch (PfModelException e) { LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition()); } @@ -364,4 +400,21 @@ public class ControlLoopHandler { controlLoops.setControlLoopList(new ArrayList<>(controlLoopMap.values())); return controlLoops; } + + /** + * Get properties of a controlloopelement. + * + * @param id the control loop element id + * @return the instance properties + */ + public Map<String, ToscaProperty> getClElementInstanceProperties(UUID id) { + Map<String, ToscaProperty> propertiesMap = new HashMap<>(); + for (var controlLoop : controlLoopMap.values()) { + var element = controlLoop.getElements().get(id); + if (element != null) { + propertiesMap.putAll(element.getPropertiesMap()); + } + } + return propertiesMap; + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java index 1d445324b..e42fac46e 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java @@ -24,6 +24,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.io.Closeable; import java.io.IOException; import java.util.List; +import lombok.Getter; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; import org.onap.policy.common.endpoints.event.comm.TopicSink; @@ -49,6 +50,7 @@ public class IntermediaryActivator extends ServiceManagerContainer implements Cl private ParticipantHandler participantHandler; + @Getter private final MessageTypeDispatcher msgDispatcher; /** diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java index 69f8febb8..ea7d84501 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java @@ -24,6 +24,7 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -60,6 +61,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.comm.Participa import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -206,6 +208,22 @@ public class ParticipantHandler { } /** + * Get common properties of a controlloopelement. + * + * @param clElementDef the control loop element definition + * @return the common properties + */ + public Map<String, ToscaProperty> getClElementDefinitionCommonProperties(ToscaConceptIdentifier clElementDef) { + Map<String, ToscaProperty> commonPropertiesMap = new HashMap<>(); + clElementDefsOnThisParticipant.stream().forEach(definition -> { + if (definition.getClElementDefinitionId().equals(clElementDef)) { + commonPropertiesMap.putAll(definition.getCommonPropertiesMap()); + } + }); + return commonPropertiesMap; + } + + /** * Check if a participant message applies to this participant handler. * * @param participantMsg the message to check @@ -284,15 +302,10 @@ public class ParticipantHandler { LOGGER.debug("ParticipantUpdate message received for participantId {}", participantUpdateMsg.getParticipantId()); - if (!participantUpdateMsg.appliesTo(participantType, participantId)) { - return; - } - if (!participantUpdateMsg.getParticipantDefinitionUpdates().isEmpty()) { // This message is to commission the controlloop for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) { if (participantDefinition.getParticipantType().equals(participantType)) { - clElementDefsOnThisParticipant.clear(); clElementDefsOnThisParticipant.addAll(participantDefinition.getControlLoopElementDefinitionList()); break; } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java new file mode 100644 index 000000000..29387959b --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandlerTest.java @@ -0,0 +1,93 @@ +/*- + * ============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.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +import java.time.Instant; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; +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.ControlLoopElementListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +class ControlLoopHandlerTest { + + private CommonTestData commonTestData = new CommonTestData(); + + @Test + void controlLoopHandlerTest() { + ControlLoopHandler clh = commonTestData.getMockControlLoopHandler(); + assertNotNull(clh.getControlLoops()); + + assertNotNull(clh.getControlLoopMap()); + assertNotNull(clh.getElementsOnThisParticipant()); + + UUID elementId1 = UUID.randomUUID(); + ControlLoopElement element = new ControlLoopElement(); + element.setId(elementId1); + element.setDefinition(new ToscaConceptIdentifier( + "org.onap.policy.controlloop.PolicyControlLoopParticipant", "1.0.1")); + + element.setOrderedState(ControlLoopOrderedState.PASSIVE); + + ControlLoopElementListener listener = mock(ControlLoopElementListener.class); + clh.registerControlLoopElementListener(listener); + assertThat(clh.getListeners()).contains(listener); + + } + + @Test + void updateNullControlLoopHandlerTest() { + UUID id = UUID.randomUUID(); + + ControlLoopHandler clh = commonTestData.getMockControlLoopHandler(); + assertNull(clh.updateControlLoopElementState(null, null, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + assertNull(clh.updateControlLoopElementState(null, id, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + ClElementStatistics clElementStatistics = new ClElementStatistics(); + ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("defName", "0.0.1"); + clElementStatistics.setParticipantId(controlLoopId); + clElementStatistics.setControlLoopState(ControlLoopState.RUNNING); + clElementStatistics.setTimeStamp(Instant.now()); + + clh.updateControlLoopElementStatistics(id, clElementStatistics); + assertNull(clh.updateControlLoopElementState(controlLoopId, id, ControlLoopOrderedState.UNINITIALISED, + ControlLoopState.PASSIVE)); + + + + } + +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java new file mode 100644 index 000000000..d60bb71bc --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/DummyParticipantParameters.java @@ -0,0 +1,35 @@ +/*- + * ============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.intermediary.handler; + +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; + +@Getter +@Setter +public class DummyParticipantParameters implements ParticipantParameters { + + @NotNull + private ParticipantIntermediaryParameters intermediaryParameters; +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java new file mode 100644 index 000000000..bbe0412ed --- /dev/null +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivatorTest.java @@ -0,0 +1,97 @@ +/*- + * ============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.intermediary.handler; + +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatusReq; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusReqListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters.CommonTestData; +import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardCoderObject; + +class IntermediaryActivatorTest { + private static final Coder CODER = new StandardCoder(); + + private static final String TOPIC_FIRST = "TOPIC1"; + private static final String TOPIC_SECOND = "TOPIC2"; + + @Test + void testStartAndStop() throws Exception { + ParticipantParameters parameters = CommonTestData.getParticipantParameters(); + + var publisherFirst = spy(mock(Publisher.class)); + var publisherSecond = spy(mock(Publisher.class)); + var publishers = List.of(publisherFirst, publisherSecond); + + var listenerFirst = spy(mock(ParticipantStatusReqListener.class)); + when(listenerFirst.getType()).thenReturn(TOPIC_FIRST); + when(listenerFirst.getScoListener()).thenReturn(listenerFirst); + + var listenerSecond = spy(mock(ParticipantStatusReqListener.class)); + when(listenerSecond.getType()).thenReturn(TOPIC_SECOND); + when(listenerSecond.getScoListener()).thenReturn(listenerSecond); + + List<Listener<ParticipantStatusReq>> listeners = List.of(listenerFirst, listenerSecond); + + ParticipantHandler handler = mock(ParticipantHandler.class); + try (var activator = new IntermediaryActivator(parameters, handler, publishers, listeners)) { + + assertFalse(activator.isAlive()); + activator.start(); + assertTrue(activator.isAlive()); + + // repeat start - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.start()); + assertTrue(activator.isAlive()); + verify(publisherFirst, times(1)).active(anyList()); + verify(publisherSecond, times(1)).active(anyList()); + + StandardCoderObject sco = CODER.decode("{messageType:" + TOPIC_FIRST + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerFirst, times(1)).onTopicEvent(any(), any(), any()); + + sco = CODER.decode("{messageType:" + TOPIC_SECOND + "}", StandardCoderObject.class); + activator.getMsgDispatcher().onTopicEvent(null, "msg", sco); + verify(listenerSecond, times(1)).onTopicEvent(any(), any(), any()); + + activator.stop(); + assertFalse(activator.isAlive()); + + // repeat stop - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.stop()); + assertFalse(activator.isAlive()); + } + } +} diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java index 9353cde81..ae20f4b7f 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/controlloop/participant/intermediary/main/parameters/CommonTestData.java @@ -21,10 +21,16 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.main.parameters; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.mockito.Mockito; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher; +import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ControlLoopHandler; +import org.onap.policy.clamp.controlloop.participant.intermediary.handler.DummyParticipantParameters; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.parameters.TopicParameters; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; @@ -41,6 +47,7 @@ public class CommonTestData { public static final List<TopicParameters> TOPIC_PARAMS = Arrays.asList(getTopicParams()); public static final Coder CODER = new StandardCoder(); + private static final Object lockit = new Object(); /** * Get ParticipantIntermediaryParameters. @@ -57,12 +64,38 @@ public class CommonTestData { } /** + * Get ParticipantParameters. + * + * @return ParticipantParameters + */ + public static DummyParticipantParameters getParticipantParameters() { + try { + return CODER.convert(getParametersMap(PARTICIPANT_GROUP_NAME), + DummyParticipantParameters.class); + } catch (final CoderException e) { + throw new RuntimeException("cannot create ParticipantSimulatorParameters from map", e); + } + } + + /** + * Returns a property map for a Parameters map for test cases. + * + * @param name name of the parameters + * @return a property map suitable for constructing an object + */ + public static Map<String, Object> getParametersMap(final String name) { + final Map<String, Object> map = new TreeMap<>(); + map.put("intermediaryParameters", getIntermediaryParametersMap(name)); + return map; + } + + /** * Returns a property map for a intermediaryParameters map for test cases. * * @param name name of the parameters * @return a property map suitable for constructing an object */ - public Map<String, Object> getIntermediaryParametersMap(final String name) { + public static Map<String, Object> getIntermediaryParametersMap(final String name) { final Map<String, Object> map = new TreeMap<>(); map.put("name", name); map.put("participantId", getParticipantId()); @@ -80,7 +113,7 @@ public class CommonTestData { * @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<String, Object> getTopicParametersMap(final boolean isEmpty) { + public static Map<String, Object> getTopicParametersMap(final boolean isEmpty) { final Map<String, Object> map = new TreeMap<>(); if (!isEmpty) { map.put("topicSources", TOPIC_PARAMS); @@ -110,4 +143,29 @@ public class CommonTestData { public static ToscaConceptIdentifier getParticipantId() { return new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.1"); } + + /** + * Returns a participantMessagePublisher for MessageSender. + * + * @return participant Message Publisher + */ + private ParticipantMessagePublisher getParticipantMessagePublisher() { + synchronized (lockit) { + ParticipantMessagePublisher participantMessagePublisher = + new ParticipantMessagePublisher(); + participantMessagePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class))); + return participantMessagePublisher; + } + } + + /** + * Returns a mocked ControlLoopHandler for test cases. + * + * @return ControlLoopHandler + */ + public ControlLoopHandler getMockControlLoopHandler() { + return new ControlLoopHandler( + getParticipantParameters(), + getParticipantMessagePublisher()); + } } |