LOGGER.debug("new element scenario");
}
if (ElementState.REMOVED.equals(instanceElementMigrate.state())) {
- simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId(),
- instanceElement.outProperties());
- simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId());
+ simulatorService.deleteInMigration(instanceElement.instanceId(), instanceElement.elementId());
} else {
simulatorService.migrate(instanceElementMigrate.instanceId(), instanceElementMigrate.elementId(), stage,
compositionElementTarget.inProperties(), instanceElementMigrate.outProperties());
}
}
+ /**
+ * Handle deleting an automation composition element in migration.
+ *
+ * @param instanceId the instanceId
+ * @param elementId the elementId
+ */
+ public void deleteInMigration(UUID instanceId, UUID elementId) {
+ if (getConfig().isMigrateSuccess()) {
+ intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
+ } else {
+ intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!");
+ }
+ }
+
/**
* Handle an update on an automation composition element.
*
Map.of("key", "value"), Map.of(), ElementState.REMOVED);
acElementHandler
.migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove, 0);
- verify(intermediaryApi).updateAutomationCompositionElementState(
- INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
- DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
verify(intermediaryApi).updateAutomationCompositionElementState(
INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(),
DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
testThread.interrupt();
testThread.join();
}
+
+ @Test
+ void testDeleteInMigration() {
+ var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+ var simulatorService = new SimulatorService(intermediaryApi);
+ var instanceId = UUID.randomUUID();
+ var elementId = UUID.randomUUID();
+ simulatorService.deleteInMigration(instanceId, elementId);
+ verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
+
+ simulatorService.getConfig().setMigrateSuccess(false);
+ simulatorService.deleteInMigration(instanceId, elementId);
+ verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, elementId,
+ DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Delete failed!");
+ }
}
@RequiredArgsConstructor
public class AutomationCompositionOutHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AutomationCompositionOutHandler.class);
+ private static final String MSG_NOT_PRESENT
+ = "Cannot update Automation composition element {}, {} id {} not present";
+ private static final String MSG_STATE_CHANGE = "Automation composition element {} state changed to {}";
+ private static final String MSG_AC = "Automation composition";
+ private static final String MSG_AC_ELEMENT = "AC Element";
+ private static final String MSG_STAGE = "stage";
private final ParticipantMessagePublisher publisher;
private final CacheProvider cacheProvider;
var automationComposition = cacheProvider.getAutomationComposition(instance);
if (automationComposition == null) {
- LOGGER.error("Cannot update Automation composition element stage, Automation composition id {} not present",
- instance);
+ LOGGER.error(MSG_NOT_PRESENT, MSG_STAGE, MSG_AC, instance);
return;
}
var element = automationComposition.getElements().get(elementId);
if (element == null) {
- var msg = "Cannot update Automation composition element stage, AC Element id {} not present";
- LOGGER.error(msg, elementId);
+ LOGGER.error(MSG_NOT_PRESENT, MSG_STAGE, MSG_AC_ELEMENT, elementId);
return;
}
var automationComposition = cacheProvider.getAutomationComposition(instance);
if (automationComposition == null) {
- LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
- instance);
+ LOGGER.error(MSG_NOT_PRESENT, "state", MSG_AC, instance);
return;
}
var element = automationComposition.getElements().get(elementId);
if (element == null) {
- var msg = "Cannot update Automation composition element state, AC Element id {} not present";
- LOGGER.error(msg, elementId);
+ checkElement(automationComposition, instance, elementId, deployState, stateChangeResult, message);
return;
}
handleLockState(automationComposition, element, lockState, stateChangeResult);
}
- var automationCompositionStateChangeAck =
- new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
- automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId());
- automationCompositionStateChangeAck.setReplicaId(cacheProvider.getReplicaId());
- automationCompositionStateChangeAck.setMessage(AcmUtils.validatedMessage(message));
- automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId()));
- automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult);
- automationCompositionStateChangeAck.setAutomationCompositionId(instance);
- automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(),
+ var acStateChangeAck = createAutomationCompositionDeployAck();
+ acStateChangeAck.setMessage(AcmUtils.validatedMessage(message));
+ acStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId()));
+ acStateChangeAck.setStateChangeResult(stateChangeResult);
+ acStateChangeAck.setAutomationCompositionId(instance);
+ acStateChangeAck.getAutomationCompositionResultMap().put(element.getId(),
new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(),
element.getUseState(), element.getOutProperties(), true, message));
- LOGGER.debug("Automation composition element {} state changed to {}", elementId, deployState);
- automationCompositionStateChangeAck.setResult(true);
- publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck);
+ LOGGER.debug(MSG_STATE_CHANGE, elementId, deployState);
+ publisher.sendAutomationCompositionAck(acStateChangeAck);
cacheProvider.getMsgIdentification().remove(element.getId());
}
+ private void checkElement(AutomationComposition automationComposition, UUID instance, UUID elementId,
+ DeployState deployState, StateChangeResult stateChangeResult, String message) {
+ if ((DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState()))) {
+ var acStateChangeAck = createAutomationCompositionDeployAck();
+ acStateChangeAck.setMessage(AcmUtils.validatedMessage(message));
+ acStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(elementId));
+ acStateChangeAck.setStateChangeResult(stateChangeResult);
+ acStateChangeAck.setAutomationCompositionId(instance);
+ acStateChangeAck.getAutomationCompositionResultMap().put(elementId,
+ new AcElementDeployAck(deployState, null, null,
+ null, Map.of(), true, message));
+ LOGGER.debug(MSG_STATE_CHANGE, elementId, deployState);
+ publisher.sendAutomationCompositionAck(acStateChangeAck);
+ cacheProvider.getMsgIdentification().remove(elementId);
+ } else {
+ LOGGER.error(MSG_NOT_PRESENT, "state", MSG_AC_ELEMENT, elementId);
+ }
+ }
+
+ private AutomationCompositionDeployAck createAutomationCompositionDeployAck() {
+ var acStateChangeAck =
+ new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
+ acStateChangeAck.setParticipantId(cacheProvider.getParticipantId());
+ acStateChangeAck.setReplicaId(cacheProvider.getReplicaId());
+ acStateChangeAck.setResult(true);
+ return acStateChangeAck;
+ }
+
private void handleDeployState(AutomationComposition automationComposition, AutomationCompositionElement element,
DeployState deployState, StateChangeResult stateChangeResult) {
element.setDeployState(deployState);
var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
if (automationComposition == null) {
- LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
- automationCompositionId);
+ LOGGER.error(MSG_NOT_PRESENT, "outProperites", MSG_AC, automationCompositionId);
return;
}
var element = automationComposition.getElements().get(elementId);
if (element == null) {
- var msg = "Cannot update Automation composition element state, AC Element id {} not present";
- LOGGER.error(msg, elementId);
+ LOGGER.error(MSG_NOT_PRESENT, "outProperites", MSG_AC_ELEMENT, elementId);
return;
}
element.setOperationalState(operationalState);
import org.onap.policy.clamp.acm.participant.intermediary.handler.cache.AutomationCompositionMsg;
import org.onap.policy.clamp.acm.participant.intermediary.handler.cache.CacheProvider;
import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantReqSync;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class MsgExecutor {
private final ExecutorService executor = Context.taskWrapping(Executors.newSingleThreadExecutor());
+ private static final Logger LOGGER = LoggerFactory.getLogger(MsgExecutor.class);
private final CacheProvider cacheProvider;
private final ParticipantMessagePublisher publisher;
message.setCompositionId(null);
message.setRevisionIdComposition(null);
} else {
+ LOGGER.debug("Composition {} missing or outdated", message.getCompositionId());
result = false;
}
}
message.setCompositionTargetId(null);
message.setRevisionIdCompositionTarget(null);
} else {
+ LOGGER.debug("Composition Target {} missing or outdated", message.getCompositionTargetId());
result = false;
}
}
message.setInstanceId(null);
message.setRevisionIdInstance(null);
} else {
+ LOGGER.debug("Instance {} missing or outdated", message.getInstanceId());
result = false;
}
}
*/
public Map<String, Object> getCommonProperties(@NonNull UUID compositionId,
@NonNull ToscaConceptIdentifier definition) {
- var map = acElementsDefinitions.get(compositionId).getElements().get(definition);
+ var acDefinition = acElementsDefinitions.get(compositionId);
+ if (acDefinition == null) {
+ return new HashMap<>();
+ }
+ var map = acDefinition.getElements().get(definition);
return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>();
}
*/
public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element) {
var acDefinition = acElementsDefinitions.get(compositionId);
- var acDefinitionElement = acDefinition.getElements().get(element.getDefinition());
+ var acDefinitionElement = acDefinition != null ? acDefinition.getElements().get(element.getDefinition()) : null;
return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, element.getDefinition(),
acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(),
assertDoesNotThrow(() -> ach.handleAutomationCompositionStateChange(automationCompositionStateChange));
}
+ @Test
+ void handleAcStateChangeUndeployTest() {
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ automationComposition.setCompositionId(UUID.randomUUID());
+ automationComposition.setInstanceId(UUID.randomUUID());
+ automationComposition.setCompositionTargetId(UUID.randomUUID());
+ var participantDeploy =
+ CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition);
+
+ var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters());
+ cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(),
+ automationComposition.getInstanceId(), participantDeploy, UUID.randomUUID());
+
+ var automationCompositionStateChange = CommonTestData.getStateChange(CommonTestData.getParticipantId(),
+ automationComposition.getInstanceId(), DeployOrder.UNDEPLOY, LockOrder.NONE);
+
+ var participantMessagePublisher = mock(ParticipantMessagePublisher.class);
+ var listener = mock(ThreadHandler.class);
+ var ach = new AutomationCompositionHandler(cacheProvider, participantMessagePublisher, listener);
+ ach.handleAutomationCompositionStateChange(automationCompositionStateChange);
+ automationComposition = cacheProvider.getAutomationComposition(automationComposition.getInstanceId());
+ verify(listener, times(automationComposition.getElements().size())).undeploy(any(), any(), any());
+ for (var element : automationComposition.getElements().values()) {
+ assertEquals(DeployState.UNDEPLOYING, element.getDeployState());
+ }
+ }
+
@Test
void handleAutomationCompositionStateChangeUndeployTest() {
var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
.sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class));
assertEquals(compositionId, automationComposition.getCompositionId());
}
+
+ @Test
+ void deleteFailMigrationTest() {
+ var cacheProvider = mock(CacheProvider.class);
+ when(cacheProvider.getParticipantId()).thenReturn(UUID.randomUUID());
+
+ var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next();
+ when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+
+ automationComposition.setCompositionTargetId(UUID.randomUUID());
+ automationComposition.setDeployState(DeployState.MIGRATING);
+ var publisher = mock(ParticipantMessagePublisher.class);
+ var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider);
+ acOutHandler.updateAutomationCompositionElementState(automationComposition.getInstanceId(),
+ UUID.randomUUID(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "");
+ verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class));
+ }
}
private UpdateSync handleAcStateChange(AutomationComposition automationComposition, DocMessage message) {
var result = new UpdateSync();
var element = automationComposition.getElements().get(message.getInstanceElementId());
+ if (element == null && isMigration(automationComposition)
+ && StateChangeResult.FAILED.equals(message.getStateChangeResult())) {
+ // fail delete element during migration
+ automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+ result.setUpdated(true);
+ result.setToBeSync(true);
+ return result;
+ }
if (element == null || !validateStateMessage(automationComposition, message)) {
return result;
}
return result;
}
+ private boolean isMigration(AutomationComposition automationComposition) {
+ return DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState());
+ }
+
private boolean validateStateMessage(AutomationComposition automationComposition, DocMessage message) {
return !DeployState.DELETED.equals(message.getDeployState())
|| (DeployState.DELETING.equals(automationComposition.getDeployState()));
}
private AutomationComposition createDeploying() {
- var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
- automationComposition.setInstanceId(INSTANCE_ID);
- automationComposition.setDeployState(DeployState.DEPLOYING);
- automationComposition.setLockState(LockState.NONE);
- automationComposition.setPhase(0);
- automationComposition.setLastMsg(TimestampHelper.now());
- automationComposition.setCompositionId(COMPOSITION_ID);
- for (var element : automationComposition.getElements().values()) {
- element.setDeployState(DeployState.DEPLOYING);
- element.setLockState(LockState.NONE);
- }
- return automationComposition;
+ return createAutomationComposition(DeployState.DEPLOYING, LockState.NONE);
}
@Test
void testSendAutomationCompositionMigratingPrecheck() {
- var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
- automationComposition.setLockState(LockState.LOCKED);
- automationComposition.setDeployState(DeployState.DEPLOYED);
+ var automationComposition = createAutomationComposition(DeployState.DEPLOYED, LockState.LOCKED);
automationComposition.setSubState(SubState.MIGRATION_PRECHECKING);
for (var element : automationComposition.getElements().values()) {
- element.setDeployState(DeployState.DEPLOYED);
element.setSubState(SubState.NONE);
- element.setLockState(LockState.LOCKED);
if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
element.setSubState(SubState.MIGRATION_PRECHECKING);
}
@Test
void testSendAutomationCompositionPrepare() {
- var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
- automationComposition.setLockState(LockState.NONE);
- automationComposition.setDeployState(DeployState.UNDEPLOYED);
+ var automationComposition = createAutomationComposition(DeployState.UNDEPLOYED, LockState.NONE);
automationComposition.setSubState(SubState.PREPARING);
for (var element : automationComposition.getElements().values()) {
- element.setDeployState(DeployState.UNDEPLOYED);
element.setSubState(SubState.NONE);
- element.setLockState(LockState.NONE);
if (ELEMENT_NAME.equals(element.getDefinition().getName())) {
element.setSubState(SubState.PREPARING);
}
simpleScanner.simpleScan(automationComposition, new UpdateSync());
verify(acProvider).updateAutomationComposition(any());
}
+
+ @Test
+ void testScanMessageMigrationFail() {
+ var automationComposition = createAutomationComposition(DeployState.MIGRATING, LockState.LOCKED);
+ var elementId = UUID.randomUUID();
+ var docMessage = new DocMessage();
+ docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
+ docMessage.setStateChangeResult(StateChangeResult.FAILED);
+ docMessage.setInstanceId(INSTANCE_ID);
+ docMessage.setInstanceElementId(elementId);
+ docMessage.setDeployState(DeployState.UNDEPLOYED);
+ docMessage.setLockState(LockState.NONE);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+ var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
+ acRuntimeParameterGroup, new EncryptionUtils(acRuntimeParameterGroup));
+ var result = simpleScanner.scanMessage(automationComposition, docMessage);
+ assertTrue(result.isUpdated());
+ assertTrue(result.isToBeSync());
+ }
+
+ private AutomationComposition createAutomationComposition(DeployState deployState, LockState lockState) {
+ var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
+ automationComposition.setInstanceId(INSTANCE_ID);
+ automationComposition.setDeployState(deployState);
+ automationComposition.setLockState(lockState);
+ automationComposition.setPhase(0);
+ automationComposition.setLastMsg(TimestampHelper.now());
+ automationComposition.setCompositionId(COMPOSITION_ID);
+ for (var element : automationComposition.getElements().values()) {
+ element.setDeployState(deployState);
+ element.setLockState(lockState);
+ }
+ return automationComposition;
+ }
}