diff options
author | 2024-07-23 10:22:27 +0100 | |
---|---|---|
committer | 2024-07-23 09:27:30 +0000 | |
commit | 1c144c87fbe077eb471650064c64888c4501f581 (patch) | |
tree | d4fcc2018f0cf78e6495fd1f020edd324bd0480e /runtime-acm | |
parent | af4d49da0f35da5d1086f0181b594dcc772e383d (diff) |
Add support for Prepare, Review and Migrate pre-check in ACM runtime
Issue-ID: POLICY-5079
Change-Id: I6e54d2bce31f906efcc4d5bf3b930d34e7913fd2
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Diffstat (limited to 'runtime-acm')
8 files changed, 418 insertions, 73 deletions
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 2bf08220a..c732654f2 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 @@ -22,7 +22,6 @@ package org.onap.policy.clamp.acm.runtime.instantiation; import jakarta.validation.Valid; -import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import java.util.UUID; import java.util.stream.Collectors; @@ -37,8 +36,12 @@ 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.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; @@ -82,19 +85,19 @@ public class AutomationCompositionInstantiationProvider { public InstantiationResponse createAutomationComposition(UUID compositionId, AutomationComposition automationComposition) { if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } var checkAutomationCompositionOpt = automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()); if (checkAutomationCompositionOpt.isPresent()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getKey().asIdentifier() + " already defined"); } var validationResult = validateAutomationComposition(automationComposition); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition); @@ -120,7 +123,7 @@ public class AutomationCompositionInstantiationProvider { var instanceId = automationComposition.getInstanceId(); var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(acToUpdate.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) { @@ -131,22 +134,42 @@ public class AutomationCompositionInstantiationProvider { acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom()); var validationResult = validateAutomationComposition(acToUpdate); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate); return createInstantiationResponse(automationComposition); - } else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState()) - || DeployState.UPDATING.equals(acToUpdate.getDeployState())) - && LockState.LOCKED.equals(acToUpdate.getLockState())) { - if (automationComposition.getCompositionTargetId() != null) { - return migrateAutomationComposition(automationComposition, acToUpdate); + } + + if (automationComposition.getRestarting() != null) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed"); + } + + var deployOrder = DeployOrder.UPDATE; + var subOrder = SubOrder.NONE; + + if (automationComposition.getCompositionTargetId() != null) { + + if (Boolean.TRUE.equals(automationComposition.getPrecheck())) { + subOrder = SubOrder.MIGRATE_PRECHECK; + deployOrder = DeployOrder.NONE; } else { - return updateDeployedAutomationComposition(automationComposition, acToUpdate); + deployOrder = DeployOrder.MIGRATE; } } - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, - "Not allowed to update in the state " + acToUpdate.getDeployState()); + var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder, + acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(), + acToUpdate.getStateChangeResult()); + return switch (result) { + case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acToUpdate); + + case "MIGRATE" -> migrateAutomationComposition(automationComposition, acToUpdate); + + case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acToUpdate); + + default -> throw new PfModelRuntimeException(Status.BAD_REQUEST, + "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState()); + }; } /** @@ -164,17 +187,14 @@ public class AutomationCompositionInstantiationProvider { var elementId = element.getKey(); var dbAcElement = acToBeUpdated.getElements().get(elementId); if (dbAcElement == null) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId); + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId); } AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().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()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } // Publish property update event to the participants supervisionAcHandler.update(acToBeUpdated); @@ -187,26 +207,23 @@ public class AutomationCompositionInstantiationProvider { AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { if (!DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not allowed to migrate in the state " + acToBeUpdated.getDeployState()); } - if (automationComposition.getRestarting() != null) { - throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Migrate not allowed"); - } // Iterate and update the element property values for (var element : automationComposition.getElements().entrySet()) { var elementId = element.getKey(); var dbAcElement = acToBeUpdated.getElements().get(elementId); if (dbAcElement == null) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId); + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId); } AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); var newDefinition = element.getValue().getDefinition(); var compatibility = newDefinition.asConceptKey().getCompatibility(dbAcElement.getDefinition().asConceptKey()); if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, dbAcElement.getDefinition() + " is not compatible with " + newDefinition); } if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR.equals(compatibility)) { @@ -219,17 +236,57 @@ public class AutomationCompositionInstantiationProvider { var validationResult = validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId()); if (!validationResult.isValid()) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult()); + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId()); // Publish migrate event to the participants - supervisionAcHandler.migrate(acToBeUpdated, automationComposition.getCompositionTargetId()); + supervisionAcHandler.migrate(acToBeUpdated); automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated); return createInstantiationResponse(automationComposition); } + private InstantiationResponse migratePrecheckAc( + AutomationComposition automationComposition, AutomationComposition acToBeUpdated) { + + acToBeUpdated.setPrecheck(true); + var copyAc = new AutomationComposition(acToBeUpdated); + // Iterate and update the element property values + for (var element : automationComposition.getElements().entrySet()) { + var elementId = element.getKey(); + var copyElement = copyAc.getElements().get(elementId); + if (copyElement == null) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId); + } + AcmUtils.recursiveMerge(copyElement.getProperties(), element.getValue().getProperties()); + var newDefinition = element.getValue().getDefinition(); + var compatibility = + newDefinition.asConceptKey().getCompatibility(copyElement.getDefinition().asConceptKey()); + if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, + copyElement.getDefinition() + " is not compatible with " + newDefinition); + } + copyElement.setDefinition(element.getValue().getDefinition()); + } + + var validationResult = + validateAutomationComposition(copyAc, automationComposition.getCompositionTargetId()); + if (!validationResult.isValid()) { + throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); + } + copyAc.setCompositionTargetId(automationComposition.getCompositionTargetId()); + + // Publish migrate event to the participants + supervisionAcHandler.migratePrecheck(copyAc); + + AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED, + SubState.MIGRATION_PRECHECKING); + acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR); + + return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated)); + } + private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) { return validateAutomationComposition(automationComposition, automationComposition.getCompositionId()); } @@ -296,7 +353,7 @@ public class AutomationCompositionInstantiationProvider { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId()) && !compositionId.equals(automationComposition.getCompositionTargetId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } return automationComposition; @@ -312,17 +369,17 @@ public class AutomationCompositionInstantiationProvider { public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState()) && !DeployState.DELETING.equals(automationComposition.getDeployState())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Automation composition state is still " + automationComposition.getDeployState()); } if (DeployState.DELETING.equals(automationComposition.getDeployState()) && StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, "Automation composition state is still " + automationComposition.getDeployState()); } if (automationComposition.getRestarting() != null) { @@ -366,7 +423,7 @@ public class AutomationCompositionInstantiationProvider { @Valid AcInstanceStateUpdate acInstanceStateUpdate) { var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId); if (!compositionId.equals(automationComposition.getCompositionId())) { - throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, + throw new PfModelRuntimeException(Status.BAD_REQUEST, automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId); } var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId()); @@ -376,8 +433,9 @@ public class AutomationCompositionInstantiationProvider { participantProvider.verifyParticipantState(participantIds); var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(), - acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(), - automationComposition.getLockState(), automationComposition.getStateChangeResult()); + acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(), + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState(), automationComposition.getStateChangeResult()); switch (result) { case "DEPLOY": supervisionAcHandler.deploy(automationComposition, acDefinition); @@ -395,6 +453,14 @@ public class AutomationCompositionInstantiationProvider { supervisionAcHandler.unlock(automationComposition, acDefinition); break; + case "PREPARE": + supervisionAcHandler.prepare(automationComposition); + break; + + case "REVIEW": + supervisionAcHandler.review(automationComposition); + break; + default: throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acInstanceStateUpdate); } 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 75477866a..a8d26871a 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 @@ -30,6 +30,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import lombok.AllArgsConstructor; import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; @@ -42,6 +43,7 @@ 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; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; @@ -68,6 +70,7 @@ public class SupervisionAcHandler { private final AcElementPropertiesPublisher acElementPropertiesPublisher; private final AutomationCompositionMigrationPublisher acCompositionMigrationPublisher; private final ParticipantSyncPublisher participantSyncPublisher; + private final AcPreparePublisher acPreparePublisher; private final ExecutorService executor = Context.taskWrapping(Executors.newFixedThreadPool(1)); @@ -150,6 +153,30 @@ public class SupervisionAcHandler { } /** + * Handle prepare Pre Deploy an AutomationComposition instance. + * + * @param automationComposition the AutomationComposition + */ + public void prepare(AutomationComposition automationComposition) { + AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE, SubState.PREPARING); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + automationCompositionProvider.updateAutomationComposition(automationComposition); + executor.execute(() -> acPreparePublisher.sendPrepare(automationComposition)); + } + + /** + * Handle prepare Post Deploy an AutomationComposition instance. + * + * @param automationComposition the AutomationComposition + */ + public void review(AutomationComposition automationComposition) { + AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.REVIEWING); + automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); + automationCompositionProvider.updateAutomationComposition(automationComposition); + executor.execute(() -> acPreparePublisher.sendRevew(automationComposition)); + } + + /** * Handle Lock an AutomationComposition instance. * * @param automationComposition the AutomationComposition @@ -285,6 +312,7 @@ public class SupervisionAcHandler { element.setOutProperties(acElementAck.getValue().getOutProperties()); element.setOperationalState(acElementAck.getValue().getOperationalState()); element.setUseState(acElementAck.getValue().getUseState()); + element.setSubState(SubState.NONE); element.setDeployState(acElementAck.getValue().getDeployState()); element.setLockState(acElementAck.getValue().getLockState()); element.setRestarting(null); @@ -308,12 +336,19 @@ public class SupervisionAcHandler { * Handle Migration of an AutomationComposition instance to other ACM Definition. * * @param automationComposition the AutomationComposition - * @param compositionTargetId the ACM Definition Id */ - public void migrate(AutomationComposition automationComposition, UUID compositionTargetId) { + public void migrate(AutomationComposition automationComposition) { AcmUtils.setCascadedState(automationComposition, DeployState.MIGRATING, LockState.LOCKED); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - executor.execute( - () -> acCompositionMigrationPublisher.send(automationComposition, compositionTargetId)); + executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition)); + } + + /** + * Handle Migration precheck of an AutomationComposition instance to other ACM Definition. + * + * @param automationComposition the AutomationComposition + */ + public void migratePrecheck(AutomationComposition automationComposition) { + executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition)); } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java index d1aa6c239..e723d2c0b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java @@ -34,6 +34,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; +import org.onap.policy.clamp.models.acm.concepts.SubState; 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.utils.AcmUtils; @@ -133,7 +134,7 @@ public class SupervisionScanner { LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId()); if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(), - automationComposition.getLockState()) + automationComposition.getLockState(), automationComposition.getSubState()) || StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId()); @@ -151,7 +152,8 @@ public class SupervisionScanner { int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()); defaultMin = Math.min(defaultMin, startPhase); defaultMax = Math.max(defaultMax, startPhase); - if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { + if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + element.getSubState())) { completed = false; minSpNotCompleted = Math.min(minSpNotCompleted, startPhase); maxSpNotCompleted = Math.max(maxSpNotCompleted, startPhase); @@ -168,7 +170,8 @@ public class SupervisionScanner { automationComposition.getDeployState(), automationComposition.getLockState()); if (DeployState.UPDATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATING.equals(automationComposition.getDeployState())) { + || DeployState.MIGRATING.equals(automationComposition.getDeployState()) + || !SubState.NONE.equals(automationComposition.getSubState())) { // UPDATING do not need phases handleTimeoutUpdate(automationComposition); return; @@ -198,6 +201,8 @@ public class SupervisionScanner { automationComposition.setDeployState(AcmUtils.deployCompleted(deployState)); automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState())); automationComposition.setPhase(null); + automationComposition.setSubState(SubState.NONE); + automationComposition.setPrecheck(null); if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); } @@ -233,7 +238,8 @@ public class SupervisionScanner { var now = TimestampHelper.nowEpochMilli(); var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg()); for (var element : automationComposition.getElements().values()) { - if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { + if (!AcmUtils.isInTransitionalState( + element.getDeployState(), element.getLockState(), element.getSubState())) { continue; } if ((now - lastMsg) > maxStatusWaitMs) { @@ -255,7 +261,8 @@ public class SupervisionScanner { var now = TimestampHelper.nowEpochMilli(); var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg()); for (var element : automationComposition.getElements().values()) { - if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) { + if (!AcmUtils.isInTransitionalState( + element.getDeployState(), element.getLockState(), element.getSubState())) { continue; } var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java new file mode 100644 index 000000000..acf403595 --- /dev/null +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 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.acm.runtime.supervision.comm; + +import io.micrometer.core.annotation.Timed; +import java.time.Instant; +import java.util.UUID; +import lombok.AllArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; +import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@AllArgsConstructor +public class AcPreparePublisher extends AbstractParticipantPublisher<AutomationCompositionPrepare> { + + private static final Logger LOGGER = LoggerFactory.getLogger(AcPreparePublisher.class); + + /** + * Send AutomationCompositionPrepare Prepare message to Participant. + * + * @param automationComposition the AutomationComposition + */ + @Timed(value = "publisher.prepare", description = "AC Prepare Pre Deploy published") + public void sendPrepare(AutomationComposition automationComposition) { + var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(), + automationComposition.getInstanceId()); + acPrepare.setParticipantList( + AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.NONE)); + LOGGER.debug("AC Prepare sent {}", acPrepare); + super.send(acPrepare); + } + + /** + * Send AutomationCompositionPrepare Review message to Participant. + * + * @param automationComposition the AutomationComposition + */ + @Timed(value = "publisher.review", description = "AC Review Post Deploy published") + public void sendRevew(AutomationComposition automationComposition) { + var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(), + automationComposition.getInstanceId()); + acPrepare.setPreDeploy(false); + LOGGER.debug("AC Review sent {}", acPrepare); + super.send(acPrepare); + } + + private AutomationCompositionPrepare createAutomationCompositionPrepare(UUID compositionId, UUID instanceId) { + var acPrepare = new AutomationCompositionPrepare(); + acPrepare.setCompositionId(compositionId); + acPrepare.setAutomationCompositionId(instanceId); + acPrepare.setMessageId(UUID.randomUUID()); + acPrepare.setTimestamp(Instant.now()); + return acPrepare; + } +} diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java index e26a5403b..b961eab93 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java @@ -36,17 +36,17 @@ public class AutomationCompositionMigrationPublisher * Send AutomationCompositionMigration message to Participant. * * @param automationComposition the AutomationComposition - * @param compositionTargetId the Composition Definition Target */ @Timed( value = "publisher.automation_composition_migration", description = "AUTOMATION_COMPOSITION_MIGRATION messages published") - public void send(AutomationComposition automationComposition, UUID compositionTargetId) { + public void send(AutomationComposition automationComposition) { var acsc = new AutomationCompositionMigration(); + acsc.setPrecheck(Boolean.TRUE.equals(automationComposition.getPrecheck())); acsc.setCompositionId(automationComposition.getCompositionId()); acsc.setAutomationCompositionId(automationComposition.getInstanceId()); acsc.setMessageId(UUID.randomUUID()); - acsc.setCompositionTargetId(compositionTargetId); + acsc.setCompositionTargetId(automationComposition.getCompositionTargetId()); acsc.setParticipantUpdatesList( AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.MIGRATE)); 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 2ee6a152e..0591ab02c 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 @@ -48,6 +48,7 @@ import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; @@ -169,7 +170,7 @@ class AutomationCompositionInstantiationProviderTest { var supervisionAcHandler = mock(SupervisionAcHandler.class); var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, participantProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, CommonTestData.getTestParamaterGroup()); var instantiationResponse = instantiationProvider.updateAutomationComposition( automationCompositionUpdate.getCompositionId(), automationCompositionUpdate); @@ -200,15 +201,15 @@ class AutomationCompositionInstantiationProviderTest { .thenReturn(automationCompositionUpdate); var instantiationProvider = - new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null, - mock(SupervisionAcHandler.class), mock(ParticipantProvider.class), - mock(AcRuntimeParameterGroup.class)); + new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), + new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class), + mock(AcRuntimeParameterGroup.class)); var compositionId = automationCompositionUpdate.getCompositionId(); assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) .hasMessageMatching( - "Not allowed to update in the state " + automationCompositionUpdate.getDeployState()); + "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState()); automationCompositionUpdate.setDeployState(DeployState.UPDATING); automationCompositionUpdate.setLockState(LockState.LOCKED); @@ -216,7 +217,7 @@ class AutomationCompositionInstantiationProviderTest { assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) .hasMessageMatching( - "Not allowed to migrate in the state " + automationCompositionUpdate.getDeployState()); + "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState()); } @Test @@ -243,7 +244,7 @@ class AutomationCompositionInstantiationProviderTest { automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID()); assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) - .hasMessageMatching("There is a restarting process, Migrate not allowed"); + .hasMessageMatching("There is a restarting process, Update not allowed"); automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED); automationCompositionUpdate.setLockState(LockState.NONE); @@ -275,7 +276,7 @@ class AutomationCompositionInstantiationProviderTest { var supervisionAcHandler = mock(SupervisionAcHandler.class); var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, participantProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, mock(AcRuntimeParameterGroup.class)); assertThatThrownBy( () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate)) @@ -305,7 +306,7 @@ class AutomationCompositionInstantiationProviderTest { var supervisionAcHandler = mock(SupervisionAcHandler.class); var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup()); + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup()); assertThatThrownBy(() -> instantiationProvider .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition)) @@ -321,7 +322,51 @@ class AutomationCompositionInstantiationProviderTest { var instantiationResponse = instantiationProvider .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition); - verify(supervisionAcHandler).migrate(any(), any()); + verify(supervisionAcHandler).migrate(any()); + verify(acProvider).updateAutomationComposition(automationComposition); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition); + } + + + @Test + void testInstantiationMigrationPrecheck() { + 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 automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + automationComposition.setCompositionId(compositionId); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + automationComposition.setPrecheck(true); + var acProvider = mock(AutomationCompositionProvider.class); + when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition); + + var supervisionAcHandler = mock(SupervisionAcHandler.class); + var acmParticipantProvider = mock(ParticipantProvider.class); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, + new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup()); + + assertThatThrownBy(() -> instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition)) + .hasMessageMatching( + String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId())); + + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionTargetId = acDefinitionTarget.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + + automationComposition.setCompositionTargetId(compositionTargetId); + + var instantiationResponse = instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition); + + verify(supervisionAcHandler).migratePrecheck(any()); verify(acProvider).updateAutomationComposition(automationComposition); InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition); } @@ -354,7 +399,45 @@ class AutomationCompositionInstantiationProviderTest { var supervisionAcHandler = mock(SupervisionAcHandler.class); var participantProvider = mock(ParticipantProvider.class); var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, - null, supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup()); + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); + + assertThatThrownBy(() -> instantiationProvider + .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate)) + .hasMessageStartingWith("Element id not present"); + } + + @Test + void testMigratePrecheckBadRequest() { + 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 automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + automationComposition.setCompositionId(compositionId); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setPrecheck(true); + var acProvider = mock(AutomationCompositionProvider.class); + when(acProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition); + + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var compositionTargetId = acDefinitionTarget.getCompositionId(); + when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget)); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(compositionTargetId); + automationComposition.getElements().clear(); + + var supervisionAcHandler = mock(SupervisionAcHandler.class); + var participantProvider = mock(ParticipantProvider.class); + var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, + new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, + new AcRuntimeParameterGroup()); assertThatThrownBy(() -> instantiationProvider .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate)) @@ -605,5 +688,21 @@ class AutomationCompositionInstantiationProviderTest { acInstanceStateUpdate.setLockOrder(LockOrder.LOCK); provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class)); + + automationComposition.setDeployState(DeployState.UNDEPLOYED); + automationComposition.setLockState(LockState.NONE); + acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE); + acInstanceStateUpdate.setLockOrder(LockOrder.NONE); + acInstanceStateUpdate.setSubOrder(SubOrder.PREPARE); + provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); + verify(supervisionAcHandler).prepare(any(AutomationComposition.class)); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.LOCKED); + acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE); + acInstanceStateUpdate.setLockOrder(LockOrder.NONE); + acInstanceStateUpdate.setSubOrder(SubOrder.REVIEW); + provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate); + verify(supervisionAcHandler).review(any(AutomationComposition.class)); } } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java index e895401a4..2d9c1280b 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java @@ -36,6 +36,7 @@ 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.AcElementPropertiesPublisher; +import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher; @@ -76,7 +77,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider, mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var automationCompositionAckMessage = getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK, @@ -124,7 +125,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider, mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); @@ -161,7 +162,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), automationCompositionStateChangePublisher, null, - null, mock(ParticipantSyncPublisher.class)); + null, mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); @@ -175,7 +176,8 @@ class SupervisionAcHandlerTest { var automationCompositionProvider = mock(AutomationCompositionProvider.class); var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), automationCompositionDeployPublisher, mock(AutomationCompositionStateChangePublisher.class), - mock(AcElementPropertiesPublisher.class), null, mock(ParticipantSyncPublisher.class)); + mock(AcElementPropertiesPublisher.class), null, + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); @@ -195,7 +197,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -213,7 +215,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); @@ -234,7 +236,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -252,7 +254,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -272,7 +274,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -290,7 +292,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher, mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML); var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var automationComposition = @@ -321,7 +323,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), mock(AcElementPropertiesPublisher.class), null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage); @@ -335,7 +337,7 @@ class SupervisionAcHandlerTest { var handler = new SupervisionAcHandler(mock(AutomationCompositionProvider.class), mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class), acElementPropertiesPublisher, null, - mock(ParticipantSyncPublisher.class)); + mock(ParticipantSyncPublisher.class), null); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock"); handler.update(automationComposition); @@ -348,10 +350,46 @@ class SupervisionAcHandlerTest { var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class); var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class), null, null, null, - acCompositionMigrationPublisher, mock(ParticipantSyncPublisher.class)); + acCompositionMigrationPublisher, mock(ParticipantSyncPublisher.class), null); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + handler.migrate(automationComposition); + verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class)); + } + + @Test + void testMigratePrecheck() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, + null, acCompositionMigrationPublisher, null, null); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + handler.migratePrecheck(automationComposition); + verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class)); + } + + @Test + void testPrepare() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acPreparePublisher = mock(AcPreparePublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, + null, null, null, acPreparePublisher); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); + handler.prepare(automationComposition); + verify(acPreparePublisher, timeout(1000)).sendPrepare(any(AutomationComposition.class)); + } + + @Test + void testReview() { + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + var acPreparePublisher = mock(AcPreparePublisher.class); + var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null, + null, null, null, acPreparePublisher); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate"); - handler.migrate(automationComposition, UUID.randomUUID()); - verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class), any()); + handler.review(automationComposition); + verify(acPreparePublisher, timeout(1000)).sendRevew(any(AutomationComposition.class)); } } 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 7cf0bf84f..77b47f4e3 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 @@ -231,7 +231,29 @@ class SupervisionMessagesTest { publisher.active(topicSink); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); - publisher.send(automationComposition, UUID.randomUUID()); + publisher.send(automationComposition); + verify(topicSink).send(anyString()); + } + + @Test + void testAcPreparePublisher() { + var publisher = new AcPreparePublisher(); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + publisher.sendPrepare(automationComposition); + verify(topicSink).send(anyString()); + } + + @Test + void testAcReviewPublisher() { + var publisher = new AcPreparePublisher(); + var topicSink = mock(TopicSink.class); + publisher.active(topicSink); + var automationComposition = + InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); + publisher.sendRevew(automationComposition); verify(topicSink).send(anyString()); } |