Add state support in fail scenario

Allowed state from the participant perspective

Action

state

stChResult

Description

Prime

PRIMED

NO_ERROR

Prime is completed

COMMISSIONED

FAILED

Prime is failed

Deprime

COMMISSIONED

NO_ERROR

Deprime is completed

PRIMED

FAILED

Deprime is failed

 

Action

deployState

lockState

stChResult

Description

Deploy

DEPLOYED

 

NO_ERROR

Deploy is completed

UNDEPLOYED

 

FAILED

Deploy is failed

Undeploy

UNDEPLOYED

 

NO_ERROR

Undeploy is completed

DEPLOYED

 

FAILED

Undeploy is failed

Lock

 

LOCKED

NO_ERROR

Lock is completed

 

UNLOCKED

FAILED

Lock is failed

Unlock

 

UNLOCKED

NO_ERROR

Unlock is completed

 

LOCKED

FAILED

Unlock is failed

Update

DEPLOYED

 

NO_ERROR

Update is completed

DEPLOYED

 

FAILED

Update is failed

Migrate

DEPLOYED

 

NO_ERROR

Migrate is completed

DEPLOYED

 

FAILED

Migrate is failed

Delete

DELETED

 

NO_ERROR

Delete is completed

UNDEPLOYED

 

FAILED

Delete is failed

Handle states and failure scenarios from the participant perspective

It is important to make distinction between the state of the instance/element flow, and the state of the application/configuration involved.
A deployed element means that a participant has completed a deploy action, and should not be confused with a deployed application.

Example with two elements:

  1. an instance is deployed, so the two elements are DEPLOYED

  2. user calls undeploy command (ACM-R sets all element as DEPLOYING)

  3. participant executes the first instance element with success and sends UNDEPLOYED state

  4. participant executes the second instance element with fail and sends DEPLOYED state

  5. user calls undeploy command again (ACM-R sets all element as DEPLOYING)

  6. participant does not know that the application related to the first element is already UNDEPLOYED when the flow state is UNDEPLOYING

There are some contexts in a failure scenario that the participant need to know the state of the deployed application. From participant side, using “outProperties” it could be possible to handle custom states that better suit whit the context.

Solutions

Example of a participant that deploy/undeploy applications.
The following Java code shows how to implement deploy and undeploy that avoid to repeat the action already executed.

@Override public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { if ("DEPLOYED".equals(instanceElement.outProperties().get("state"))) { // deploy process already done intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Already Deployed"); return; }         // deployment process      ....................................... ....................................... // end of the deployment process if (isDeploySuccess()) { instanceElement.outProperties().put("state", "DEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties());     intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); } else { instanceElement.outProperties().put("state", "UNDEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties());            intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!"); }   } @Override   public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { if ("DEPLOYED".equals(instanceElement.outProperties().get("state"))) {           // undeploy process already done intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Already Undeployed"); return;        } // undeployment process      ....................................... ....................................... // end of the undeployment process       if (isUndeploySuccess()) { instanceElement.outProperties().put("state", "UNDEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties()); intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); } else { instanceElement.outProperties().put("state", "DEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties()); intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!"); }    }

 

Example of a participant that make configurations.
The following Java code shows how to implement deploy and undeploy that needs a clean up and repeat the action. The state of the configuration will saved in outProperties.

@Override public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { var state = instanceElement.outProperties().get("state"); if ("DEPLOYED".equals(state)) { // clean up deployment } else if ("DEPLOYING".equals(state) || "UNDEPLOYING".equals(state)) { // check and clean up }       // deployment process   instanceElement.outProperties().put("state", "DEPLOYING"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties()); .......................................       ....................................... ....................................... // end of the deployment process             if (isDeploySuccess()) { instanceElement.outProperties().put("state", "DEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties());     intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed"); } else { instanceElement.outProperties().put("state", "UNDEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties());            intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!"); }    } @Override   public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException { var state = instanceElement.outProperties().get("state"); if ("UNDEPLOYED".equals(state)) { // clean up undeployment } else if ("DEPLOYING".equals(state) || "UNDEPLOYING".equals(state)) { // check and clean up }        // undeployment process   instanceElement.outProperties().put("state", "UNDEPLOYING"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties());     ....................................... .......................................       ....................................... ....................................... // end of the undeployment process       if (isUndeploySuccess()) { instanceElement.outProperties().put("state", "UNDEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties()); intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed"); } else { instanceElement.outProperties().put("state", "DEPLOYED"); intermediaryApi.sendAcElementInfo(instanceElement.instanceId(), instanceElement.elementId(), null, null, instanceElement.outProperties()); intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!"); }   }

 

Final consideration: In all suggestions shown before we have used labels as "DEPLOY", "UNDEPLOY", "DEPLOYING", "UNDEPLOYING" but the developer can change them as better suit with the context of the participant.