aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancescoFioraEst <francesco.fiora@est.tech>2024-01-19 14:29:25 +0000
committerFrancescoFioraEst <francesco.fiora@est.tech>2024-07-24 16:19:31 +0100
commit37195c69c99b5987f037a018859b4421cbcbadf2 (patch)
tree66c18541aca4cb1598701ee2a289d1e390cb6553
parenta2f6493f89eff78a78d8ba2aa34f6080d6ab8830 (diff)
Add support for Prepare, Review and Migrate pre-check in intermediary
Add support for Prepare, Review and Migrate pre-check in ACM intermediary. Issue-ID: POLICY-5080 Change-Id: I08045a8eb01dcea6492aac12b7a8021a47ae19e8 Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java46
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java3
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java152
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java51
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java20
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java64
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java13
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java89
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java164
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java18
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java32
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java46
-rw-r--r--participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java222
13 files changed, 818 insertions, 102 deletions
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java
new file mode 100644
index 000000000..0f6d2c09f
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/AcPrepareListener.java
@@ -0,0 +1,46 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AcPrepareListener extends ParticipantListener<AutomationCompositionPrepare> {
+
+ /**
+ * Constructs the object.
+ *
+ * @param participantHandler the handler for managing the state of the participant
+ */
+ public AcPrepareListener(final ParticipantHandler participantHandler) {
+ super(AutomationCompositionPrepare.class, participantHandler,
+ participantHandler::handleAutomationCompositionPrepare);
+ }
+
+
+ @Override
+ public String getType() {
+ return ParticipantMessageType.AUTOMATION_COMPOSITION_PREPARE.name();
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java
index 89daa5fd2..95613cc9e 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java
@@ -27,6 +27,7 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
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.SubState;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -79,6 +80,7 @@ public class AcLockHandler {
int startPhase = ParticipantUtils.findStartPhase(compositionInProperties);
if (startPhaseMsg.equals(startPhase)) {
element.setLockState(LockState.LOCKING);
+ element.setSubState(SubState.NONE);
var compositionElement = cacheProvider.createCompositionElementDto(
automationComposition.getCompositionId(), element, compositionInProperties);
var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
@@ -99,6 +101,7 @@ public class AcLockHandler {
int startPhase = ParticipantUtils.findStartPhase(compositionInProperties);
if (startPhaseMsg.equals(startPhase)) {
element.setLockState(LockState.UNLOCKING);
+ element.setSubState(SubState.NONE);
var compositionElement = cacheProvider.createCompositionElementDto(
automationComposition.getCompositionId(), element, compositionInProperties);
var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java
new file mode 100644
index 000000000..3044080af
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java
@@ -0,0 +1,152 @@
+/*-
+ * ============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.participant.intermediary.handler;
+
+import java.util.List;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class AcSubStateHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AcSubStateHandler.class);
+
+ private final CacheProvider cacheProvider;
+ private final ThreadHandler listener;
+
+ /**
+ * Handles AutomationComposition Migration Precheck.
+ *
+ * @param migrationMsg the AutomationCompositionMigration
+ */
+ public void handleAcMigrationPrecheck(AutomationCompositionMigration migrationMsg) {
+ if (migrationMsg.getAutomationCompositionId() == null || migrationMsg.getCompositionTargetId() == null) {
+ return;
+ }
+
+ var automationComposition = cacheProvider.getAutomationComposition(migrationMsg.getAutomationCompositionId());
+ if (automationComposition == null) {
+ LOGGER.debug("Automation composition {} does not use this participant",
+ migrationMsg.getAutomationCompositionId());
+ return;
+ }
+ automationComposition.setSubState(SubState.MIGRATION_PRECHECKING);
+ for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) {
+ if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) {
+
+ callParticipantMigratePrecheck(migrationMsg.getMessageId(), participantDeploy.getAcElementList(),
+ automationComposition, migrationMsg.getCompositionTargetId());
+ }
+ }
+ }
+
+ private void callParticipantMigratePrecheck(UUID messageId, List<AcElementDeploy> acElements,
+ AutomationComposition automationComposition, UUID compositionTargetId) {
+ var compositionElementMap = cacheProvider.getCompositionElementDtoMap(automationComposition);
+ var instanceElementMap = cacheProvider.getInstanceElementDtoMap(automationComposition);
+ var acElementList = automationComposition.getElements();
+ for (var acElement : acElements) {
+ var element = acElementList.get(acElement.getId());
+ element.setSubState(SubState.MIGRATION_PRECHECKING);
+ }
+ var acCopyMigrateTo = new AutomationComposition(automationComposition);
+ acElementList = acCopyMigrateTo.getElements();
+ for (var acElement : acElements) {
+ var element = acElementList.get(acElement.getId());
+ AcmUtils.recursiveMerge(element.getProperties(), acElement.getProperties());
+ element.setDefinition(acElement.getDefinition());
+ }
+
+ var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(acCopyMigrateTo,
+ compositionTargetId);
+ var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(acCopyMigrateTo);
+
+ for (var acElement : acElements) {
+ listener.migratePrecheck(messageId, compositionElementMap.get(acElement.getId()),
+ compositionElementTargetMap.get(acElement.getId()),
+ instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId()));
+ }
+ }
+
+ /**
+ * Handle AutomationComposition Prepare message.
+ *
+ * @param acPrepareMsg the AutomationCompositionPrepare message
+ */
+ public void handleAcPrepare(AutomationCompositionPrepare acPrepareMsg) {
+ if (acPrepareMsg.isPreDeploy()) {
+ for (var participantPrepare : acPrepareMsg.getParticipantList()) {
+ if (cacheProvider.getParticipantId().equals(participantPrepare.getParticipantId())) {
+ cacheProvider.initializeAutomationComposition(acPrepareMsg.getCompositionId(),
+ acPrepareMsg.getAutomationCompositionId(), participantPrepare, DeployState.UNDEPLOYED,
+ SubState.PREPARING);
+ callParticipanPrepare(acPrepareMsg.getMessageId(), participantPrepare.getAcElementList(),
+ acPrepareMsg.getAutomationCompositionId());
+ }
+ }
+ } else {
+ var automationComposition =
+ cacheProvider.getAutomationComposition(acPrepareMsg.getAutomationCompositionId());
+ automationComposition.setSubState(SubState.REVIEWING);
+ callParticipanReview(acPrepareMsg.getMessageId(), automationComposition);
+ }
+ }
+
+ private void callParticipanPrepare(UUID messageId, List<AcElementDeploy> acElementList, UUID instanceId) {
+ var automationComposition = cacheProvider.getAutomationComposition(instanceId);
+ for (var elementDeploy : acElementList) {
+ var element = automationComposition.getElements().get(elementDeploy.getId());
+ var compositionInProperties = cacheProvider
+ .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
+ var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(),
+ element, compositionInProperties);
+ var instanceElement = new InstanceElementDto(instanceId, elementDeploy.getId(),
+ elementDeploy.getToscaServiceTemplateFragment(),
+ elementDeploy.getProperties(), element.getOutProperties());
+ listener.prepare(messageId, compositionElement, instanceElement);
+ }
+ }
+
+ private void callParticipanReview(UUID messageId, AutomationComposition automationComposition) {
+ for (var element : automationComposition.getElements().values()) {
+ var compositionInProperties = cacheProvider
+ .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition());
+ element.setSubState(SubState.REVIEWING);
+ var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(),
+ element, compositionInProperties);
+ var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
+ null, element.getProperties(), element.getOutProperties());
+ listener.review(messageId, compositionElement, instanceElement);
+ }
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
index b60d6372c..0f230c0a4 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
@@ -21,12 +21,9 @@
package org.onap.policy.clamp.acm.participant.intermediary.handler;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
-import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
@@ -35,6 +32,7 @@ import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
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.AutomationCompositionDeploy;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeployAck;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
@@ -171,40 +169,12 @@ public class AutomationCompositionHandler {
}
}
- private Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
- UUID compositionId) {
- Map<UUID, CompositionElementDto> map = new HashMap<>();
- for (var element : automationComposition.getElements().values()) {
- var compositionInProperties = cacheProvider.getCommonProperties(compositionId, element.getDefinition());
- var compositionElement = cacheProvider
- .createCompositionElementDto(compositionId, element, compositionInProperties);
- map.put(element.getId(), compositionElement);
- }
- return map;
- }
-
- private Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
- return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
- }
-
- private Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
- Map<UUID, InstanceElementDto> map = new HashMap<>();
- var serviceTemplateFragment = cacheProvider
- .getServiceTemplateFragmentMap().get(automationComposition.getCompositionId());
- for (var element : automationComposition.getElements().values()) {
- var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
- serviceTemplateFragment, element.getProperties(), element.getOutProperties());
- map.put(element.getId(), instanceElement);
- }
- return map;
- }
-
private void callParticipantUpdateProperty(UUID messageId, List<AcElementDeploy> acElements,
AutomationComposition acCopy) {
- var instanceElementDtoMap = getInstanceElementDtoMap(acCopy);
- var instanceElementDtoMapUpdated = getInstanceElementDtoMap(
+ var instanceElementDtoMap = cacheProvider.getInstanceElementDtoMap(acCopy);
+ var instanceElementDtoMapUpdated = cacheProvider.getInstanceElementDtoMap(
cacheProvider.getAutomationComposition(acCopy.getInstanceId()));
- var compositionElementDtoMap = getCompositionElementDtoMap(acCopy);
+ var compositionElementDtoMap = cacheProvider.getCompositionElementDtoMap(acCopy);
for (var acElement : acElements) {
listener.update(messageId, compositionElementDtoMap.get(acElement.getId()),
instanceElementDtoMap.get(acElement.getId()), instanceElementDtoMapUpdated.get(acElement.getId()));
@@ -218,6 +188,7 @@ public class AutomationCompositionHandler {
var acElement = acElementList.get(element.getId());
AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties());
acElement.setDeployState(deployState);
+ acElement.setSubState(SubState.NONE);
acElement.setDefinition(element.getDefinition());
}
}
@@ -261,6 +232,7 @@ public class AutomationCompositionHandler {
int startPhase = ParticipantUtils.findStartPhase(compositionInProperties);
if (startPhaseMsg.equals(startPhase)) {
element.setDeployState(DeployState.DELETING);
+ element.setSubState(SubState.NONE);
var compositionElement = cacheProvider.createCompositionElementDto(
automationComposition.getCompositionId(), element, compositionInProperties);
var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
@@ -293,7 +265,7 @@ public class AutomationCompositionHandler {
if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) {
updateExistingElementsOnThisParticipant(migrationMsg.getAutomationCompositionId(), participantDeploy,
- DeployState.MIGRATING);
+ DeployState.MIGRATING);
callParticipantMigrate(migrationMsg.getMessageId(), participantDeploy.getAcElementList(),
acCopy, migrationMsg.getCompositionTargetId());
@@ -303,11 +275,12 @@ public class AutomationCompositionHandler {
private void callParticipantMigrate(UUID messageId, List<AcElementDeploy> acElements,
AutomationComposition acCopy, UUID compositionTargetId) {
- var compositionElementMap = getCompositionElementDtoMap(acCopy);
- var instanceElementMap = getInstanceElementDtoMap(acCopy);
+ var compositionElementMap = cacheProvider.getCompositionElementDtoMap(acCopy);
+ var instanceElementMap = cacheProvider.getInstanceElementDtoMap(acCopy);
var automationComposition = cacheProvider.getAutomationComposition(acCopy.getInstanceId());
- var compositionElementTargetMap = getCompositionElementDtoMap(automationComposition, compositionTargetId);
- var instanceElementMigrateMap = getInstanceElementDtoMap(automationComposition);
+ var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(automationComposition,
+ compositionTargetId);
+ var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(automationComposition);
for (var acElement : acElements) {
listener.migrate(messageId, compositionElementMap.get(acElement.getId()),
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
index 1f4c036e7..06b11bbca 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
@@ -37,6 +37,7 @@ import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
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.messages.kafka.participant.ParticipantMessageType;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck;
@@ -93,7 +94,13 @@ public class AutomationCompositionOutHandler {
}
element.setRestarting(null);
- if (deployState != null) {
+ if (deployState != null && !SubState.NONE.equals(element.getSubState())) {
+ handleSubState(automationComposition, element);
+ if (!StateChangeResult.NO_ERROR.equals(stateChangeResult)) {
+ stateChangeResult = StateChangeResult.NO_ERROR;
+ LOGGER.warn("SubState has always NO_ERROR result!");
+ }
+ } else if (deployState != null) {
handleDeployState(automationComposition, element, deployState);
}
if (lockState != null) {
@@ -132,6 +139,7 @@ public class AutomationCompositionOutHandler {
}
automationComposition.setDeployState(deployState);
automationComposition.setLockState(element.getLockState());
+ automationComposition.setSubState(SubState.NONE);
if (DeployState.DELETED.equals(deployState)) {
cacheProvider.removeAutomationComposition(automationComposition.getInstanceId());
@@ -146,6 +154,16 @@ public class AutomationCompositionOutHandler {
.filter(acElement -> !lockState.equals(acElement.getLockState())).findAny();
if (checkOpt.isEmpty()) {
automationComposition.setLockState(lockState);
+ automationComposition.setSubState(SubState.NONE);
+ }
+ }
+
+ private void handleSubState(AutomationComposition automationComposition, AutomationCompositionElement element) {
+ element.setSubState(SubState.NONE);
+ var checkOpt = automationComposition.getElements().values().stream()
+ .filter(acElement -> !SubState.NONE.equals(acElement.getSubState())).findAny();
+ if (checkOpt.isEmpty()) {
+ automationComposition.setSubState(SubState.NONE);
}
}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
index 29b77fcb6..f56fabf3f 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
@@ -30,6 +30,7 @@ import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto;
+import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto;
import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
@@ -39,6 +40,7 @@ import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
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;
@@ -161,6 +163,21 @@ public class CacheProvider {
*/
public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
ParticipantDeploy participantDeploy) {
+ initializeAutomationComposition(compositionId, instanceId, participantDeploy,
+ DeployState.DEPLOYING, SubState.NONE);
+ }
+
+ /**
+ * Initialize an AutomationComposition from a ParticipantDeploy.
+ *
+ * @param compositionId the composition Id
+ * @param instanceId the Automation Composition Id
+ * @param participantDeploy the ParticipantDeploy
+ * @param deployState the DeployState
+ * @param subState the SubState
+ */
+ public void initializeAutomationComposition(@NonNull UUID compositionId, @NonNull UUID instanceId,
+ ParticipantDeploy participantDeploy, DeployState deployState, SubState subState) {
var acLast = automationCompositions.get(instanceId);
Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
for (var element : participantDeploy.getAcElementList()) {
@@ -168,8 +185,9 @@ public class CacheProvider {
acElement.setId(element.getId());
acElement.setParticipantId(getParticipantId());
acElement.setDefinition(element.getDefinition());
- acElement.setDeployState(DeployState.DEPLOYING);
+ acElement.setDeployState(deployState);
acElement.setLockState(LockState.NONE);
+ acElement.setSubState(subState);
acElement.setProperties(element.getProperties());
var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null;
if (acElementLast != null) {
@@ -186,6 +204,8 @@ public class CacheProvider {
automationComposition.setCompositionId(compositionId);
automationComposition.setInstanceId(instanceId);
automationComposition.setElements(acElementMap);
+ automationComposition.setDeployState(deployState);
+ automationComposition.setSubState(subState);
automationCompositions.put(instanceId, automationComposition);
}
@@ -208,6 +228,7 @@ public class CacheProvider {
acElement.setDefinition(element.getDefinition());
acElement.setDeployState(element.getDeployState());
acElement.setLockState(element.getLockState());
+ acElement.setSubState(SubState.NONE);
acElement.setOperationalState(element.getOperationalState());
acElement.setUseState(element.getUseState());
acElement.setProperties(element.getProperties());
@@ -236,10 +257,49 @@ public class CacheProvider {
* @return the CompositionElementDto
*/
public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element,
- Map<String, Object> compositionInProperties) {
+ Map<String, Object> compositionInProperties) {
var compositionOutProperties = getAcElementsDefinitions()
.get(compositionId).get(element.getDefinition()).getOutProperties();
return new CompositionElementDto(compositionId,
element.getDefinition(), compositionInProperties, compositionOutProperties);
}
+
+ /**
+ * Get a Map of CompositionElementDto by elementId from the elements of an AutomationComposition.
+ *
+ * @param automationComposition the AutomationComposition
+ * @param compositionId the compositionId
+ * @return the Map of CompositionElementDto
+ */
+ public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition,
+ UUID compositionId) {
+ Map<UUID, CompositionElementDto> map = new HashMap<>();
+ for (var element : automationComposition.getElements().values()) {
+ var compositionInProperties = getCommonProperties(compositionId, element.getDefinition());
+ var compositionElement = createCompositionElementDto(compositionId, element, compositionInProperties);
+ map.put(element.getId(), compositionElement);
+ }
+ return map;
+ }
+
+ public Map<UUID, CompositionElementDto> getCompositionElementDtoMap(AutomationComposition automationComposition) {
+ return getCompositionElementDtoMap(automationComposition, automationComposition.getCompositionId());
+ }
+
+ /**
+ * Get a Map of InstanceElementDto by elementId from the elements of an AutomationComposition.
+ *
+ * @param automationComposition the AutomationComposition
+ * @return the Map of InstanceElementDto
+ */
+ public Map<UUID, InstanceElementDto> getInstanceElementDtoMap(AutomationComposition automationComposition) {
+ Map<UUID, InstanceElementDto> map = new HashMap<>();
+ var serviceTemplateFragment = serviceTemplateFragmentMap.get(automationComposition.getCompositionId());
+ for (var element : automationComposition.getElements().values()) {
+ var instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), element.getId(),
+ serviceTemplateFragment, element.getProperties(), element.getOutProperties());
+ map.put(element.getId(), instanceElement);
+ }
+ return map;
+ }
}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
index 5ae8f0422..6615ae102 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
@@ -28,6 +28,7 @@ import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessag
import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantAckMessage;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister;
@@ -55,6 +56,7 @@ public class ParticipantHandler {
private final AutomationCompositionHandler automationCompositionHandler;
private final AcLockHandler acLockHandler;
+ private final AcSubStateHandler acSubStateHandler;
private final AcDefinitionHandler acDefinitionHandler;
private final ParticipantMessagePublisher publisher;
private final CacheProvider cacheProvider;
@@ -106,7 +108,11 @@ public class ParticipantHandler {
value = "listener.automation_composition_migration",
description = "AUTOMATION_COMPOSITION_MIGRATION messages received")
public void handleAutomationCompositionMigration(AutomationCompositionMigration migrationMsg) {
- automationCompositionHandler.handleAutomationCompositionMigration(migrationMsg);
+ if (Boolean.TRUE.equals(migrationMsg.getPrecheck())) {
+ acSubStateHandler.handleAcMigrationPrecheck(migrationMsg);
+ } else {
+ automationCompositionHandler.handleAutomationCompositionMigration(migrationMsg);
+ }
}
/**
@@ -119,6 +125,11 @@ public class ParticipantHandler {
automationCompositionHandler.handleAcPropertyUpdate(propertyUpdateMsg);
}
+ @Timed(value = "listener.prepare", description = "AUTOMATION_COMPOSITION_PREPARE message received")
+ public void handleAutomationCompositionPrepare(AutomationCompositionPrepare acPrepareMsg) {
+ acSubStateHandler.handleAcPrepare(acPrepareMsg);
+ }
+
/**
* Check if a participant message applies to this participant handler.
*
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
index 00e0044b4..e6c2d379c 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
@@ -319,4 +319,93 @@ public class ThreadHandler implements Closeable {
}
executionMap.remove(instanceElement.elementId());
}
+
+ /**
+ * Handles AutomationComposition Migration Precheck.
+ *
+ * @param messageId the messageId
+ * @param compositionElement the information of the Automation Composition Definition Element
+ * @param compositionElementTarget the information of the Automation Composition Definition Element Target
+ * @param instanceElement the information of the Automation Composition Instance Element
+ * @param instanceElementMigrate the information of the Automation Composition Instance Element updated
+ */
+ public void migratePrecheck(UUID messageId, CompositionElementDto compositionElement,
+ CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
+ InstanceElementDto instanceElementMigrate) {
+ cleanExecution(instanceElement.elementId(), messageId);
+ var result = executor.submit(() ->
+ this.migratePrecheckProcess(compositionElement, compositionElementTarget, instanceElement,
+ instanceElementMigrate));
+ executionMap.put(instanceElement.elementId(), result);
+ }
+
+ private void migratePrecheckProcess(CompositionElementDto compositionElement,
+ CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
+ InstanceElementDto instanceElementMigrate) {
+ try {
+ listener.migratePrecheck(compositionElement, compositionElementTarget, instanceElement,
+ instanceElementMigrate);
+ } catch (PfModelException e) {
+ LOGGER.error("Automation composition element migrate precheck failed {} {}",
+ instanceElement.elementId(), e.getMessage());
+ intermediaryApi.updateAutomationCompositionElementState(
+ instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
+ null, StateChangeResult.FAILED, "Automation composition element migrate precheck failed");
+ }
+ executionMap.remove(instanceElement.elementId());
+ }
+
+ /**
+ * Handles AutomationComposition Prepare Post Deploy.
+ *
+ * @param messageId the messageId
+ * @param compositionElement the information of the Automation Composition Definition Element
+ * @param instanceElement the information of the Automation Composition Instance Element
+ */
+ public void review(UUID messageId, CompositionElementDto compositionElement,
+ InstanceElementDto instanceElement) {
+ cleanExecution(instanceElement.elementId(), messageId);
+ var result = executor.submit(() -> this.reviewProcess(compositionElement, instanceElement));
+ executionMap.put(instanceElement.elementId(), result);
+ }
+
+ private void reviewProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
+ try {
+ listener.review(compositionElement, instanceElement);
+ } catch (PfModelException e) {
+ LOGGER.error("Automation composition element Review failed {} {}",
+ instanceElement.elementId(), e.getMessage());
+ intermediaryApi.updateAutomationCompositionElementState(
+ instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED,
+ null, StateChangeResult.FAILED, "Automation composition element Review failed");
+ }
+ executionMap.remove(instanceElement.elementId());
+ }
+
+ /**
+ * Handles AutomationComposition Prepare Pre Deploy.
+ *
+ * @param messageId the messageId
+ * @param compositionElement the information of the Automation Composition Definition Element
+ * @param instanceElement the information of the Automation Composition Instance Element
+ */
+ public void prepare(UUID messageId, CompositionElementDto compositionElement,
+ InstanceElementDto instanceElement) {
+ cleanExecution(instanceElement.elementId(), messageId);
+ var result = executor.submit(() -> this.prepareProcess(compositionElement, instanceElement));
+ executionMap.put(instanceElement.elementId(), result);
+ }
+
+ private void prepareProcess(CompositionElementDto compositionElement, InstanceElementDto instanceElement) {
+ try {
+ listener.prepare(compositionElement, instanceElement);
+ } catch (PfModelException e) {
+ LOGGER.error("Automation composition element prepare Pre Deploy failed {} {}",
+ instanceElement.elementId(), e.getMessage());
+ intermediaryApi.updateAutomationCompositionElementState(
+ instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED,
+ null, StateChangeResult.FAILED, "Automation composition element prepare Pre Deploy failed");
+ }
+ executionMap.remove(instanceElement.elementId());
+ }
}
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java
new file mode 100644
index 000000000..293a4415b
--- /dev/null
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java
@@ -0,0 +1,164 @@
+/*-
+ * ============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.participant.intermediary.handler;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class AcSubStateHandlerTest {
+
+ @Test
+ void handleAcStateChangeNullTest() {
+ var cacheProvider = mock(CacheProvider.class);
+ var ach = new AcSubStateHandler(cacheProvider, mock(ThreadHandler.class));
+
+ var acMigration = new AutomationCompositionMigration();
+ acMigration.setPrecheck(true);
+ assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(acMigration));
+
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ acMigration.setAutomationCompositionId(automationComposition.getInstanceId());
+ acMigration.setCompositionTargetId(UUID.randomUUID());
+ assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(acMigration));
+
+ var acPrepare = new AutomationCompositionPrepare();
+ assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepare));
+
+ acPrepare.setAutomationCompositionId(automationComposition.getInstanceId());
+ assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepare));
+ }
+
+ @Test
+ void handleAcMigrationPrecheckTest() {
+ var listener = mock(ThreadHandler.class);
+ var cacheProvider = mock(CacheProvider.class);
+ var ach = new AcSubStateHandler(cacheProvider, listener);
+ var migrationMsg = new AutomationCompositionMigration();
+ migrationMsg.setPrecheck(true);
+ assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(migrationMsg));
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ migrationMsg.setCompositionTargetId(UUID.randomUUID());
+ migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId());
+ assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(migrationMsg));
+ when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ var participantDeploy = new ParticipantDeploy();
+ participantDeploy.setParticipantId(CommonTestData.getParticipantId());
+ when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
+ migrationMsg.getParticipantUpdatesList().add(participantDeploy);
+ Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
+ for (var element : automationComposition.getElements().values()) {
+ var acElementDeploy = new AcElementDeploy();
+ acElementDeploy.setProperties(Map.of());
+ acElementDeploy.setId(element.getId());
+ acElementDeploy.setDefinition(element.getDefinition());
+ participantDeploy.getAcElementList().add(acElementDeploy);
+ map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
+ }
+ when(cacheProvider.getAcElementsDefinitions())
+ .thenReturn(Map.of(automationComposition.getCompositionId(), map,
+ migrationMsg.getCompositionTargetId(), map));
+
+ ach.handleAcMigrationPrecheck(migrationMsg);
+ verify(listener, times(automationComposition.getElements().size()))
+ .migratePrecheck(any(), any(), any(), any(), any());
+ }
+
+ @Test
+ void handlePrepareTest() {
+ var listener = mock(ThreadHandler.class);
+ var cacheProvider = mock(CacheProvider.class);
+ var ach = new AcSubStateHandler(cacheProvider, listener);
+
+ var acPrepareMsg = new AutomationCompositionPrepare();
+ acPrepareMsg.setPreDeploy(true);
+ assertDoesNotThrow(() -> ach.handleAcPrepare(acPrepareMsg));
+
+ acPrepareMsg.setParticipantId(CommonTestData.getParticipantId());
+ when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
+ var participantDeploy = new ParticipantDeploy();
+ participantDeploy.setParticipantId(CommonTestData.getParticipantId());
+ acPrepareMsg.getParticipantList().add(participantDeploy);
+
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ acPrepareMsg.setAutomationCompositionId(automationComposition.getInstanceId());
+ when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
+ for (var element : automationComposition.getElements().values()) {
+ var acElementDeploy = new AcElementDeploy();
+ acElementDeploy.setProperties(Map.of());
+ acElementDeploy.setId(element.getId());
+ participantDeploy.getAcElementList().add(acElementDeploy);
+ map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
+ }
+ when(cacheProvider.getAcElementsDefinitions())
+ .thenReturn(Map.of(automationComposition.getCompositionId(), map));
+
+ ach.handleAcPrepare(acPrepareMsg);
+ verify(listener, times(automationComposition.getElements().size())).prepare(any(), any(), any());
+ }
+
+ @Test
+ void handleReviewTest() {
+ var cacheProvider = mock(CacheProvider.class);
+ when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
+
+ var acPrepareMsg = new AutomationCompositionPrepare();
+ acPrepareMsg.setPreDeploy(false);
+ acPrepareMsg.setParticipantId(CommonTestData.getParticipantId());
+
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ acPrepareMsg.setAutomationCompositionId(automationComposition.getInstanceId());
+ when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>();
+ for (var element : automationComposition.getElements().values()) {
+ var acElementDeploy = new AcElementDeploy();
+ acElementDeploy.setProperties(Map.of());
+ acElementDeploy.setId(element.getId());
+ map.put(element.getDefinition(), new AutomationCompositionElementDefinition());
+ }
+ when(cacheProvider.getAcElementsDefinitions())
+ .thenReturn(Map.of(automationComposition.getCompositionId(), map));
+
+ var listener = mock(ThreadHandler.class);
+ var ach = new AcSubStateHandler(cacheProvider, listener);
+ ach.handleAcPrepare(acPrepareMsg);
+ verify(listener, times(automationComposition.getElements().size())).review(any(), any(), any());
+ }
+}
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
index eed5319f8..27813988d 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
@@ -39,6 +39,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDef
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.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.messages.kafka.participant.ParticipantPrimeAck;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus;
@@ -87,6 +88,23 @@ class AutomationCompositionOutHandlerTest {
}
@Test
+ void updateAutomationCompositionElementStatePrepareTest() {
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ automationComposition.setSubState(SubState.PREPARING);
+ var cacheProvider = mock(CacheProvider.class);
+ when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ var element = automationComposition.getElements().values().iterator().next();
+ element.setSubState(SubState.PREPARING);
+ var elementId = element.getId();
+ var publisher = mock(ParticipantMessagePublisher.class);
+ var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider);
+ acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(), elementId,
+ DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed");
+ verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class));
+ }
+
+ @Test
void updateAutomationCompositionElementStateLockTest() {
var publisher = mock(ParticipantMessagePublisher.class);
var cacheProvider = mock(CacheProvider.class);
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
index 9451f0138..ced2d81e8 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
@@ -186,4 +186,36 @@ class CacheProviderTest {
assertEquals(element.getDefinition(), result.elementDefinitionId());
}
}
+
+ @Test
+ void testGetCompositionElementDtoMap() {
+ var parameter = CommonTestData.getParticipantParameters();
+ var cacheProvider = new CacheProvider(parameter);
+ var compositionId = UUID.randomUUID();
+ var automationComposition =
+ CommonTestData.getTestAutomationCompositions().getAutomationCompositionList().get(0);
+ automationComposition.setCompositionId(compositionId);
+ cacheProvider.addElementDefinition(compositionId,
+ CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition));
+ var result = cacheProvider.getCompositionElementDtoMap(automationComposition);
+ for (var element : automationComposition.getElements().values()) {
+ var compositionElementDto = result.get(element.getId());
+ assertEquals(element.getDefinition(), compositionElementDto.elementDefinitionId());
+ }
+ }
+
+ @Test
+ void testGetInstanceElementDtoMap() {
+ var parameter = CommonTestData.getParticipantParameters();
+ var cacheProvider = new CacheProvider(parameter);
+ var compositionId = UUID.randomUUID();
+ var automationComposition =
+ CommonTestData.getTestAutomationCompositions().getAutomationCompositionList().get(0);
+ automationComposition.setCompositionId(compositionId);
+ var result = cacheProvider.getInstanceElementDtoMap(automationComposition);
+ for (var element : automationComposition.getElements().values()) {
+ var compositionElementDto = result.get(element.getId());
+ assertEquals(element.getId(), compositionElementDto.elementId());
+ }
+ }
}
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
index 8c2b2473c..1fb72812b 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
@@ -62,7 +62,8 @@ class ParticipantHandlerTest {
when(publisher.isActive()).thenReturn(true);
var cacheProvider = mock(CacheProvider.class);
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class),
+ publisher, cacheProvider);
participantHandler.handleParticipantStatusReq(new ParticipantStatusReq());
verify(publisher).sendParticipantRegister(any(ParticipantRegister.class));
@@ -76,7 +77,8 @@ class ParticipantHandlerTest {
void handleAutomationCompositionDeployTest() {
var acHandler = mock(AutomationCompositionHandler.class);
var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class),
- mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
+ mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class),
+ mock(CacheProvider.class));
var automationCompositionDeploy = new AutomationCompositionDeploy();
participantHandler.handleAutomationCompositionDeploy(automationCompositionDeploy);
verify(acHandler).handleAutomationCompositionDeploy(automationCompositionDeploy);
@@ -86,8 +88,8 @@ class ParticipantHandlerTest {
void handleAutomationCompositionStateChangeTest() {
var acHandler = mock(AutomationCompositionHandler.class);
var acLockHandler = mock(AcLockHandler.class);
- var participantHandler = new ParticipantHandler(acHandler, acLockHandler, mock(AcDefinitionHandler.class),
- mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
+ var participantHandler = new ParticipantHandler(acHandler, acLockHandler, mock(AcSubStateHandler.class),
+ mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
var acStateChange = new AutomationCompositionStateChange();
acStateChange.setDeployOrderedState(DeployOrder.DEPLOY);
@@ -104,18 +106,25 @@ class ParticipantHandlerTest {
@Test
void handleAutomationCompositionMigrationTest() {
var acHandler = mock(AutomationCompositionHandler.class);
+ var acSubStateHandler = mock(AcSubStateHandler.class);
var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class),
- mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
+ acSubStateHandler, mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class),
+ mock(CacheProvider.class));
var migrationMsg = new AutomationCompositionMigration();
participantHandler.handleAutomationCompositionMigration(migrationMsg);
verify(acHandler).handleAutomationCompositionMigration(migrationMsg);
+
+ migrationMsg.setPrecheck(true);
+ participantHandler.handleAutomationCompositionMigration(migrationMsg);
+ verify(acSubStateHandler).handleAcMigrationPrecheck(migrationMsg);
}
@Test
void handleAcPropertyUpdateTest() {
var acHandler = mock(AutomationCompositionHandler.class);
var participantHandler = new ParticipantHandler(acHandler, mock(AcLockHandler.class),
- mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
+ mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class),
+ mock(CacheProvider.class));
var propertyUpdateMsg = new PropertiesUpdate();
participantHandler.handleAcPropertyUpdate(propertyUpdateMsg);
verify(acHandler).handleAcPropertyUpdate(propertyUpdateMsg);
@@ -127,8 +136,8 @@ class ParticipantHandlerTest {
when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
when(cacheProvider.getReplicaId()).thenReturn(CommonTestData.getReplicaId());
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class),
- cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class),
+ mock(ParticipantMessagePublisher.class), cacheProvider);
var participantAckMsg = new ParticipantAckMessage(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY);
assertTrue(participantHandler.appliesTo(participantAckMsg));
@@ -147,7 +156,8 @@ class ParticipantHandlerTest {
when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
when(cacheProvider.getSupportedAcElementTypes()).thenReturn(List.of(new ParticipantSupportedElementType()));
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher,
+ cacheProvider);
participantHandler.sendParticipantRegister();
verify(publisher).sendParticipantRegister(any(ParticipantRegister.class));
@@ -159,7 +169,8 @@ class ParticipantHandlerTest {
var cacheProvider = mock(CacheProvider.class);
when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher,
+ cacheProvider);
participantHandler.handleParticipantRegisterAck(new ParticipantRegisterAck());
verify(publisher).sendParticipantStatus(any(ParticipantStatus.class));
@@ -171,7 +182,8 @@ class ParticipantHandlerTest {
var cacheProvider = mock(CacheProvider.class);
when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class), publisher,
+ cacheProvider);
participantHandler.sendParticipantDeregister();
verify(publisher).sendParticipantDeregister(any(ParticipantDeregister.class));
@@ -180,8 +192,8 @@ class ParticipantHandlerTest {
@Test
void handleParticipantDeregisterAckTest() {
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), mock(AcDefinitionHandler.class), mock(ParticipantMessagePublisher.class),
- mock(CacheProvider.class));
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), mock(AcDefinitionHandler.class),
+ mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
var participantDeregisterAck = new ParticipantDeregisterAck();
assertDoesNotThrow(() -> participantHandler.handleParticipantDeregisterAck(participantDeregisterAck));
}
@@ -194,8 +206,8 @@ class ParticipantHandlerTest {
var acHandler = mock(AcDefinitionHandler.class);
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), acHandler, mock(ParticipantMessagePublisher.class),
- mock(CacheProvider.class));
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler,
+ mock(ParticipantMessagePublisher.class), mock(CacheProvider.class));
participantHandler.handleParticipantPrime(participantPrime);
verify(acHandler).handlePrime(participantPrime);
@@ -213,7 +225,7 @@ class ParticipantHandlerTest {
var publisher = mock(ParticipantMessagePublisher.class);
var acHandler = mock(AcDefinitionHandler.class);
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), acHandler, publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler, publisher, cacheProvider);
participantHandler.handleParticipantSync(participantSyncMsg);
verify(acHandler).handleParticipantSync(participantSyncMsg);
@@ -229,7 +241,7 @@ class ParticipantHandlerTest {
when(publisher.isActive()).thenReturn(true);
var acHandler = mock(AcDefinitionHandler.class);
var participantHandler = new ParticipantHandler(mock(AutomationCompositionHandler.class),
- mock(AcLockHandler.class), acHandler, publisher, cacheProvider);
+ mock(AcLockHandler.class), mock(AcSubStateHandler.class), acHandler, publisher, cacheProvider);
participantHandler.sendHeartbeat();
verify(publisher).sendParticipantRegister(any(ParticipantRegister.class));
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
index f3471e6ee..57b065978 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
@@ -49,7 +49,7 @@ class ThreadHandlerTest {
private static final int TIMEOUT = 400;
@Test
- void test() throws PfModelException, IOException {
+ void testPrime() throws PfModelException, IOException {
var listener = mock(AutomationCompositionElementListener.class);
var intermediaryApi = mock(ParticipantIntermediaryApi.class);
try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
@@ -61,11 +61,45 @@ class ThreadHandlerTest {
verify(listener, timeout(TIMEOUT)).prime(composition);
clearInvocations(listener);
+ threadHandler.deprime(messageId, composition);
+ verify(listener, timeout(TIMEOUT)).deprime(composition);
+ }
+ }
+
+ @Test
+ void testPrimeException() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
+ var compositionId = UUID.randomUUID();
+ var composition = new CompositionDto(compositionId, Map.of(), Map.of());
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).prime(composition);
+ var messageId = UUID.randomUUID();
+ threadHandler.prime(messageId, composition);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
+ StateChangeResult.FAILED, "Composition Defintion prime failed");
+
+ clearInvocations(listener);
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition);
+ threadHandler.deprime(messageId, composition);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
+ StateChangeResult.FAILED, "Composition Defintion deprime failed");
+ }
+ }
+
+ @Test
+ void testDeploy() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
Map<String, Object> properties = Map.of("key", "value");
var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
properties, properties);
var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
- null, properties, properties);
+ null, properties, properties);
+ var messageId = UUID.randomUUID();
threadHandler.deploy(messageId, compositionElement, instanceElement);
verify(listener, timeout(TIMEOUT)).deploy(compositionElement, instanceElement);
@@ -88,43 +122,21 @@ class ThreadHandlerTest {
instanceElement, instanceElementUpdated);
clearInvocations(listener);
- threadHandler.lock(messageId, compositionElement, instanceElement);
- verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement);
-
- clearInvocations(listener);
- threadHandler.unlock(messageId, compositionElement, instanceElement);
- verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement);
-
- clearInvocations(listener);
threadHandler.undeploy(messageId, compositionElement, instanceElement);
verify(listener, timeout(TIMEOUT)).undeploy(compositionElement, instanceElement);
clearInvocations(listener);
threadHandler.delete(messageId, compositionElement, instanceElement);
verify(listener, timeout(TIMEOUT)).delete(compositionElement, instanceElement);
-
- clearInvocations(listener);
- threadHandler.deprime(messageId, composition);
- verify(listener, timeout(TIMEOUT)).deprime(composition);
}
}
@Test
- void testException() throws PfModelException, IOException {
+ void testDeployException() throws PfModelException, IOException {
var listener = mock(AutomationCompositionElementListener.class);
var intermediaryApi = mock(ParticipantIntermediaryApi.class);
try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
- var compositionId = UUID.randomUUID();
- var composition = new CompositionDto(compositionId, Map.of(), Map.of());
- doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
- .prime(composition);
- var messageId = UUID.randomUUID();
- threadHandler.prime(messageId, composition);
- verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
- StateChangeResult.FAILED, "Composition Defintion prime failed");
-
- clearInvocations(intermediaryApi);
Map<String, Object> properties = Map.of("key", "value");
var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
properties, properties);
@@ -135,9 +147,10 @@ class ThreadHandlerTest {
element.setId(elementId);
doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
.deploy(compositionElement, instanceElement);
+ var messageId = UUID.randomUUID();
threadHandler.deploy(messageId, compositionElement, instanceElement);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
+ DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
"Automation composition element deploy failed");
clearInvocations(listener);
@@ -147,44 +160,169 @@ class ThreadHandlerTest {
.update(compositionElement, instanceElement, instanceElementUpdated);
threadHandler.update(messageId, compositionElement, instanceElement, instanceElementUpdated);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- DeployState.DEPLOYED, null, StateChangeResult.FAILED,
- "Automation composition element update failed");
+ DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element update failed");
+
+ clearInvocations(listener);
+ var compositionTargetId = UUID.randomUUID();
+ var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(),
+ properties, properties);
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
+ .migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementUpdated);
+ threadHandler.migrate(messageId, compositionElement, compositionElementTarget,
+ instanceElement, instanceElementUpdated);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element migrate failed");
clearInvocations(listener);
doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
+ .undeploy(compositionElement, instanceElement);
+ threadHandler.undeploy(messageId, compositionElement, instanceElement);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element undeploy failed");
+
+ clearInvocations(listener);
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
+ .delete(compositionElement, instanceElement);
+ threadHandler.delete(messageId, compositionElement, instanceElement);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element delete failed");
+ }
+ }
+
+ @Test
+ void testLock() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
+ Map<String, Object> properties = Map.of("key", "value");
+ var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
+ properties, properties);
+ var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
+ null, properties, properties);
+ var messageId = UUID.randomUUID();
+ threadHandler.lock(messageId, compositionElement, instanceElement);
+ verify(listener, timeout(TIMEOUT)).lock(compositionElement, instanceElement);
+
+ clearInvocations(listener);
+ threadHandler.unlock(messageId, compositionElement, instanceElement);
+ verify(listener, timeout(TIMEOUT)).unlock(compositionElement, instanceElement);
+
+ clearInvocations(listener);
+ threadHandler.undeploy(messageId, compositionElement, instanceElement);
+ verify(listener, timeout(TIMEOUT)).undeploy(compositionElement, instanceElement);
+ }
+ }
+
+ @Test
+ void testLockException() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
+ Map<String, Object> properties = Map.of("key", "value");
+ var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
+ properties, properties);
+ var instanceId = UUID.randomUUID();
+ var elementId = UUID.randomUUID();
+ var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties);
+ var element = new AcElementDeploy();
+ element.setId(elementId);
+ var messageId = UUID.randomUUID();
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
.lock(compositionElement, instanceElement);
threadHandler.lock(messageId, compositionElement, instanceElement);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
+ null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
clearInvocations(listener);
doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
.unlock(compositionElement, instanceElement);
threadHandler.unlock(messageId, compositionElement, instanceElement);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
+ null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
+ }
+ }
+
+ @Test
+ void testSubState() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
+ Map<String, Object> properties = Map.of("key", "value");
+ var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
+ properties, properties);
+ var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(),
+ null, properties, properties);
+ var messageId = UUID.randomUUID();
+ threadHandler.prepare(messageId, compositionElement, instanceElement);
+ verify(listener, timeout(TIMEOUT)).prepare(compositionElement, instanceElement);
clearInvocations(listener);
+ threadHandler.review(messageId, compositionElement, instanceElement);
+ verify(listener, timeout(TIMEOUT)).review(compositionElement, instanceElement);
+
+ clearInvocations(listener);
+ var instanceElementMigrate = new InstanceElementDto(instanceElement.instanceId(),
+ instanceElement.elementId(), null, properties, properties);
+ var compositionTargetId = UUID.randomUUID();
+ var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(),
+ properties, properties);
+ threadHandler.migratePrecheck(messageId, compositionElement, compositionElementTarget,
+ instanceElement, instanceElementMigrate);
+ verify(listener, timeout(TIMEOUT)).migratePrecheck(compositionElement, compositionElementTarget,
+ instanceElement, instanceElementMigrate);
+ }
+ }
+
+ @Test
+ void testSubStateException() throws PfModelException, IOException {
+ var listener = mock(AutomationCompositionElementListener.class);
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
+
+ Map<String, Object> properties = Map.of("key", "value");
+ var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(),
+ properties, properties);
+ var instanceId = UUID.randomUUID();
+ var elementId = UUID.randomUUID();
+ var instanceElement = new InstanceElementDto(instanceId, elementId, null, properties, properties);
+ var element = new AcElementDeploy();
+ element.setId(elementId);
doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
- .undeploy(compositionElement, instanceElement);
- threadHandler.undeploy(messageId, compositionElement, instanceElement);
+ .prepare(compositionElement, instanceElement);
+ var messageId = UUID.randomUUID();
+ threadHandler.prepare(messageId, compositionElement, instanceElement);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- DeployState.DEPLOYED, null, StateChangeResult.FAILED,
- "Automation composition element undeploy failed");
+ DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element prepare Pre Deploy failed");
clearInvocations(listener);
doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
- .delete(compositionElement, instanceElement);
- threadHandler.delete(messageId, compositionElement, instanceElement);
+ .review(compositionElement, instanceElement);
+ threadHandler.review(messageId, compositionElement, instanceElement);
verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
- DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
- "Automation composition element delete failed");
+ DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element Review failed");
clearInvocations(listener);
- doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(composition);
- threadHandler.deprime(messageId, composition);
- verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
- StateChangeResult.FAILED, "Composition Defintion deprime failed");
+ var compositionTargetId = UUID.randomUUID();
+ var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(),
+ properties, properties);
+ var instanceElementMigrate = new InstanceElementDto(instanceElement.instanceId(),
+ instanceElement.elementId(), null, properties, properties);
+ doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
+ .migratePrecheck(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate);
+ threadHandler.migratePrecheck(messageId, compositionElement, compositionElementTarget,
+ instanceElement, instanceElementMigrate);
+ verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+ "Automation composition element migrate precheck failed");
}
}
}