Add support participant restart in ACM runtime
Issue-ID: POLICY-4744
Change-Id: I33d31751be7ca5d7c215a2b465564d3ab0c7bee6
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
(cherry picked from commit b13d8dc3a73bc372dabe47ebd88ed1892ee688ea)
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcElementRestart.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcElementRestart.java
new file mode 100644
index 0000000..3815989
--- /dev/null
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcElementRestart.java
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 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.models.acm.concepts;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.UnaryOperator;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+import lombok.ToString;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+@NoArgsConstructor
+@Data
+@ToString
+public class AcElementRestart {
+
+ @NonNull
+ private UUID id = UUID.randomUUID();
+
+ @NonNull
+ private ToscaConceptIdentifier definition = new ToscaConceptIdentifier(PfConceptKey.getNullKey());
+
+ // State of the AutomationCompositionElement
+ private DeployState deployState;
+
+ // State of the AutomationCompositionElement
+ private LockState lockState;
+
+ private ToscaServiceTemplate toscaServiceTemplateFragment;
+
+ // A map indexed by the property name. Each map entry is the serialized value of the property,
+ // which can be deserialized into an instance of the type of the property.
+ private Map<String, Object> properties = new LinkedHashMap<>();
+
+ /**
+ * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy.
+ *
+ * @param otherElement the other element to copy from
+ */
+ public AcElementRestart(final AcElementRestart otherElement) {
+ this.id = otherElement.id;
+ this.definition = new ToscaConceptIdentifier(otherElement.definition);
+ this.deployState = otherElement.deployState;
+ this.lockState = otherElement.lockState;
+ this.toscaServiceTemplateFragment = otherElement.toscaServiceTemplateFragment;
+ this.properties = PfUtils.mapMap(otherElement.properties, UnaryOperator.identity());
+ }
+
+}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcTypeState.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcTypeState.java
index 8e36f7a..76851b4 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcTypeState.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/AcTypeState.java
@@ -25,6 +25,5 @@
COMMISSIONED,
PRIMING,
PRIMED,
- DEPRIMING,
- RESTARTING
+ DEPRIMING
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java
index b8ee020..e5f4ad4 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantRestartAc.java
@@ -37,11 +37,7 @@
private UUID automationCompositionId;
- // current state of auto composition
- private DeployState deployState;
- private LockState lockState;
-
- private List<AcElementDeploy> acElementList = new ArrayList<>();
+ private List<AcElementRestart> acElementList = new ArrayList<>();
/**
* Copy constructor.
@@ -50,8 +46,6 @@
*/
public ParticipantRestartAc(ParticipantRestartAc copyConstructor) {
this.automationCompositionId = copyConstructor.automationCompositionId;
- this.deployState = copyConstructor.deployState;
- this.lockState = copyConstructor.lockState;
- this.acElementList = PfUtils.mapList(copyConstructor.acElementList, AcElementDeploy::new);
+ this.acElementList = PfUtils.mapList(copyConstructor.acElementList, AcElementRestart::new);
}
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestart.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestart.java
index 6b801ce..c86a3e4 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestart.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestart.java
@@ -25,6 +25,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
import org.onap.policy.models.base.PfUtils;
@@ -34,11 +35,14 @@
@ToString(callSuper = true)
public class ParticipantRestart extends ParticipantMessage {
- // priming
+ // composition state
+ AcTypeState state;
+
+ // element definition
private List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
- // autocomposition list
- private List<ParticipantRestartAc> autocompositionList = new ArrayList<>();
+ // automationcomposition instances list
+ private List<ParticipantRestartAc> automationcompositionList = new ArrayList<>();
/**
* Constructor.
@@ -56,6 +60,6 @@
super(source);
this.participantDefinitionUpdates =
PfUtils.mapList(source.participantDefinitionUpdates, ParticipantDefinition::new);
- this.autocompositionList = PfUtils.mapList(source.autocompositionList, ParticipantRestartAc::new);
+ this.automationcompositionList = PfUtils.mapList(source.automationcompositionList, ParticipantRestartAc::new);
}
}
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java
index ee8e010..ae49ec6 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java
@@ -36,6 +36,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
@@ -426,4 +427,19 @@
return acElementDeploy;
}
+ /**
+ * Create a new AcElementRestart from an AutomationCompositionElement.
+ *
+ * @param element the AutomationCompositionElement
+ * @return the AcElementRestart
+ */
+ public static AcElementRestart createAcElementRestart(AutomationCompositionElement element) {
+ var acElementRestart = new AcElementRestart();
+ acElementRestart.setId(element.getId());
+ acElementRestart.setDefinition(new ToscaConceptIdentifier(element.getDefinition()));
+ acElementRestart.setDeployState(element.getDeployState());
+ acElementRestart.setLockState(element.getLockState());
+ acElementRestart.setProperties(PfUtils.mapMap(element.getProperties(), UnaryOperator.identity()));
+ return acElementRestart;
+ }
}
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestartTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestartTest.java
index 1ae607e..ba84ac7 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestartTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantRestartTest.java
@@ -29,9 +29,7 @@
import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.Test;
-import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
-import org.onap.policy.clamp.models.acm.concepts.DeployState;
-import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
import org.onap.policy.clamp.models.acm.utils.CommonTestData;
@@ -60,7 +58,7 @@
participantDefinitionUpdate.setAutomationCompositionElementDefinitionList(List.of(acDefinition));
orig.setParticipantDefinitionUpdates(List.of(participantDefinitionUpdate));
- var acElement = new AcElementDeploy();
+ var acElement = new AcElementRestart();
acElement.setId(UUID.randomUUID());
var id = new ToscaConceptIdentifier("id", "1.2.3");
acElement.setDefinition(id);
@@ -68,10 +66,8 @@
var acRestart = new ParticipantRestartAc();
acRestart.setAcElementList(List.of(acElement));
acRestart.setAutomationCompositionId(UUID.randomUUID());
- acRestart.setDeployState(DeployState.DEPLOYED);
- acRestart.setLockState(LockState.LOCKED);
- orig.setAutocompositionList(List.of(acRestart));
+ orig.setAutomationcompositionList(List.of(acRestart));
assertEquals(removeVariableFields(orig.toString()),
removeVariableFields(new ParticipantRestart(orig).toString()));
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java
index 7e8f605..a9bd25f 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java
@@ -66,6 +66,8 @@
assertThat(AcmUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE)).isTrue();
assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING)).isTrue();
assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING)).isTrue();
+ assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE)).isTrue();
+ assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED)).isTrue();
}
@Test
@@ -192,6 +194,16 @@
assertEquals(element.getDefinition(), result.getDefinition());
}
+ @Test
+ void testCreateAcElementRestart() {
+ var element = getDummyAutomationComposition().getElements().values().iterator().next();
+ var result = AcmUtils.createAcElementRestart(element);
+ assertEquals(element.getId(), result.getId());
+ assertEquals(element.getDefinition(), result.getDefinition());
+ assertEquals(element.getDeployState(), result.getDeployState());
+ assertEquals(element.getLockState(), result.getLockState());
+ }
+
private AutomationComposition getDummyAutomationComposition() {
var automationComposition = new AutomationComposition();
automationComposition.setCompositionId(UUID.randomUUID());
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java
index c79e317..961f12a 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java
@@ -130,7 +130,7 @@
var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
if (!AcTypeState.COMMISSIONED.equals(acDefinition.getState())) {
throw new PfModelRuntimeException(Status.BAD_REQUEST,
- "ACM not in COMMISSIONED state, Update of ACM Definition not allowed");
+ "ACM not in COMMISSIONED state, Delete of ACM Definition not allowed");
}
var serviceTemplate = acDefinitionProvider.deleteAcDefintion(compositionId);
return createCommissioningResponse(compositionId, serviceTemplate);
@@ -184,6 +184,10 @@
throw new PfModelRuntimeException(Status.BAD_REQUEST, "There are instances, Priming/Depriming not allowed");
}
var acmDefinition = acDefinitionProvider.getAcDefinition(compositionId);
+ if (acmDefinition.getRestarting() != null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
+ "There is a restarting process, Priming/Depriming not allowed");
+ }
var stateOrdered = acTypeStateResolver.resolve(acTypeStateUpdate.getPrimeOrder(), acmDefinition.getState(),
acmDefinition.getStateChangeResult());
switch (stateOrdered) {
@@ -220,7 +224,7 @@
participantIds.add(participantId);
}
}
- if (! participantIds.isEmpty()) {
+ if (!participantIds.isEmpty()) {
acmParticipantProvider.verifyParticipantState(participantIds);
}
acmDefinition.setState(AcTypeState.DEPRIMING);
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
index ab3b00d..710a975 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
@@ -155,6 +155,9 @@
.putAll(automationComposition.getElements().get(elementId).getProperties());
}
}
+ if (automationComposition.getRestarting() != null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed");
+ }
var validationResult = validateAutomationComposition(acToBeUpdated);
if (!validationResult.isValid()) {
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
@@ -187,10 +190,16 @@
return result;
}
if (!AcTypeState.PRIMED.equals(acDefinitionOpt.get().getState())) {
- result.addResult(new ObjectValidationResult("ServiceTemplate", acDefinitionOpt.get().getState(),
+ result.addResult(new ObjectValidationResult("ServiceTemplate.state", acDefinitionOpt.get().getState(),
ValidationStatus.INVALID, "Commissioned automation composition definition not primed"));
return result;
}
+ if (acDefinitionOpt.get().getRestarting() != null) {
+ result.addResult(
+ new ObjectValidationResult("ServiceTemplate.restarting", acDefinitionOpt.get().getRestarting(),
+ ValidationStatus.INVALID, "There is a restarting process in composition"));
+ return result;
+ }
var participantIds = acDefinitionOpt.get().getElementStateMap().values().stream()
.map(NodeTemplateState::getParticipantId).collect(Collectors.toSet());
@@ -245,8 +254,10 @@
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
"Automation composition state is still " + automationComposition.getDeployState());
}
- var acDefinition = acDefinitionProvider
- .getAcDefinition(automationComposition.getCompositionId());
+ if (automationComposition.getRestarting() != null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Delete not allowed");
+ }
+ var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
if (acDefinition != null) {
var participantIds = acDefinition.getElementStateMap().values().stream()
.map(NodeTemplateState::getParticipantId).collect(Collectors.toSet());
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
index 536e3e2..5a2079b 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
@@ -22,6 +22,7 @@
import io.micrometer.core.annotation.Timed;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import lombok.AllArgsConstructor;
@@ -31,6 +32,7 @@
import org.onap.policy.clamp.models.acm.concepts.AcElementDeployAck;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
@@ -78,8 +80,8 @@
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
automationCompositionProvider.updateAutomationComposition(automationComposition);
var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
- automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(),
- startPhase, true);
+ automationCompositionDeployPublisher.send(automationComposition, acDefinition.getServiceTemplate(), startPhase,
+ true);
}
/**
@@ -261,9 +263,19 @@
element.setUseState(acElementAck.getValue().getUseState());
element.setDeployState(acElementAck.getValue().getDeployState());
element.setLockState(acElementAck.getValue().getLockState());
+ element.setRestarting(null);
updated = true;
}
}
+
+ if (automationComposition.getRestarting() != null) {
+ var restarting = automationComposition.getElements().values().stream()
+ .map(AutomationCompositionElement::getRestarting).filter(Objects::nonNull).findAny();
+ if (restarting.isEmpty()) {
+ automationComposition.setRestarting(null);
+ }
+ }
+
return updated;
}
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java
index 7303fc8..079f218 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java
@@ -68,13 +68,13 @@
public void doCheck() {
if (executor.getQueue().size() < 2) {
LOGGER.debug("Add scanning Message");
- executor.execute(() -> supervisionScanner.run());
+ executor.execute(supervisionScanner::run);
}
}
- @Before("@annotation(MessageIntercept) && args(participantStatusMessage,..)")
- public void handleParticipantStatus(ParticipantStatus participantStatusMessage) {
- executor.execute(() -> partecipantScanner.handleParticipantStatus(participantStatusMessage.getParticipantId()));
+ @Before("@annotation(MessageIntercept) && args(participantStatusMsg,..)")
+ public void handleParticipantStatus(ParticipantStatus participantStatusMsg) {
+ executor.execute(() -> partecipantScanner.handleParticipantStatus(participantStatusMsg.getParticipantId()));
}
@Override
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
index a18ea19..4f58801 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
@@ -58,7 +58,7 @@
}
var acDefinition = acDefinitionOpt.get();
if (!AcTypeState.PRIMING.equals(acDefinition.getState())
- && !AcTypeState.DEPRIMING.equals(acDefinition.getState())) {
+ && !AcTypeState.DEPRIMING.equals(acDefinition.getState()) && acDefinition.getRestarting() == null) {
LOGGER.error("AC Definition {} already primed/deprimed with participant {}",
participantPrimeAckMessage.getCompositionId(), participantPrimeAckMessage.getParticipantId());
return;
@@ -68,8 +68,8 @@
private void handleParticipantPrimeAck(ParticipantPrimeAck participantPrimeAckMessage,
AutomationCompositionDefinition acDefinition) {
- var finalState =
- AcTypeState.PRIMING.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
+ var finalState = AcTypeState.PRIMING.equals(acDefinition.getState())
+ || AcTypeState.PRIMED.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
var msgInErrors = StateChangeResult.FAILED.equals(participantPrimeAckMessage.getStateChangeResult());
boolean inProgress = !StateChangeResult.FAILED.equals(acDefinition.getStateChangeResult());
if (inProgress && msgInErrors) {
@@ -77,14 +77,19 @@
}
boolean completed = true;
+ boolean restarting = false;
for (var element : acDefinition.getElementStateMap().values()) {
if (participantPrimeAckMessage.getParticipantId().equals(element.getParticipantId())) {
element.setMessage(participantPrimeAckMessage.getMessage());
element.setState(participantPrimeAckMessage.getCompositionState());
+ element.setRestarting(null);
}
if (!finalState.equals(element.getState())) {
completed = false;
}
+ if (element.getRestarting() != null) {
+ restarting = true;
+ }
}
if (inProgress && !msgInErrors && completed) {
@@ -92,7 +97,9 @@
if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) {
acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
}
-
+ }
+ if (!restarting) {
+ acDefinition.setRestarting(null);
}
acDefinitionProvider.updateAcDefinition(acDefinition);
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java
index 092fc35..c07c584 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionPartecipantScanner.java
@@ -46,9 +46,8 @@
* @param participantProvider the Participant Provider
* @param acRuntimeParameterGroup the parameters for the automation composition runtime
*/
- public SupervisionPartecipantScanner(
- final ParticipantProvider participantProvider,
- final AcRuntimeParameterGroup acRuntimeParameterGroup) {
+ public SupervisionPartecipantScanner(final ParticipantProvider participantProvider,
+ final AcRuntimeParameterGroup acRuntimeParameterGroup) {
this.participantProvider = participantProvider;
participantStatusTimeout.setMaxWaitMs(acRuntimeParameterGroup.getParticipantParameters().getMaxStatusWaitMs());
@@ -70,11 +69,17 @@
private void scanParticipantStatus(Participant participant) {
var id = participant.getParticipantId();
if (participantStatusTimeout.isTimeout(id)) {
- LOGGER.debug("report Participant fault");
- return;
+ if (ParticipantState.ON_LINE.equals(participant.getParticipantState())) {
+ // restart scenario
+ LOGGER.debug("Participant is back ON_LINE {}", id);
+ participantStatusTimeout.clear(id);
+ } else {
+ LOGGER.debug("report Participant is still OFF_LINE {}", id);
+ return;
+ }
}
if (participantStatusTimeout.getDuration(id) > participantStatusTimeout.getMaxWaitMs()) {
- LOGGER.debug("report Participant fault");
+ LOGGER.debug("report Participant OFF_LINE {}", id);
participantStatusTimeout.setTimeout(id);
participant.setParticipantState(ParticipantState.OFF_LINE);
participantProvider.updateParticipant(participant);
@@ -85,6 +90,7 @@
* handle participant Status message.
*/
public void handleParticipantStatus(UUID id) {
+ LOGGER.debug("Participant is ON_LINE {}", id);
participantStatusTimeout.clear(id);
}
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
index 6d43803..e0d11ed 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java
@@ -21,6 +21,7 @@
package org.onap.policy.clamp.acm.runtime.supervision;
import io.micrometer.core.annotation.Timed;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,13 +30,18 @@
import org.apache.commons.collections4.MapUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRestartPublisher;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
import org.onap.policy.clamp.models.acm.concepts.Participant;
import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister;
-import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessage;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
import org.slf4j.Logger;
@@ -54,6 +60,8 @@
private final ParticipantRegisterAckPublisher participantRegisterAckPublisher;
private final ParticipantDeregisterAckPublisher participantDeregisterAckPublisher;
private final AutomationCompositionProvider automationCompositionProvider;
+ private final AcDefinitionProvider acDefinitionProvider;
+ private final ParticipantRestartPublisher participantRestartPublisher;
/**
* Handle a ParticipantRegister message from a participant.
@@ -64,11 +72,24 @@
@Timed(value = "listener.participant_register", description = "PARTICIPANT_REGISTER messages received")
public void handleParticipantMessage(ParticipantRegister participantRegisterMsg) {
LOGGER.debug("Participant Register received {}", participantRegisterMsg);
- saveParticipantStatus(participantRegisterMsg,
- listToMap(participantRegisterMsg.getParticipantSupportedElementType()));
+ var participantOpt = participantProvider.findParticipant(participantRegisterMsg.getParticipantId());
+
+ if (participantOpt.isPresent()) {
+ var participant = participantOpt.get();
+ if (ParticipantState.OFF_LINE.equals(participant.getParticipantState())) {
+ participant.setParticipantState(ParticipantState.ON_LINE);
+ participantProvider.saveParticipant(participant);
+ }
+ handleRestart(participant.getParticipantId());
+ } else {
+ var participant = createParticipant(participantRegisterMsg.getParticipantId(),
+ listToMap(participantRegisterMsg.getParticipantSupportedElementType()));
+ participantProvider.saveParticipant(participant);
+
+ }
participantRegisterAckPublisher.send(participantRegisterMsg.getMessageId(),
- participantRegisterMsg.getParticipantId());
+ participantRegisterMsg.getParticipantId());
}
/**
@@ -100,32 +121,83 @@
@Timed(value = "listener.participant_status", description = "PARTICIPANT_STATUS messages received")
public void handleParticipantMessage(ParticipantStatus participantStatusMsg) {
LOGGER.debug("Participant Status received {}", participantStatusMsg);
- saveParticipantStatus(participantStatusMsg,
- listToMap(participantStatusMsg.getParticipantSupportedElementType()));
+
+ var participantOpt = participantProvider.findParticipant(participantStatusMsg.getParticipantId());
+ if (participantOpt.isEmpty()) {
+ var participant = createParticipant(participantStatusMsg.getParticipantId(),
+ listToMap(participantStatusMsg.getParticipantSupportedElementType()));
+ participantProvider.saveParticipant(participant);
+ }
if (!participantStatusMsg.getAutomationCompositionInfoList().isEmpty()) {
automationCompositionProvider.upgradeStates(participantStatusMsg.getAutomationCompositionInfoList());
}
}
- private void saveParticipantStatus(ParticipantMessage participantMessage,
- Map<UUID, ParticipantSupportedElementType> participantSupportedElementType) {
- var participantOpt = participantProvider.findParticipant(participantMessage.getParticipantId());
-
- if (participantOpt.isEmpty()) {
- var participant = new Participant();
- participant.setParticipantId(participantMessage.getParticipantId());
- participant.setParticipantSupportedElementTypes(participantSupportedElementType);
- participant.setParticipantState(ParticipantState.ON_LINE);
-
- participantProvider.saveParticipant(participant);
- } else {
- var participant = participantOpt.get();
- participant.setParticipantState(ParticipantState.ON_LINE);
-
- participantProvider.updateParticipant(participant);
+ private void handleRestart(UUID participantId) {
+ var compositionIds = participantProvider.getCompositionIds(participantId);
+ for (var compositionId : compositionIds) {
+ var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
+ LOGGER.debug("Scan Composition {} for restart", acDefinition.getCompositionId());
+ handleRestart(participantId, acDefinition);
}
}
+ private void handleRestart(UUID participantId, AutomationCompositionDefinition acDefinition) {
+ if (AcTypeState.COMMISSIONED.equals(acDefinition.getState())) {
+ LOGGER.debug("Composition {} COMMISSIONED", acDefinition.getCompositionId());
+ return;
+ }
+ LOGGER.debug("Composition to be send in Restart message {}", acDefinition.getCompositionId());
+ for (var elementState : acDefinition.getElementStateMap().values()) {
+ if (participantId.equals(elementState.getParticipantId())) {
+ elementState.setRestarting(true);
+ }
+ }
+ var automationCompositionList =
+ automationCompositionProvider.getAcInstancesByCompositionId(acDefinition.getCompositionId());
+ List<AutomationComposition> automationCompositions = new ArrayList<>();
+ for (var automationComposition : automationCompositionList) {
+ if (isAcToBeRestarted(participantId, automationComposition)) {
+ automationCompositions.add(automationComposition);
+ }
+ }
+ // expected final state
+ if (StateChangeResult.TIMEOUT.equals(acDefinition.getStateChangeResult())) {
+ acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ }
+ acDefinition.setRestarting(true);
+ acDefinitionProvider.updateAcDefinition(acDefinition);
+ participantRestartPublisher.send(participantId, acDefinition, automationCompositions);
+ }
+
+ private boolean isAcToBeRestarted(UUID participantId, AutomationComposition automationComposition) {
+ boolean toAdd = false;
+ for (var element : automationComposition.getElements().values()) {
+ if (participantId.equals(element.getParticipantId())) {
+ element.setRestarting(true);
+ toAdd = true;
+ }
+ }
+ if (toAdd) {
+ automationComposition.setRestarting(true);
+ // expected final state
+ if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
+ automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ }
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ }
+ return toAdd;
+ }
+
+ private Participant createParticipant(UUID participantId,
+ Map<UUID, ParticipantSupportedElementType> participantSupportedElementType) {
+ var participant = new Participant();
+ participant.setParticipantId(participantId);
+ participant.setParticipantSupportedElementTypes(participantSupportedElementType);
+ participant.setParticipantState(ParticipantState.ON_LINE);
+ return participant;
+ }
+
private Map<UUID, ParticipantSupportedElementType> listToMap(List<ParticipantSupportedElementType> elementList) {
Map<UUID, ParticipantSupportedElementType> map = new HashMap<>();
MapUtils.populateMap(map, elementList, ParticipantSupportedElementType::getId);
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java
index cb00c8e..b086b19 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantRestartPublisher.java
@@ -34,7 +34,6 @@
import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRestart;
-import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.utils.AcmUtils;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
@@ -51,6 +50,9 @@
/**
* Send Restart to Participant.
*
+ * @param participantId the ParticipantId
+ * @param acmDefinition the AutomationComposition Definition
+ * @param automationCompositions the list of automationCompositions
*/
@Timed(value = "publisher.participant_restart", description = "Participant Restart published")
public void send(UUID participantId, AutomationCompositionDefinition acmDefinition,
@@ -61,21 +63,21 @@
message.setCompositionId(acmDefinition.getCompositionId());
message.setMessageId(UUID.randomUUID());
message.setTimestamp(Instant.now());
+ message.setState(acmDefinition.getState());
message.setParticipantDefinitionUpdates(prepareParticipantRestarting(participantId, acmDefinition));
+ var toscaServiceTemplateFragment = AcmUtils.getToscaServiceTemplateFragment(acmDefinition.getServiceTemplate());
for (var automationComposition : automationCompositions) {
var restartAc = new ParticipantRestartAc();
restartAc.setAutomationCompositionId(automationComposition.getInstanceId());
- restartAc.setDeployState(automationComposition.getDeployState());
- restartAc.setLockState(automationComposition.getLockState());
for (var element : automationComposition.getElements().values()) {
if (participantId.equals(element.getParticipantId())) {
- var acElementDeploy = AcmUtils.createAcElementDeploy(element, DeployOrder.RESTARTING);
- acElementDeploy.setToscaServiceTemplateFragment(acmDefinition.getServiceTemplate());
- restartAc.getAcElementList().add(acElementDeploy);
+ var acElementRestart = AcmUtils.createAcElementRestart(element);
+ acElementRestart.setToscaServiceTemplateFragment(toscaServiceTemplateFragment);
+ restartAc.getAcElementList().add(acElementRestart);
}
}
- message.getAutocompositionList().add(restartAc);
+ message.getAutomationcompositionList().add(restartAc);
}
LOGGER.debug("Participant Restart sent {}", message);
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
index 08d20ba..d7c79bc 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
@@ -188,4 +188,57 @@
provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate);
verify(participantPrimePublisher, timeout(1000).times(1)).sendDepriming(compositionId);
}
+
+ @Test
+ void testBadRequest() {
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var provider = new CommissioningProvider(mock(AcDefinitionProvider.class), acProvider,
+ mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class));
+
+ var compositionId = UUID.randomUUID();
+ when(acProvider.getAcInstancesByCompositionId(compositionId)).thenReturn(List.of(new AutomationComposition()));
+
+ var toscaServiceTemplate = new ToscaServiceTemplate();
+ assertThatThrownBy(() -> provider.updateCompositionDefinition(compositionId, toscaServiceTemplate))
+ .hasMessageMatching("There are ACM instances, Update of ACM Definition not allowed");
+
+ var acTypeStateUpdate = new AcTypeStateUpdate();
+ assertThatThrownBy(() -> provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate))
+ .hasMessageMatching("There are instances, Priming/Depriming not allowed");
+ }
+
+ @Test
+ void testPrimedBadRequest() {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var toscaServiceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ var acmDefinition = CommonTestData.createAcDefinition(toscaServiceTemplate, AcTypeState.PRIMED);
+ var compositionId = acmDefinition.getCompositionId();
+ when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition);
+
+ var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class),
+ mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class));
+
+ assertThatThrownBy(() -> provider.updateCompositionDefinition(compositionId, toscaServiceTemplate))
+ .hasMessageMatching("ACM not in COMMISSIONED state, Update of ACM Definition not allowed");
+
+ assertThatThrownBy(() -> provider.deleteAutomationCompositionDefinition(compositionId))
+ .hasMessageMatching("ACM not in COMMISSIONED state, Delete of ACM Definition not allowed");
+ }
+
+ @Test
+ void testPrimingBadRequest() {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var toscaServiceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ var acmDefinition = CommonTestData.createAcDefinition(toscaServiceTemplate, AcTypeState.PRIMED);
+ acmDefinition.setRestarting(true);
+ var compositionId = acmDefinition.getCompositionId();
+ when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition);
+
+ var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class),
+ mock(AcmParticipantProvider.class), new AcTypeStateResolver(), mock(ParticipantPrimePublisher.class));
+
+ var acTypeStateUpdate = new AcTypeStateUpdate();
+ assertThatThrownBy(() -> provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate))
+ .hasMessageMatching("There is a restarting process, Priming/Depriming not allowed");
+ }
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
index 13da979..3ac2efc 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
@@ -145,6 +145,115 @@
}
@Test
+ void testInstantiationUpdate() throws AutomationCompositionException {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
+
+ var automationCompositionUpdate =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationCompositionUpdate.setCompositionId(compositionId);
+ automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
+ automationCompositionUpdate.setLockState(LockState.LOCKED);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
+ .thenReturn(automationCompositionUpdate);
+ when(acProvider.updateAutomationComposition(automationCompositionUpdate))
+ .thenReturn(automationCompositionUpdate);
+
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var acmParticipantProvider = mock(AcmParticipantProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, supervisionAcHandler, acmParticipantProvider);
+ var instantiationResponse = instantiationProvider.updateAutomationComposition(
+ automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
+
+ verify(supervisionAcHandler).update(any());
+ verify(acProvider).updateAutomationComposition(automationCompositionUpdate);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionUpdate);
+ }
+
+ @Test
+ void testUpdateBadRequest() throws AutomationCompositionException {
+ var automationCompositionUpdate =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationCompositionUpdate.setDeployState(DeployState.DEPLOYING);
+ automationCompositionUpdate.setLockState(LockState.NONE);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
+ .thenReturn(automationCompositionUpdate);
+
+ var instantiationProvider =
+ new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null,
+ mock(SupervisionAcHandler.class), mock(AcmParticipantProvider.class));
+
+ var compositionId = automationCompositionUpdate.getCompositionId();
+ assertThatThrownBy(
+ () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
+ .hasMessageMatching(
+ "Not allowed to update in the state " + automationCompositionUpdate.getDeployState());
+ }
+
+ @Test
+ void testUpdateRestartedBadRequest() throws AutomationCompositionException {
+ var automationCompositionUpdate =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
+ automationCompositionUpdate.setLockState(LockState.LOCKED);
+ automationCompositionUpdate.setRestarting(true);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
+ .thenReturn(automationCompositionUpdate);
+
+ var instantiationProvider =
+ new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null,
+ mock(SupervisionAcHandler.class), mock(AcmParticipantProvider.class));
+
+ var compositionId = automationCompositionUpdate.getCompositionId();
+ assertThatThrownBy(
+ () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
+ .hasMessageMatching("There is a restarting process, Update not allowed");
+
+ automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED);
+ automationCompositionUpdate.setLockState(LockState.NONE);
+
+ var instanceId = automationCompositionUpdate.getInstanceId();
+ assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(compositionId, instanceId))
+ .hasMessageMatching("There is a restarting process, Delete not allowed");
+ }
+
+ @Test
+ void testUpdateCompositionRestartedBadRequest() throws AutomationCompositionException {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ acDefinition.setRestarting(true);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
+
+ var automationCompositionUpdate =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationCompositionUpdate.setCompositionId(compositionId);
+ automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
+ automationCompositionUpdate.setLockState(LockState.LOCKED);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
+ .thenReturn(automationCompositionUpdate);
+ when(acProvider.updateAutomationComposition(automationCompositionUpdate))
+ .thenReturn(automationCompositionUpdate);
+
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var acmParticipantProvider = mock(AcmParticipantProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, supervisionAcHandler, acmParticipantProvider);
+ assertThatThrownBy(
+ () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
+ .hasMessageMatching("\"AutomationComposition\" INVALID, item has status INVALID\n"
+ + " item \"ServiceTemplate.restarting\" value \"true\" INVALID,"
+ + " There is a restarting process in composition\n");
+ }
+
+ @Test
void testInstantiationDelete() {
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
@@ -154,8 +263,8 @@
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var acmParticipantProvider = mock(AcmParticipantProvider.class);
- var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, null, supervisionAcHandler, acmParticipantProvider);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, supervisionAcHandler, acmParticipantProvider);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
@@ -178,15 +287,15 @@
verify(supervisionAcHandler).delete(any(), any());
}
- private void assertThatDeleteThrownBy(AutomationComposition automationComposition,
- DeployState deployState, LockState lockState) {
+ private void assertThatDeleteThrownBy(AutomationComposition automationComposition, DeployState deployState,
+ LockState lockState) {
automationComposition.setDeployState(deployState);
automationComposition.setLockState(lockState);
var acProvider = mock(AutomationCompositionProvider.class);
var acDefinitionProvider = mock(AcDefinitionProvider.class);
- var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, null, null, null);
+ var instantiationProvider =
+ new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null, null);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
@@ -214,8 +323,8 @@
.thenReturn(automationCompositionCreate);
var acmParticipantProvider = mock(AcmParticipantProvider.class);
- var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, null, null, acmParticipantProvider);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, null, acmParticipantProvider);
var instantiationResponse = instantiationProvider.createAutomationComposition(
automationCompositionCreate.getCompositionId(), automationCompositionCreate);
@@ -241,8 +350,8 @@
automationComposition.setCompositionId(compositionId);
var acProvider = mock(AutomationCompositionProvider.class);
- var provider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, null, null, acmParticipantProvider);
+ var provider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null,
+ acmParticipantProvider);
assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
.hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
@@ -262,8 +371,8 @@
var acProvider = mock(AutomationCompositionProvider.class);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
- var provider = new AutomationCompositionInstantiationProvider(acProvider,
- mock(AcDefinitionProvider.class), null, null, null);
+ var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
+ null, null, null);
var compositionId = automationComposition.getCompositionId();
assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
@@ -281,8 +390,8 @@
var acProvider = mock(AutomationCompositionProvider.class);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
- var provider = new AutomationCompositionInstantiationProvider(acProvider,
- mock(AcDefinitionProvider.class), null, null, null);
+ var provider = new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
+ null, null, null);
var compositionId = automationComposition.getCompositionId();
var wrongCompositionId = UUID.randomUUID();
@@ -315,7 +424,7 @@
automationComposition.setCompositionId(compositionId);
assertThatThrownBy(() -> provider.createAutomationComposition(compositionId, automationComposition))
.hasMessageMatching("\"AutomationComposition\" INVALID, item has status INVALID\n"
- + " item \"ServiceTemplate\" value \"COMMISSIONED\" INVALID,"
+ + " item \"ServiceTemplate.state\" value \"COMMISSIONED\" INVALID,"
+ " Commissioned automation composition definition not primed\n");
}
@@ -332,8 +441,7 @@
automationComposition.setCompositionId(compositionId);
automationComposition.setInstanceId(instanceId);
var acProvider = mock(AutomationCompositionProvider.class);
- when(acProvider.getAutomationComposition(instanceId))
- .thenReturn(automationComposition);
+ when(acProvider.getAutomationComposition(instanceId)).thenReturn(automationComposition);
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var acmParticipantProvider = mock(AcmParticipantProvider.class);
@@ -367,7 +475,6 @@
acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
acInstanceStateUpdate.setLockOrder(LockOrder.LOCK);
provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
- verify(supervisionAcHandler).lock(any(AutomationComposition.class),
- any(AutomationCompositionDefinition.class));
+ verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class));
}
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java
index e441bef..ed8a856 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandlerTest.java
@@ -26,22 +26,34 @@
import static org.mockito.Mockito.when;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRestartPublisher;
import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
+import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
+import org.onap.policy.clamp.models.acm.concepts.Participant;
import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
class SupervisionParticipantHandlerTest {
+
+ private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
+
@Test
void testHandleParticipantDeregister() {
var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
@@ -54,9 +66,10 @@
participantDeregisterMessage.setMessageId(UUID.randomUUID());
participantDeregisterMessage.setParticipantId(CommonTestData.getParticipantId());
var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class);
- var handler = new SupervisionParticipantHandler(participantProvider,
- mock(ParticipantRegisterAckPublisher.class), participantDeregisterAckPublisher,
- mock(AutomationCompositionProvider.class));
+ var handler =
+ new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class),
+ participantDeregisterAckPublisher, mock(AutomationCompositionProvider.class),
+ mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class));
handler.handleParticipantMessage(participantDeregisterMessage);
@@ -77,8 +90,8 @@
var participantProvider = mock(ParticipantProvider.class);
var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher,
- mock(ParticipantDeregisterAckPublisher.class),
- mock(AutomationCompositionProvider.class));
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionProvider.class),
+ mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class));
handler.handleParticipantMessage(participantRegisterMessage);
verify(participantProvider).saveParticipant(any());
@@ -87,6 +100,58 @@
}
@Test
+ void testHandleParticipantRestart() {
+ var participantRegisterMessage = new ParticipantRegister();
+ participantRegisterMessage.setMessageId(UUID.randomUUID());
+ var participantId = CommonTestData.getParticipantId();
+ participantRegisterMessage.setParticipantId(participantId);
+ var supportedElementType = new ParticipantSupportedElementType();
+ supportedElementType.setTypeName("Type");
+ supportedElementType.setTypeVersion("1.0.0");
+ participantRegisterMessage.setParticipantSupportedElementType(List.of(supportedElementType));
+
+ var participant = new Participant();
+ participant.setParticipantId(participantId);
+ var participantProvider = mock(ParticipantProvider.class);
+ when(participantProvider.findParticipant(participantId)).thenReturn(Optional.of(participant));
+ var compositionId = UUID.randomUUID();
+ var composition2Id = UUID.randomUUID();
+ when(participantProvider.getCompositionIds(participantId)).thenReturn(Set.of(compositionId, composition2Id));
+
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = new AutomationCompositionDefinition();
+ acDefinition.setState(AcTypeState.COMMISSIONED);
+ acDefinition.setCompositionId(composition2Id);
+ when(acDefinitionProvider.getAcDefinition(composition2Id)).thenReturn(acDefinition);
+
+ acDefinition = new AutomationCompositionDefinition();
+ acDefinition.setCompositionId(compositionId);
+ acDefinition.setState(AcTypeState.PRIMED);
+ var nodeTemplateState = new NodeTemplateState();
+ nodeTemplateState.setParticipantId(participantId);
+ acDefinition.setElementStateMap(Map.of("code", nodeTemplateState));
+ when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition);
+
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
+ automationComposition.getElements().values().iterator().next().setParticipantId(participantId);
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
+ .thenReturn(List.of(automationComposition));
+
+ var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
+ var participantRestartPublisher = mock(ParticipantRestartPublisher.class);
+ var handler = new SupervisionParticipantHandler(participantProvider, participantRegisterAckPublisher,
+ mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider, acDefinitionProvider,
+ participantRestartPublisher);
+ handler.handleParticipantMessage(participantRegisterMessage);
+
+ verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), participantId);
+ verify(acDefinitionProvider).updateAcDefinition(any(AutomationCompositionDefinition.class));
+ verify(participantRestartPublisher).send(any(), any(AutomationCompositionDefinition.class), any());
+ }
+
+ @Test
void testHandleParticipantStatus() {
var participantStatusMessage = new ParticipantStatus();
participantStatusMessage.setParticipantId(CommonTestData.getParticipantId());
@@ -98,14 +163,16 @@
participantStatusMessage.setAutomationCompositionInfoList(List.of(new AutomationCompositionInfo()));
var participantProvider = mock(ParticipantProvider.class);
- var handler = new SupervisionParticipantHandler(participantProvider,
- mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
- mock(AutomationCompositionProvider.class));
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var handler =
+ new SupervisionParticipantHandler(participantProvider, mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), automationCompositionProvider,
+ mock(AcDefinitionProvider.class), mock(ParticipantRestartPublisher.class));
var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
when(participantProvider.findParticipant(CommonTestData.getParticipantId()))
.thenReturn(Optional.of(participant));
handler.handleParticipantMessage(participantStatusMessage);
- verify(participantProvider).updateParticipant(any());
+ verify(automationCompositionProvider).upgradeStates(any());
}
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
index 8de5cca..06684d8 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
@@ -222,6 +222,31 @@
}
@Test
+ void testParticipantRestartPublisher() {
+ var publisher = new ParticipantRestartPublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+
+ var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ // serviceTemplate.setName("Name");
+ // serviceTemplate.setVersion("1.0.0");
+ var acmDefinition = new AutomationCompositionDefinition();
+ acmDefinition.setCompositionId(UUID.randomUUID());
+ acmDefinition.setServiceTemplate(serviceTemplate);
+ var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+ acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.PRIMED));
+
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+
+ var participantId = automationComposition.getElements().values().iterator().next().getParticipantId();
+ acmDefinition.getElementStateMap().values().iterator().next().setParticipantId(participantId);
+
+ publisher.send(participantId, acmDefinition, List.of(automationComposition));
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
void testParticipantRegisterListener() {
final var participantRegister = new ParticipantRegister();
var supervisionHandler = mock(SupervisionParticipantHandler.class);