Extend the functionality of deletion step to also inform the participant of instance deletion. This allow the participant to take any necessary steps that might result from instance deletion.
Issue-ID: POLICY-4686
Change-Id: Ibeb44d472da20ad98dafa9ddd7ded28398f4ed10
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
DEPLOYED,
DEPLOYING,
UNDEPLOYED,
- UNDEPLOYING
+ UNDEPLOYING,
+ DELETING,
+ DELETED
}
public enum DeployOrder {
NONE,
UNDEPLOY,
- DEPLOY
+ DEPLOY,
+ DELETE
}
// list of results
public static final String DEPLOY = DeployOrder.DEPLOY.name();
public static final String UNDEPLOY = DeployOrder.UNDEPLOY.name();
+ public static final String DELETE = DeployOrder.DELETE.name();
public static final String LOCK = LockOrder.LOCK.name();
public static final String UNLOCK = LockOrder.UNLOCK.name();
public static final String NONE = "NONE";
this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYED, STATE_LOCKED_NONE}, DEPLOY);
this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYED, LOCKED}, UNDEPLOY);
+ this.graph.put(new String[] {DELETE, LOCK_NONE, UNDEPLOYED, LOCK_NONE}, DELETE);
this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKED}, UNLOCK);
this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKED}, LOCK);
}
var jpa = acElementRepository.getReferenceById(element.getAutomationCompositionElementId().toString());
jpa.setUseState(element.getUseState());
jpa.setOperationalState(element.getOperationalState());
- jpa.setProperties(element.getStatusProperties());
+ jpa.setStatusProperties(element.getStatusProperties());
jpaList.add(jpa);
}
}
*/
public static boolean isInTransitionalState(DeployState deployState, LockState lockState) {
return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState)
- || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState);
+ || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState)
+ || DeployState.DELETING.equals(deployState);
}
/**
* @return the DeployOrder
*/
public static DeployOrder stateDeployToOrder(DeployState deployState) {
- if (DeployState.DEPLOYING.equals(deployState)) {
- return DeployOrder.DEPLOY;
- } else if (DeployState.UNDEPLOYING.equals(deployState)) {
- return DeployOrder.UNDEPLOY;
+ DeployOrder result = null;
+ switch (deployState) {
+ case DEPLOYING:
+ result = DeployOrder.DEPLOY;
+ break;
+
+ case UNDEPLOYING:
+ result = DeployOrder.UNDEPLOY;
+ break;
+
+ case DELETING:
+ result = DeployOrder.DELETE;
+ break;
+
+ default:
+ result = DeployOrder.NONE;
}
- return DeployOrder.NONE;
+ return result;
}
/**
* @return the DeployState
*/
public static DeployState deployCompleted(DeployState deployState) {
- if (DeployState.DEPLOYING.equals(deployState)) {
- return DeployState.DEPLOYED;
- } else if (DeployState.UNDEPLOYING.equals(deployState)) {
- return DeployState.UNDEPLOYED;
+ DeployState result = null;
+ switch (deployState) {
+ case DEPLOYING:
+ result = DeployState.DEPLOYED;
+ break;
+
+ case UNDEPLOYING:
+ result = DeployState.UNDEPLOYED;
+ break;
+
+ case DELETING:
+ result = DeployState.DELETED;
+ break;
+
+ default:
+ return deployState;
}
- return deployState;
+ return result;
}
/**
// from transitional state to order state
assertEquals(DeployOrder.DEPLOY, AcmUtils.stateDeployToOrder(DeployState.DEPLOYING));
assertEquals(DeployOrder.UNDEPLOY, AcmUtils.stateDeployToOrder(DeployState.UNDEPLOYING));
+ assertEquals(DeployOrder.DELETE, AcmUtils.stateDeployToOrder(DeployState.DELETING));
assertEquals(DeployOrder.NONE, AcmUtils.stateDeployToOrder(DeployState.DEPLOYED));
}
assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYING));
assertEquals(DeployState.UNDEPLOYED, AcmUtils.deployCompleted(DeployState.UNDEPLOYING));
assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYED));
+ assertEquals(DeployState.DELETED, AcmUtils.deployCompleted(DeployState.DELETING));
}
@Test
throws PfModelException {
// default Unlock Operation
}
+
+ public default void delete(UUID automationCompositionId, UUID automationCompositionElementId)
+ throws PfModelException {
+ // default Delete Operation
+ }
}
import java.util.Map;
import java.util.UUID;
+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.LockState;
void updateAutomationCompositionElementState(UUID automationCompositionId, UUID id, DeployState deployState,
LockState lockState, String message);
+ /**
+ * Get AutomationCompositions.
+ *
+ * @return get all AutomationCompositions
+ */
+ Map<UUID, AutomationComposition> getAutomationCompositions();
+
/**
* Send Automation Composition Element update Info to AC-runtime.
*
import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
import org.onap.policy.clamp.acm.participant.intermediary.handler.AutomationCompositionHandler;
+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.LockState;
+import org.onap.policy.models.base.PfUtils;
import org.springframework.stereotype.Component;
/**
automationCompositionHandler.sendAcElementInfo(automationCompositionId, elementId, useState, operationalState,
statusProperties);
}
+
+ @Override
+ public Map<UUID, AutomationComposition> getAutomationCompositions() {
+ return PfUtils.mapMap(automationCompositionHandler.getAutomationCompositionMap(), AutomationComposition::new);
+ }
}
if (deployState != null) {
element.setDeployState(deployState);
+ element.setLockState(
+ DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
var checkOpt = automationComposition.getElements().values().stream()
.filter(acElement -> !deployState.equals(acElement.getDeployState())).findAny();
if (checkOpt.isEmpty()) {
automationComposition.setDeployState(deployState);
+ automationComposition.setLockState(element.getLockState());
}
- element.setLockState(
- DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
}
if (lockState != null) {
element.setLockState(lockState);
if (!checkConsistantOrderState(automationComposition, stateChangeMsg.getDeployOrderedState(),
stateChangeMsg.getLockOrderedState())) {
- var automationCompositionAck =
- new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
- automationCompositionAck.setParticipantId(participantId);
- automationCompositionAck.setMessage("Automation composition is already in state "
- + stateChangeMsg.getDeployOrderedState() + " and " + stateChangeMsg.getLockOrderedState());
- automationCompositionAck.setResult(false);
- automationCompositionAck.setAutomationCompositionId(automationComposition.getInstanceId());
- publisher.sendAutomationCompositionAck(automationCompositionAck);
+ LOGGER.warn("Not Consistant OrderState Automation composition {}",
+ stateChangeMsg.getAutomationCompositionId());
return;
}
private void handleDeployOrderState(final AutomationComposition automationComposition, DeployOrder orderedState,
Integer startPhaseMsg, List<AutomationCompositionElementDefinition> acElementDefinitions) {
- if (DeployOrder.UNDEPLOY.equals(orderedState)) {
- handleUndeployState(automationComposition, startPhaseMsg, acElementDefinitions);
- } else {
- LOGGER.debug("StateChange message has no state, state is null {}", automationComposition.getKey());
+ switch (orderedState) {
+ case UNDEPLOY:
+ handleUndeployState(automationComposition, startPhaseMsg, acElementDefinitions);
+ break;
+ case DELETE:
+ handleDeleteState(automationComposition, startPhaseMsg, acElementDefinitions);
+ break;
+
+ default:
+ LOGGER.debug("StateChange message has no state, state is null {}", automationComposition.getKey());
+ break;
}
}
}
private void initializeDeploy(UUID messageId, UUID instanceId, ParticipantDeploy participantDeploy) {
- var automationComposition = automationCompositionMap.get(instanceId);
-
- if (automationComposition != null) {
- var automationCompositionUpdateAck =
- new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
- automationCompositionUpdateAck.setParticipantId(participantId);
-
- automationCompositionUpdateAck.setMessage(
- "Automation composition " + instanceId + " already defined on participant " + participantId);
- automationCompositionUpdateAck.setResult(false);
- automationCompositionUpdateAck.setResponseTo(messageId);
- automationCompositionUpdateAck.setAutomationCompositionId(instanceId);
- publisher.sendAutomationCompositionAck(automationCompositionUpdateAck);
- return;
- }
-
- automationComposition = new AutomationComposition();
+ var automationComposition = new AutomationComposition();
automationComposition.setInstanceId(instanceId);
var acElements = storeElementsOnThisParticipant(participantDeploy);
automationComposition.setElements(prepareAcElementMap(acElements));
automationComposition.getElements().values().stream()
.forEach(acElement -> automationCompositionElementUndeploy(automationComposition.getInstanceId(),
acElement, startPhaseMsg, acElementDefinitions));
+ }
+
+ private void handleDeleteState(final AutomationComposition automationComposition, Integer startPhaseMsg,
+ List<AutomationCompositionElementDefinition> acElementDefinitions) {
+
+ automationComposition.getElements().values().stream()
+ .forEach(acElement -> automationCompositionElementDelete(automationComposition.getInstanceId(),
+ acElement, startPhaseMsg, acElementDefinitions));
boolean isAllUninitialised = automationComposition.getElements().values().stream()
- .filter(element -> !DeployState.UNDEPLOYED.equals(element.getDeployState())).findAny().isEmpty();
+ .filter(element -> !DeployState.DELETED.equals(element.getDeployState())).findAny().isEmpty();
if (isAllUninitialised) {
automationCompositionMap.remove(automationComposition.getInstanceId());
}
}
}
+ private void automationCompositionElementDelete(UUID instanceId, AutomationCompositionElement acElement,
+ Integer startPhaseMsg, List<AutomationCompositionElementDefinition> acElementDefinitions) {
+ var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, acElement.getDefinition());
+ if (acElementNodeTemplate != null) {
+ int startPhase = ParticipantUtils.findStartPhase(acElementNodeTemplate.getProperties());
+ if (startPhaseMsg.equals(startPhase)) {
+ for (var acElementListener : listeners) {
+ try {
+ acElementListener.delete(instanceId, acElement.getId());
+ updateAutomationCompositionElementState(instanceId, acElement.getId(), DeployState.DELETED,
+ null, "Deleted");
+ } catch (PfModelException e) {
+ LOGGER.error("Automation composition element unlock failed {}", instanceId);
+ }
+ }
+ }
+ }
+ }
/**
* Undeploy Instance Elements On Participant.
"Automation composition state is still " + automationComposition.getDeployState());
}
var response = new InstantiationResponse();
- automationComposition =
- automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
+ var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
+ supervisionAcHandler.delete(automationComposition, acDefinition);
response.setInstanceId(automationComposition.getInstanceId());
response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
return response;
automationCompositionStateChangePublisher.send(automationComposition, startPhase, true);
}
+ /**
+ * Handle Delete an AutomationComposition instance.
+ *
+ * @param automationComposition the AutomationComposition
+ * @param acDefinition the AutomationCompositionDefinition
+ */
+ public void delete(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
+ AcmUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+ automationCompositionStateChangePublisher.send(automationComposition, startPhase, true);
+ }
+
/**
* Handle a AutomationComposition deploy acknowledge message from a participant.
*
}
private void setAcElementStateInDb(AutomationCompositionDeployAck automationCompositionAckMessage) {
- if (automationCompositionAckMessage.getAutomationCompositionResultMap() != null) {
- var automationComposition = automationCompositionProvider
- .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId());
- if (automationComposition.isPresent()) {
- var updated = updateState(automationComposition.get(),
- automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet());
- if (updated) {
- automationCompositionProvider.updateAutomationComposition(automationComposition.get());
- }
+ var automationComposition = automationCompositionProvider
+ .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId());
+ if (automationComposition.isEmpty()) {
+ LOGGER.warn("AutomationComposition not found in database {}",
+ automationCompositionAckMessage.getAutomationCompositionId());
+ return;
+ }
+
+ if (automationCompositionAckMessage.getAutomationCompositionResultMap() == null
+ || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) {
+ if (DeployState.DELETING.equals(automationComposition.get().getDeployState())) {
+ // scenario when Automation Composition instance has never been deployed
+ automationComposition.get().getElements().values()
+ .forEach(element -> element.setDeployState(DeployState.DELETED));
+ automationCompositionProvider.updateAutomationComposition(automationComposition.get());
} else {
- LOGGER.warn("AutomationComposition not found in database {}",
- automationCompositionAckMessage.getAutomationCompositionId());
+ LOGGER.warn("Empty AutomationCompositionResultMap {} {}",
+ automationCompositionAckMessage.getAutomationCompositionId(),
+ automationCompositionAckMessage.getMessage());
}
+ return;
+ }
+
+ var updated = updateState(automationComposition.get(),
+ automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet());
+ if (updated) {
+ automationCompositionProvider.updateAutomationComposition(automationComposition.get());
}
}
if (element != null) {
element.setDeployState(acElementAck.getValue().getDeployState());
element.setLockState(acElementAck.getValue().getLockState());
- if (DeployState.DEPLOYED.equals(element.getDeployState())) {
- element.setOperationalState(acElementAck.getValue().getOperationalState());
- element.setUseState(acElementAck.getValue().getUseState());
- element.setStatusProperties(acElementAck.getValue().getStatusProperties());
- } else {
- element.setOperationalState(null);
- element.setUseState(null);
- element.setStatusProperties(Map.of());
- }
+ element.setOperationalState(acElementAck.getValue().getOperationalState());
+ element.setUseState(acElementAck.getValue().getUseState());
+ element.setStatusProperties(acElementAck.getValue().getStatusProperties());
updated = true;
}
}
LOGGER.debug("automation composition scan: transition state {} {} ", automationComposition.getDeployState(),
automationComposition.getLockState());
- var deployState = automationComposition.getDeployState();
- automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
- automationComposition
- .setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
- automationCompositionProvider.updateAutomationComposition(automationComposition);
-
- // Clear missed report counter on automation composition
- clearFaultAndCounter(automationComposition);
+ complete(automationComposition);
} else {
LOGGER.debug("automation composition scan: transition from state {} to {} not completed",
automationComposition.getDeployState(), automationComposition.getLockState());
}
}
+ private void complete(final AutomationComposition automationComposition) {
+ var deployState = automationComposition.getDeployState();
+ automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
+ automationComposition
+ .setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
+ if (DeployState.DELETED.equals(automationComposition.getDeployState())) {
+ automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
+ } else {
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ }
+
+ // Clear missed report counter on automation composition
+ clearFaultAndCounter(automationComposition);
+ }
+
private void clearFaultAndCounter(AutomationComposition automationComposition) {
automationCompositionCounter.clear(automationComposition.getInstanceId());
phaseMap.remove(automationComposition.getInstanceId());
var compositionId = acDefinition.getCompositionId();
when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
var acProvider = mock(AutomationCompositionProvider.class);
- var instantiationProvider =
- new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null);
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ null, supervisionAcHandler);
var automationCompositionCreate =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
automationCompositionCreate.setCompositionId(compositionId);
instantiationProvider.deleteAutomationComposition(automationCompositionCreate.getCompositionId(),
automationCompositionCreate.getInstanceId());
- verify(acProvider).deleteAutomationComposition(automationCompositionCreate.getInstanceId());
+ verify(supervisionAcHandler).delete(any(), any());
}
@Test
var acProvider = mock(AutomationCompositionProvider.class);
var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
- acDefinitionProvider, null, null);
+ acDefinitionProvider, null, supervisionAcHandler);
when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
.thenReturn(automationComposition);
when(acProvider.deleteAutomationComposition(instanceId)).thenReturn(automationComposition);
instantiationProvider.deleteAutomationComposition(compositionId, instanceId);
+ verify(supervisionAcHandler).delete(any(), any());
}
private void assertThatDeleteThrownBy(AutomationComposition automationComposition,
import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion());
- assertThat(automationCompositionsFromDb.getAutomationCompositionList()).isEmpty();
+ assertEquals(DeployState.DELETING,
+ automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
}
@Test
acRuntimeParameterGroup);
supervisionScanner.run(false);
- verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class));
+ verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testScannerDelete() {
+ var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
+ automationComposition.setDeployState(DeployState.DELETING);
+ automationComposition.setLockState(LockState.NONE);
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
+ .thenReturn(List.of(automationComposition));
+
+ var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+ automationCompositionStateChangePublisher, automationCompositionDeployPublisher,
+ acRuntimeParameterGroup);
+ supervisionScanner.run(false);
+
+ verify(automationCompositionProvider).deleteAutomationComposition(automationComposition.getInstanceId());
}
@Test