return null;
}
+ /**
+ * Get the First StartPhase
+ * it depend of the state of the Control Loop
+ * and also from the all startPhase defined into the ToscaServiceTemplate.
+ * @param controlLoop the ControlLoop
+ * @param toscaServiceTemplate the ToscaServiceTemplate
+ * @return the First StartPhase
+ */
+ public static int getFirstStartPhase(ControlLoop controlLoop, ToscaServiceTemplate toscaServiceTemplate) {
+ var minStartPhase = 1000;
+ var maxStartPhase = 0;
+ for (var element : controlLoop.getElements().values()) {
+ ToscaNodeTemplate toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates()
+ .get(element.getDefinition().getName());
+ int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties());
+ minStartPhase = Math.min(minStartPhase, startPhase);
+ maxStartPhase = Math.max(maxStartPhase, startPhase);
+ }
+
+ return ControlLoopState.UNINITIALISED2PASSIVE.equals(controlLoop.getState())
+ || ControlLoopState.PASSIVE2RUNNING.equals(controlLoop.getState()) ? minStartPhase
+ : maxStartPhase;
+ }
+
/**
* Finds startPhase from a map of properties.
*
--- /dev/null
+/*-
+ * ============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.models.controlloop.concepts;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+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.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+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.ToscaServiceTemplate;
+
+class ParticipantUtilsTest {
+
+ private static final Coder CODER = new StandardCoder();
+ private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml";
+ private static final String CONTROL_LOOP_JSON = "src/test/resources/providers/TestControlLoops.json";
+ private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
+ private static final String POLICY_CONTROL_LOOP_ELEMENT =
+ "org.onap.policy.clamp.controlloop.PolicyControlLoopElement";
+ private static final String PARTICIPANT_CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.Participant";
+ private static final StandardYamlCoder YAML_TRANSLATOR = new StandardYamlCoder();
+
+ @Test
+ void testFindParticipantType() throws CoderException {
+ var identifier = new ToscaConceptIdentifier("Identifier", "1.0.1");
+ var result = ParticipantUtils.findParticipantType(Map.of("participantType", CODER.encode(identifier)));
+ assertThat(result).isEqualTo(identifier);
+ }
+
+ @Test
+ void testFindStartPhase() {
+ var identifier = 13;
+ var result = ParticipantUtils.findStartPhase(Map.of("startPhase", identifier));
+ assertThat(result).isEqualTo(identifier);
+ }
+
+ @Test
+ void testGetFirstStartPhase() throws CoderException {
+ var serviceTemplate = YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(TOSCA_TEMPLATE_YAML),
+ ToscaServiceTemplate.class);
+ var controlLoops = CODER.decode(ResourceUtils.getResourceAsString(CONTROL_LOOP_JSON), ControlLoops.class);
+ var result = ParticipantUtils.getFirstStartPhase(controlLoops.getControlLoopList().get(0), serviceTemplate);
+ assertThat(result).isZero();
+ }
+
+ @Test
+ void testCheckIfNodeTemplateIsControlLoopElement() throws CoderException {
+ var serviceTemplate = YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(TOSCA_TEMPLATE_YAML),
+ ToscaServiceTemplate.class);
+ var nodeTemplate = new ToscaNodeTemplate();
+ nodeTemplate.setType(CONTROL_LOOP_ELEMENT);
+ assertThat(ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(nodeTemplate, serviceTemplate)).isTrue();
+
+ nodeTemplate.setType(POLICY_CONTROL_LOOP_ELEMENT);
+ assertThat(ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(nodeTemplate, serviceTemplate)).isTrue();
+
+ nodeTemplate.setType(PARTICIPANT_CONTROL_LOOP_ELEMENT);
+ assertThat(ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(nodeTemplate, serviceTemplate)).isFalse();
+ }
+}
/**
* Handle a control loop element state change message.
*
- * @param id controlloop element id
+ * @param controlLoopId the controlLoop Id
+ * @param id the controlLoop UUID
* @param orderedState the current state
* @param newState the ordered state
* @return controlLoopElement the updated controlloop element
* Handle a control loop state change message.
*
* @param stateChangeMsg the state change message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- public void handleControlLoopStateChange(ControlLoopStateChange stateChangeMsg) {
+ public void handleControlLoopStateChange(ControlLoopStateChange stateChangeMsg,
+ List<ControlLoopElementDefinition> clElementDefinitions) {
if (stateChangeMsg.getControlLoopId() == null) {
return;
}
return;
}
- handleState(controlLoop, stateChangeMsg.getOrderedState());
+ handleState(controlLoop, stateChangeMsg.getOrderedState(), stateChangeMsg.getStartPhase(),
+ clElementDefinitions);
}
/**
*
* @param controlLoop participant response
* @param orderedState controlloop ordered state
+ * @param startPhaseMsg startPhase from message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- private void handleState(final ControlLoop controlLoop, ControlLoopOrderedState orderedState) {
+ private void handleState(final ControlLoop controlLoop, ControlLoopOrderedState orderedState, Integer startPhaseMsg,
+ List<ControlLoopElementDefinition> clElementDefinitions) {
switch (orderedState) {
case UNINITIALISED:
- handleUninitialisedState(controlLoop, orderedState);
+ handleUninitialisedState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
break;
case PASSIVE:
- handlePassiveState(controlLoop, orderedState);
+ handlePassiveState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
break;
case RUNNING:
- handleRunningState(controlLoop, orderedState);
+ handleRunningState(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
break;
default:
LOGGER.debug("StateChange message has no state, state is null {}", controlLoop.getDefinition());
* Handle a control loop update message.
*
* @param updateMsg the update message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
public void handleControlLoopUpdate(ControlLoopUpdate updateMsg,
List<ControlLoopElementDefinition> clElementDefinitions) {
ToscaConceptIdentifier clElementDefId) {
for (var clElementDefinition : clElementDefinitions) {
- if (clElementDefId.getName().contains(
- clElementDefinition.getClElementDefinitionId().getName())) {
+ if (clElementDefId.getName().contains(clElementDefinition.getClElementDefinitionId().getName())) {
return clElementDefinition.getControlLoopElementToscaNodeTemplate();
}
}
*
* @param controlLoop participant response
* @param orderedState orderedState
+ * @param startPhaseMsg startPhase from message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
- handleStateChange(controlLoop, orderedState);
- controlLoopMap.remove(controlLoop.getDefinition());
- controlLoop.getElements().values().forEach(element -> elementsOnThisParticipant.remove(element.getId()));
+ private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ Integer startPhaseMsg, List<ControlLoopElementDefinition> clElementDefinitions) {
+ handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
+ boolean isAllUninitialised = controlLoop.getElements().values().stream()
+ .filter(element -> !ControlLoopState.UNINITIALISED.equals(element.getState())).findAny().isEmpty();
+ if (isAllUninitialised) {
+ controlLoopMap.remove(controlLoop.getDefinition());
+ controlLoop.getElements().values().forEach(element -> elementsOnThisParticipant.remove(element.getId()));
+ }
}
/**
*
* @param controlLoop participant response
* @param orderedState orderedState
+ * @param startPhaseMsg startPhase from message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
- handleStateChange(controlLoop, orderedState);
+ private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ Integer startPhaseMsg, List<ControlLoopElementDefinition> clElementDefinitions) {
+ handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
}
/**
*
* @param controlLoop participant response
* @param orderedState orderedState
+ * @param startPhaseMsg startPhase from message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
- handleStateChange(controlLoop, orderedState);
+ private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ Integer startPhaseMsg, List<ControlLoopElementDefinition> clElementDefinitions) {
+ handleStateChange(controlLoop, orderedState, startPhaseMsg, clElementDefinitions);
}
/**
*
* @param controlLoop participant status in memory
* @param orderedState orderedState the new ordered state the participant should have
+ * @param startPhaseMsg startPhase from message
+ * @param clElementDefinitions the list of ControlLoopElementDefinition
*/
- private void handleStateChange(ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
+ private void handleStateChange(ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ Integer startPhaseMsg, List<ControlLoopElementDefinition> clElementDefinitions) {
if (orderedState.equals(controlLoop.getOrderedState())) {
var controlLoopAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK);
return;
}
- controlLoop.getElements().values().stream().forEach(clElement -> {
- for (var clElementListener : listeners) {
- try {
- clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), clElement.getId(),
- clElement.getState(), orderedState);
- } catch (PfModelException e) {
- LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition());
+ controlLoop.getElements().values().stream().forEach(clElement -> controlLoopElementStateChange(controlLoop,
+ orderedState, clElement, startPhaseMsg, clElementDefinitions));
+ }
+
+ private void controlLoopElementStateChange(ControlLoop controlLoop, ControlLoopOrderedState orderedState,
+ ControlLoopElement clElement, Integer startPhaseMsg,
+ List<ControlLoopElementDefinition> clElementDefinitions) {
+ var clElementNodeTemplate = getClElementNodeTemplate(clElementDefinitions, clElement.getDefinition());
+ if (clElementNodeTemplate != null) {
+ int startPhase = ParticipantUtils.findStartPhase(clElementNodeTemplate.getProperties());
+ if (startPhaseMsg.equals(startPhase)) {
+ for (var clElementListener : listeners) {
+ try {
+ clElementListener.controlLoopElementStateChange(controlLoop.getDefinition(), clElement.getId(),
+ clElement.getState(), orderedState);
+ } catch (PfModelException e) {
+ LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition());
+ }
}
}
- });
+ }
}
/**
* @param stateChangeMsg the state change message
*/
public void handleControlLoopStateChange(ControlLoopStateChange stateChangeMsg) {
- controlLoopHandler.handleControlLoopStateChange(stateChangeMsg);
+ controlLoopHandler.handleControlLoopStateChange(stateChangeMsg, clElementDefsOnThisParticipant);
}
private void handleStateChange(ParticipantState newParticipantState, ParticipantUpdateAck response) {
import java.util.Set;
import java.util.UUID;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUtils;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.provider.PolicyModelsProvider;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
private final ControlLoopProvider controlLoopProvider;
private final ParticipantProvider participantProvider;
private final MonitoringProvider monitoringProvider;
+ private final PolicyModelsProvider modelsProvider;
// Publishers for participant communication
private final ControlLoopUpdatePublisher controlLoopUpdatePublisher;
case UNINITIALISED2PASSIVE:
case PASSIVE:
controlLoop.setState(ControlLoopState.PASSIVE2UNINITIALISED);
- controlLoopStateChangePublisher.send(controlLoop);
+ controlLoopStateChangePublisher.send(controlLoop, getFirstStartPhase(controlLoop));
break;
case PASSIVE2UNINITIALISED:
case RUNNING:
controlLoop.setState(ControlLoopState.RUNNING2PASSIVE);
- controlLoopStateChangePublisher.send(controlLoop);
+ controlLoopStateChangePublisher.send(controlLoop, getFirstStartPhase(controlLoop));
break;
default:
case PASSIVE:
controlLoop.setState(ControlLoopState.PASSIVE2RUNNING);
- controlLoopStateChangePublisher.send(controlLoop);
+ controlLoopStateChangePublisher.send(controlLoop, getFirstStartPhase(controlLoop));
break;
default:
}
}
+ private int getFirstStartPhase(ControlLoop controlLoop) {
+ ToscaServiceTemplate toscaServiceTemplate = null;
+ try {
+ toscaServiceTemplate = modelsProvider.getServiceTemplateList(null, null).get(0);
+ } catch (PfModelException e) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "Canont load ToscaServiceTemplate from DB", e);
+ }
+ return ParticipantUtils.getFirstStartPhase(controlLoop, toscaServiceTemplate);
+ }
+
private void checkParticipant(ParticipantMessage participantMessage, ParticipantState participantState,
ParticipantHealthStatus healthStatus) throws ControlLoopException, PfModelException {
if (participantMessage.getParticipantId() == null) {
var completed = true;
var minSpNotCompleted = 1000; // min startPhase not completed
+ var maxSpNotCompleted = 0; // max startPhase not completed
+ var defaultMin = 1000; // min startPhase
+ var defaultMax = 0; // max startPhase
for (ControlLoopElement element : controlLoop.getElements().values()) {
+ ToscaNodeTemplate toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates()
+ .get(element.getDefinition().getName());
+ int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties());
+ defaultMin = Math.min(defaultMin, startPhase);
+ defaultMax = Math.max(defaultMax, startPhase);
if (!element.getState().equals(element.getOrderedState().asState())) {
completed = false;
- ToscaNodeTemplate toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates()
- .get(element.getDefinition().getName());
- int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties());
minSpNotCompleted = Math.min(minSpNotCompleted, startPhase);
+ maxSpNotCompleted = Math.max(maxSpNotCompleted, startPhase);
}
}
LOGGER.debug("control loop scan: transition from state {} to {} not completed", controlLoop.getState(),
controlLoop.getOrderedState());
- if (minSpNotCompleted != phaseMap.getOrDefault(controlLoop.getKey().asIdentifier(), 0)
- && ControlLoopState.UNINITIALISED2PASSIVE.equals(controlLoop.getState())) {
- phaseMap.put(controlLoop.getKey().asIdentifier(), minSpNotCompleted);
- sendControlLoopMsg(controlLoop, minSpNotCompleted);
+ var nextSpNotCompleted = ControlLoopState.UNINITIALISED2PASSIVE.equals(controlLoop.getState())
+ || ControlLoopState.PASSIVE2RUNNING.equals(controlLoop.getState()) ? minSpNotCompleted
+ : maxSpNotCompleted;
+
+ var firstStartPhase = ControlLoopState.UNINITIALISED2PASSIVE.equals(controlLoop.getState())
+ || ControlLoopState.PASSIVE2RUNNING.equals(controlLoop.getState()) ? defaultMin
+ : defaultMax;
+
+ if (nextSpNotCompleted != phaseMap.getOrDefault(controlLoop.getKey().asIdentifier(), firstStartPhase)) {
+ phaseMap.put(controlLoop.getKey().asIdentifier(), nextSpNotCompleted);
+ sendControlLoopMsg(controlLoop, nextSpNotCompleted);
} else if (counterCheck) {
- handleCounter(controlLoop, minSpNotCompleted);
+ phaseMap.put(controlLoop.getKey().asIdentifier(), nextSpNotCompleted);
+ handleCounter(controlLoop, nextSpNotCompleted);
}
}
}
controlLoopUpdatePublisher.send(controlLoop, startPhase);
} else {
LOGGER.debug("retry message ControlLoopStateChange");
- controlLoopStateChangePublisher.send(controlLoop);
+ controlLoopStateChangePublisher.send(controlLoop, startPhase);
}
}
}
* Send ControlLoopStateChange to Participant.
*
* @param controlLoop the ControlLoop
+ * @param startPhase the startPhase
*/
- public void send(ControlLoop controlLoop) {
+ public void send(ControlLoop controlLoop, int startPhase) {
var clsc = new ControlLoopStateChange();
clsc.setControlLoopId(controlLoop.getKey().asIdentifier());
clsc.setMessageId(UUID.randomUUID());
clsc.setOrderedState(controlLoop.getOrderedState());
+ clsc.setStartPhase(startPhase);
super.send(clsc);
}
var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
- supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
+ var modelsProvider = Mockito.mock(PolicyModelsProvider.class);
+
+ supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider, modelsProvider,
controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
participantDeregisterAckPublisher, participantUpdatePublisher);
}
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.provider.PolicyModelsProvider;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
class SupervisionHandlerTest {
+ private static final String TOSCA_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/tosca-for-smoke-testing.yaml";
private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
private static final ToscaConceptIdentifier identifier = new ToscaConceptIdentifier("PMSHInstance0Crud", "1.0.1");
private static final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("ParticipantId", "1.0.0");
when(controlLoopProvider.getControlLoop(eq(identifier))).thenReturn(controlLoop);
- return new SupervisionHandler(controlLoopProvider, participantProvider, monitoringProvider,
+ var modelsProvider = Mockito.mock(PolicyModelsProvider.class);
+ when(modelsProvider.getServiceTemplateList(any(), any()))
+ .thenReturn(List.of(InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)));
+
+ return new SupervisionHandler(controlLoopProvider, participantProvider, monitoringProvider, modelsProvider,
controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
participantDeregisterAckPublisher, participantUpdatePublisher);
import static org.mockito.Mockito.when;
import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
-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.controlloop.concepts.Participant;
import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantStatusReqPublisher;
import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
+import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.provider.PolicyModelsProvider;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
private static final String TOSCA_SERVICE_TEMPLATE_YAML =
"src/test/resources/rest/servicetemplates/tosca-for-smoke-testing.yaml";
+ private static final String CONTROLLOOP_JSON = "src/test/resources/rest/controlloops/ControlLoopsSmoke.json";
+
+ private static PolicyModelsProvider modelsProvider = mock(PolicyModelsProvider.class);
+
+ @BeforeAll
+ public static void setUpBeforeAll() throws Exception {
+ ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ when(modelsProvider.getServiceTemplateList(null, null)).thenReturn(List.of(serviceTemplate));
+ }
@Test
- void testScannerOrderedStateEqualsToState() throws PfModelException {
+ void testScannerOrderedStateEqualsToState() throws PfModelException, CoderException {
var controlLoopProvider = mock(ControlLoopProvider.class);
- var modelsProvider = mock(PolicyModelsProvider.class);
var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
var participantProvider = mock(ParticipantProvider.class);
var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
var clRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
- var controlLoop = new ControlLoop();
- when(controlLoopProvider.getControlLoops(null, null)).thenReturn(List.of(controlLoop));
+ var controlLoops =
+ InstantiationUtils.getControlLoopsFromResource(CONTROLLOOP_JSON, "Crud").getControlLoopList();
+ when(controlLoopProvider.getControlLoops(null, null)).thenReturn(controlLoops);
var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider,
controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider,
}
@Test
- void testScannerOrderedStateDifferentToState() throws PfModelException {
- var controlLoop = new ControlLoop();
- controlLoop.setState(ControlLoopState.UNINITIALISED2PASSIVE);
- controlLoop.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
- controlLoop.setElements(Map.of(UUID.randomUUID(), new ControlLoopElement()));
+ void testScannerOrderedStateDifferentToState() throws PfModelException, CoderException {
+ var controlLoops =
+ InstantiationUtils.getControlLoopsFromResource(CONTROLLOOP_JSON, "Crud").getControlLoopList();
+ controlLoops.get(0).setState(ControlLoopState.UNINITIALISED2PASSIVE);
+ controlLoops.get(0).setOrderedState(ControlLoopOrderedState.UNINITIALISED);
var controlLoopProvider = mock(ControlLoopProvider.class);
- when(controlLoopProvider.getControlLoops(null, null)).thenReturn(List.of(controlLoop));
+ when(controlLoopProvider.getControlLoops(null, null)).thenReturn(controlLoops);
var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
var clRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
- var modelsProvider = mock(PolicyModelsProvider.class);
- when(modelsProvider.getServiceTemplateList(null, null)).thenReturn(List.of(new ToscaServiceTemplate()));
-
var supervisionScanner = new SupervisionScanner(controlLoopProvider, modelsProvider,
controlLoopStateChangePublisher, controlLoopUpdatePublisher, participantProvider,
participantStatusReqPublisher, participantUpdatePublisher, clRuntimeParameterGroup);
participant.setVersion("1.0.0");
when(participantProvider.getParticipants(null, null)).thenReturn(List.of(participant));
- var modelsProvider = mock(PolicyModelsProvider.class);
var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
}
@Test
- void testSendControlLoopMsgUpdate() throws PfModelException {
- var controlLoop = new ControlLoop();
- controlLoop.setState(ControlLoopState.UNINITIALISED2PASSIVE);
- controlLoop.setOrderedState(ControlLoopOrderedState.PASSIVE);
- controlLoop.setElements(Map.of(UUID.randomUUID(),
- createHttpElement(ControlLoopState.UNINITIALISED, ControlLoopOrderedState.PASSIVE)));
+ void testSendControlLoopMsgUpdate() throws PfModelException, CoderException {
+ var controlLoops =
+ InstantiationUtils.getControlLoopsFromResource(CONTROLLOOP_JSON, "Crud").getControlLoopList();
+ controlLoops.get(0).setState(ControlLoopState.UNINITIALISED2PASSIVE);
+ controlLoops.get(0).setOrderedState(ControlLoopOrderedState.PASSIVE);
+ for (var element : controlLoops.get(0).getElements().values()) {
+ if ("org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement"
+ .equals(element.getDefinition().getName())) {
+ element.setOrderedState(ControlLoopOrderedState.PASSIVE);
+ element.setState(ControlLoopState.UNINITIALISED);
+ } else {
+ element.setOrderedState(ControlLoopOrderedState.PASSIVE);
+ element.setState(ControlLoopState.PASSIVE);
+ }
+ }
var controlLoopProvider = mock(ControlLoopProvider.class);
- when(controlLoopProvider.getControlLoops(null, null)).thenReturn(List.of(controlLoop));
-
- ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
- var modelsProvider = mock(PolicyModelsProvider.class);
- when(modelsProvider.getServiceTemplateList(null, null)).thenReturn(List.of(serviceTemplate));
+ when(controlLoopProvider.getControlLoops(null, null)).thenReturn(controlLoops);
var participantProvider = mock(ParticipantProvider.class);
var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
verify(controlLoopUpdatePublisher).send(any(ControlLoop.class), anyInt());
}
- private ControlLoopElement createHttpElement(ControlLoopState state, ControlLoopOrderedState orderedState) {
- var element = new ControlLoopElement();
- element.setDefinition(new ToscaConceptIdentifier(
- "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement", "1.2.3"));
- element.setState(state);
- element.setOrderedState(orderedState);
- element.setParticipantId(new ToscaConceptIdentifier("HttpParticipant0", "1.0.0"));
- element.setParticipantType(
- new ToscaConceptIdentifier("org.onap.k8s.controlloop.HttpControlLoopParticipant", "2.3.4"));
-
- return element;
- }
-
@Test
void testScanParticipant() throws PfModelException {
var controlLoopProvider = mock(ControlLoopProvider.class);
var participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
participantProvider.updateParticipants(List.of(participant));
- var modelsProvider = mock(PolicyModelsProvider.class);
var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
package org.onap.policy.clamp.controlloop.runtime.supervision.comm;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import java.time.Instant;
import java.util.Collections;
+import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
+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.persistence.provider.ClElementStatisticsProvider;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
class SupervisionMessagesTest extends CommonRestController {
+ private static final String NOT_ACTIVE = "Not Active!";
private static final Object lockit = new Object();
private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
private static final String TOPIC = "my-topic";
var monitoringProvider =
new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
+ var modelsProvider = Mockito.mock(PolicyModelsProvider.class);
var controlLoopUpdatePublisher = Mockito.mock(ControlLoopUpdatePublisher.class);
var controlLoopStateChangePublisher = Mockito.mock(ControlLoopStateChangePublisher.class);
var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
- supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider,
+ supervisionHandler = new SupervisionHandler(clProvider, participantProvider, monitoringProvider, modelsProvider,
controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
participantDeregisterAckPublisher, participantUpdatePublisher);
}
}
}
+ @Test
+ void testSendControlLoopStateChangePublisherNotActive() {
+ var publisher = new ControlLoopStateChangePublisher();
+ assertThatThrownBy(() -> publisher.send(getControlLoop(), 0)).hasMessage(NOT_ACTIVE);
+ }
+
+ @Test
+ void testSendControlLoopStateChangePublisher() {
+ var publisher = new ControlLoopStateChangePublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.send(getControlLoop(), 0);
+ verify(topicSink).send(anyString());
+ }
+
+ private ControlLoop getControlLoop() {
+ var controlLoop = new ControlLoop();
+ controlLoop.setName("NAME");
+ controlLoop.setVersion("0.0.1");
+ controlLoop.setState(ControlLoopState.UNINITIALISED);
+ return controlLoop;
+ }
+
private ToscaConceptIdentifier getParticipantId() {
return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
}
--- /dev/null
+{
+ "controlLoopList": [
+ {
+ "name": "PMSHInstance0",
+ "version": "1.0.1",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+ "version": "1.2.3"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "PMSH control loop instance 0",
+ "elements": {
+ "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+ "definition": {
+ "name": "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "participantType": {
+ "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+ "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+ "definition": {
+ "name": "org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+ "version": "2.2.1"
+ },
+ "participantType": {
+ "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+ "version": "2.2.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+ }
+ }
+ },
+ {
+ "name": "PMSHInstance1",
+ "version": "1.0.1",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+ "version": "1.2.3"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "PMSH control loop instance 1",
+ "elements": {
+ "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+ "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "participantType": {
+ "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+ "version": "2.3.4"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+ "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+ "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "participantType": {
+ "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+ "version": "2.3.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+ },
+ "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+ "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+ "definition": {
+ "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+ "version": "1.2.3"
+ },
+ "participantId": {
+ "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+ "version": "2.2.1"
+ },
+ "participantType": {
+ "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+ "version": "2.2.1"
+ },
+ "state": "UNINITIALISED",
+ "orderedState": "UNINITIALISED",
+ "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+ }
+ }
+ }
+ ]
+}