Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Major version backward compatibility : can 9.0.0 ACM-runtime has to be backward compatible with 8.0.0? How many versions? can ACM-runtime 9.0.0 has to be backward compatible with ACM-runtime 7.0.0?
  2. Minor version backward compatibility:  as example, any 8.x.0 ACM-runtime has to be backward compatible with all ACM-runtime 8.y.0 versions.
  3. Decouple between ACM-runtime and intermediary library: ACM-runtime 8.x.0 version has to be backward compatible with all intermediary library 8.y.0 versions.
  4. Participant java code backward compatibility: intermediary library 9.0.0 version has to be java code backward compatible with participant 8.0.0 version.

What impacts backward compatibility?

  • Rest Api call
  • Messages between ACM-runtime and intermediary library
  • interfaces AutomationCompositionElementListener and ParticipantIntermediaryApi
  • properties file of ACM-runtime and Participant

What could help the backward compatibility?

  • ability to handle multi major versions by Rest Api: high expensive to develop and maintain, also it will increasing the footprint.
  • abstract classes to help the implementation of AutomationCompositionElementListener. It will avoid to break existing code when new intermediary library version is released.

What the current integration tests does? it tests ACM-runtime and intermediary library of last version with the following flows:

  • Composition Definition: create, prime, deprime and delete
  • AC instance: create, deploy, undeploy and delete

Maybe it needs to add into the integration tests all new functionalities recently developed using participant-simulator.

About the regression tests, the only flows that could be tested will be based on what functionalities support the older version installed for the test.

Java code backward compatibility

Example of refactoring of  the  interface "AutomationCompositionElementListener " in New Delhi release.

  1. is not recommended.

What impacts backward compatibility?

  • Rest Api call
  • Messages between ACM-runtime and intermediary library
  • interfaces AutomationCompositionElementListener and ParticipantIntermediaryApi
  • properties file of ACM-runtime and Participant

What could help the backward compatibility?

  • ability to handle multi major versions by Rest Api: high expensive to develop and maintain, also it will increasing the footprint.
  • abstract classes to help the implementation of AutomationCompositionElementListener. It will avoid to break existing code when new intermediary library version is released.

What the current integration tests does? it tests ACM-runtime and intermediary library of last version with the following flows:

  • Composition Definition: create, prime, deprime and delete
  • AC instance: create, deploy, undeploy and delete

Maybe it needs to add into the integration tests all new functionalities recently developed using participant-simulator.

About the regression tests, the only flows that could be tested will be based on what functionalities support the older version installed for the test.

Java code backward compatibility

Example of refactoring of  the  interface "AutomationCompositionElementListener " in New Delhi release.

Code Block
languagejava
titleAutomationCompositionElementListener
public record CompositionDto(UUID compositionId,
     Map<ToscaConceptIdentifier, Map<String, Object>> inPropertiesMap,
     Map<ToscaConceptIdentifier, Map<String, Object>> outPropertiesMap) {
}

public record CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId,
     Map<String, Object> inProperties, Map<String, Object> outProperties) {
}

public record InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment,
     Map<String, Object> inProperties, Map<String, Object> outProperties) {
}


/**
 * This interface is implemented by participant implementations to receive updates on automation composition elements.
 * Valid since New Delhi release.
 */
public interface AutomationCompositionElementListener {
    void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
                InstanceElementDto instanceElementUpdated) throws PfModelException;

    void prime(CompositionDto composition) throws PfModelException;

    void deprime(CompositionDto composition) throws PfModelException;

    void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException;

    void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
                               DeployState deployState, LockState lockState) throws PfModelException;

    void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
                 InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException;

    void migratePrecheck(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
                 InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException;
}

Note: "migratePrecheck" is just an example and it will be not delivered in Q1. That example shown how we can handle new functionality.

Wrapper class "AcElementListenerV1" for participant that was developed in Montreal release

Code Block
languagejava
titleAcElementListenerV1
/**
 * Wrapper of AutomationCompositionElementListener.
 * Valid since 7.1.1 release.
 */
public abstract class AcElementListenerV1 implements AutomationCompositionElementListener {

    protected final ParticipantIntermediaryApi intermediaryApi;

    protected  AcElementListenerV1(ParticipantIntermediaryApi intermediaryApi) {
        this.intermediaryApi = intermediaryApi;
    }

    @Override
    public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        var element = new AcElementDeploy();
        element.setId(instanceElement.elementId());
        element.setDefinition(compositionElement.elementDefinitionId());
        element.setToscaServiceTemplateFragment(instanceElement.toscaServiceTemplateFragment());
        element.setProperties(instanceElement.inProperties());
        Map<String, Object> properties = new HashMap<>(instanceElement.inProperties());
        properties.putAll(compositionElement.inProperties());
        deploy(instanceElement.instanceId(), element, properties);
    }

    public abstract void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> properties)
        throws PfModelException;

    @Override
    public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        undeploy(instanceElement.instanceId(), instanceElement.elementId());
    }

    public abstract void undeploy(UUID instanceId, UUID elementId) throws PfModelException;

    @Override
    public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        lock(instanceElement.instanceId(), instanceElement.elementId());
    }

    public abstract void lock(UUID instanceId, UUID elementId) throws PfModelException;

    @Override
    public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        unlock(instanceElement.instanceId(), instanceElement.elementId());
    }

    public abstract void unlock(UUID instanceId, UUID elementId) throws PfModelException;

    @Override
    public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        delete(instanceElement.instanceId(), instanceElement.elementId());
    }

    public abstract void delete(UUID instanceId, UUID elementId) throws PfModelException;

    @Override
    public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
                       InstanceElementDto instanceElementUpdated) throws PfModelException {
        var element = new  AcElementDeploy();
        element.setId(instanceElementUpdated.elementId());
        element.setDefinition(compositionElement.elementDefinitionId());
        element.setProperties(instanceElementUpdated.inProperties());
        update(instanceElementUpdated.instanceId(), element, element.getProperties());
    }

    public abstract void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties)
        throws PfModelException;

    private List<AutomationCompositionElementDefinition> createAcElementDefinitionList(CompositionDto composition) {
        List<AutomationCompositionElementDefinition> elementDefinitionList = new ArrayList<>();
        for (var entry : composition.inPropertiesMap().entrySet()) {
            elementDefinitionList.add(createAcElementDefinition(entry.getKey(), entry.getValue(),
                composition.outPropertiesMap().get(entry.getKey())));
        }
        return elementDefinitionList;
    }

    private AutomationCompositionElementDefinition createAcElementDefinition(
        ToscaConceptIdentifier toscaConceptIdentifier, Map<String, Object> property,
        Map<String, Object> outProperties) {
        var acElementDefinition = new AutomationCompositionElementDefinition();
        acElementDefinition.setAcElementDefinitionId(toscaConceptIdentifier);
        var toscaNodeTemplate = new ToscaNodeTemplate();
        toscaNodeTemplate.setProperties(property);
        acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(toscaNodeTemplate);
        acElementDefinition.setOutProperties(outProperties);
        return acElementDefinition;
    }

    @Override
    public void prime(CompositionDto composition) throws PfModelException {
        prime(composition.compositionId(), createAcElementDefinitionList(composition));
    }

    public abstract void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList)
Code Block
languagejava
titleAutomationCompositionElementListener
public record CompositionDto(UUID compositionId,
        throws PfModelException;

    @Override
    public void deprime(CompositionDto composition) throws PfModelException {
        deprime(composition.compositionId());
    }

    List<AutomationCompositionElementDefinition>public elementDefinitionList,
abstract void deprime(UUID compositionId) throws PfModelException;

    @Override
    public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException {
        Map<ToscaConceptIdentifierhandleRestartComposition(composition.compositionId(), Map<StringcreateAcElementDefinitionList(composition), Object>> outPropertiesMap) {
}

public record CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId,state);
    }

    //public abstract void handleRestartComposition(UUID compositionId,
    //    List<AutomationCompositionElementDefinition> elementDefinitionList,
    //    AcTypeState state) throws PfModelException;

    public void handleRestartComposition(UUID  Map<StringcompositionId,
 Object> inProperties, Map<String, Object> outProperties) {
}

public record InstanceElementDto(UUIDList<AutomationCompositionElementDefinition> instanceIdelementDefinitionList, AcTypeState UUIDstate) elementId,throws DeployOrderPfModelException orderedState,{
        switch (state) {
            case PRIMING -> prime(compositionId, elementDefinitionList);
       Map<String, Object> inProperties, Map<String, Object> outProperties) {
}


/**
 * This interface is implemented by participant implementations to receive updates on automation composition elements.
 * Valid since New Delhi release.
 */
public interface AutomationCompositionElementListener {
    void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

    void lockcase DEPRIMING -> deprime(compositionId);
            default ->
                intermediaryApi.updateCompositionState(compositionId, state, StateChangeResult.NO_ERROR, "Restarted");
        }
    }

    @Override
    public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement),
  throws PfModelException;

    void unlock(CompositionElementDtoDeployState compositionElementdeployState, InstanceElementDtoLockState instanceElementlockState) throws PfModelException;

 {
       void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;

 var element = new  AcElementDeploy();
   void update(CompositionElementDto  compositionElement, InstanceElementDto instanceElement,element.setId(instanceElement.elementId());
        element.setDefinition(compositionElement.elementDefinitionId());
        InstanceElementDto instanceElementUpdated) throws PfModelException;
element.setProperties(instanceElement.inProperties());
    void prime(CompositionDto composition) throws PfModelException;

    void deprime(CompositionDto composition) throws PfModelException;
 Map<String, Object> properties = new HashMap<>(instanceElement.inProperties());
    void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException;
 properties.putAll(compositionElement.inProperties());
    void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto handleRestartInstance(instanceElement.instanceId(),
 element, properties, deployState, lockState);
    }

     //public abstract void handleRestartInstance(UUID instanceId, AcElementDeploy element,
    //    Map<String, Object>  properties, DeployState deployState, LockState lockState) throws PfModelException;

    public void migratehandleRestartInstance(CompositionElementDtoUUID compositionElementinstanceId, CompositionElementDtoAcElementDeploy compositionElementTargetelement,
        Map<String, Object> properties,       InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException;

    void migratePrecheck(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,DeployState deployState, LockState lockState) throws PfModelException {

        if (DeployState.DEPLOYING.equals(deployState)) {
       InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException;
}

Wrapper class "AcElementListenerMontreal" for participant that was developed in Montreal release

Code Block
languagejava
titleAcElementListenerMontreal
/**
 * Wrapper of AutomationCompositionElementListener.
 * Valid since Montreal release.
 */
public abstract class AcElementListenerMontreal implements AutomationCompositionElementListener {
 deploy(instanceId, element, properties);
            return;
        }
        if (DeployState.UNDEPLOYING.equals(deployState)) {
    private final ParticipantIntermediaryApi intermediaryApi;

    protected AcElementListenerVer7undeploy(ParticipantIntermediaryApi intermediaryApi) {
instanceId, element.getId());
          this.intermediaryApi = intermediaryApireturn;
    }

    @Override}
    public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
if (DeployState.UPDATING.equals(deployState)) {
            throws PfModelException {update(instanceId, element, properties);
        var element = new  AcElementDeploy()return;
        element.setId(instanceElement.elementId());
}
        if element.setDefinition(compositionElement.elementDefinitionId());
   (DeployState.DELETING.equals(deployState)) {
     element.setOrderedState(instanceElement.orderedState());
       delete(instanceId, element.setProperties(instanceElement.inPropertiesgetId());
        Map<String, Object> properties = new HashMap<>(instanceElement.inProperties()) return;
        properties.putAll(compositionElement.inProperties());
}
        if deploy(instanceElementLockState.LOCKING.instanceIdequals(lockState)), element, properties);
{
     }

    public abstract void deploylock(UUID instanceId, AcElementDeploy element, Map<String, Object> properties), element.getId());
        throws PfModelException;

    @Overridereturn;
    public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)}
        throws PfModelExceptionif (LockState.UNLOCKING.equals(lockState)) {
            undeployunlock(instanceElement.instanceId(), instanceElementelement.elementIdgetId());
    }

;
    public abstract void undeploy(UUID instanceId, UUID elementId) throws PfModelExceptionreturn;

    @Override
    public}
 void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
   intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(),
    throws PfModelException {
      deployState, lockState, lock(instanceElement.instanceId(), instanceElement.elementId())StateChangeResult.NO_ERROR, "Restarted");
    }

    @Override
    public abstract void lockmigrate(UUIDCompositionElementDto instanceIdcompositionElement, UUID elementId) throws PfModelException;
CompositionElementDto compositionElementTarget,
    @Override
    public void unlock(CompositionElementDto compositionElementInstanceElementDto instanceElement, InstanceElementDto instanceElement)
instanceElementMigrate) throws PfModelException {
        var element = new throws PfModelException { AcElementDeploy();
        unlock(instanceElementelement.instanceIdsetId(), instanceElement.elementId());
    }

    public abstract void unlock(UUID instanceId, UUID elementId) throws PfModelException;
element.setDefinition(compositionElement.elementDefinitionId());
    @Override
    public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement)element.setProperties(instanceElement.inProperties());
        throws PfModelException {
migrate(instanceElementMigrate.instanceId(), element, compositionElementTarget.compositionId(),
           delete(instanceElement.instanceId(), instanceElement.elementId element.getProperties());
    }

    public abstract void deletemigrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId,
  elementId) throws PfModelException;

    @Override
    public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
                InstanceElementDto instanceElementUpdatedMap<String, Object> properties) throws PfModelException; {

    @Override
    varpublic elementvoid = newmigratePrecheck(CompositionElementDto compositionElement,
  AcElementDeploy();
      CompositionElementDto  element.setId(instanceElementUpdated.elementId());
compositionElementTarget, InstanceElementDto instanceElement,
        InstanceElementDto instanceElementMigrate) throws  element.setDefinition(compositionElement.elementDefinitionId());PfModelException {

        elementintermediaryApi.setOrderedStateupdateAutomationCompositionElementState(instanceElementinstanceElementMigrate.orderedStateinstanceId());,
        element.setProperties(instanceElementUpdated.inProperties());
    instanceElementMigrate.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,
             update(instanceElementUpdated.instanceId(), element, element.getProperties()"Migrate precheck not supported");
    }

    public abstract void update(UUID instanceId, AcElementDeploy element, Map<String, Object> properties)
        throws PfModelException;

    @Override    }
}

Note: "migratePrecheck" is just an example and it will be not delivered in Q1.

Into participant-library will be an abstract class for each version that we would be code compatible; after a specific number of versions we can decide to deprecate the oldest abstract class and remove it in new version.

With that solution a Participant that was developed in Montreal release, could be use the wrapper "AcElementListenerV1" and do not need other changes.

Code Block
languagejava
titleAutomationCompositionElementHandler
@Component
public class AutomationCompositionElementHandler extends AcElementListenerV1 {

    public void primeAutomationCompositionElementHandler(CompositionDtoParticipantIntermediaryApi compositionintermediaryApi) throws PfModelException {
        prime(composition.compositionId(), composition.elementDefinitionList()super(intermediaryApi);
    }

    @Override
    public abstract void primedeploy(UUID compositionIdautomationCompositionId, AcElementDeploy element, Map<String, List<AutomationCompositionElementDefinition>Object> elementDefinitionListproperties)
            throws PfModelException {
----------


If participant needs the functionality of New Delhi version, they can use "AcElementListenerV2"

Code Block
languagejava
titleAcElementListenerV2
/**
 * Wrapper of AutomationCompositionElementListener.
 * Valid since 7.1.2 release.
 */
public abstract class AcElementListenerV2 implements AutomationCompositionElementListener { PfModelException;

    @Override
    public void deprime(CompositionDto composition) throws PfModelException {
        deprime(composition.compositionId());
    }

    public abstractprivate voidfinal deprime(UUID compositionId) throws PfModelExceptionParticipantIntermediaryApi intermediaryApi;

    @Override
protected    public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelExceptionAcElementListenerV2(ParticipantIntermediaryApi intermediaryApi) {
        handleRestartComposition(composition.compositionId(), composition.elementDefinitionList(), state)this.intermediaryApi = intermediaryApi;
    }

    public abstract void handleRestartComposition(UUID compositionId,@Override
    public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
            instanceElement.elementId(),  List<AutomationCompositionElementDefinition> elementDefinitionList,null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
    }

      @Override
    public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
        throws PfModelException {
        intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
    AcTypeState state) throws PfModelException;

    @Override
    public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
    }

    @Override
    public void DeployStatehandleRestartComposition(CompositionDto deployStatecomposition, LockStateAcTypeState lockStatestate) throws PfModelException {
        var element = new  AcElementDeploy();
 switch (state) {
       element.setId(instanceElement.elementId());
     case PRIMING -> element.setDefinition(compositionElement.elementDefinitionId()prime(composition);
        element.setOrderedState(instanceElement.orderedState());
    case DEPRIMING   element.setProperties(instanceElement.inProperties()-> deprime(composition);
        Map<String, Object> properties = new HashMap<>(instanceElement.inProperties());default ->
        properties.putAll(compositionElement.inProperties());
        handleRestartInstanceintermediaryApi.updateCompositionState(instanceElementcomposition.instanceIdcompositionId(), elementstate, propertiesStateChangeResult.NO_ERROR, deployState, lockState"Restarted");
    }

    public}
 abstract void handleRestartInstance(UUID instanceId, AcElementDeploy element,
   }

    @Override
    public void Map<String, Object> propertieshandleRestartInstance(CompositionElementDto compositionElement, DeployStateInstanceElementDto deployStateinstanceElement,
 LockState lockState) throws PfModelException;

    @Override
    public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
        InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException {
       DeployState vardeployState, elementLockState =lockState) newthrows  AcElementDeploy();
PfModelException {

        if element.setId(instanceElement.elementId());
(DeployState.DEPLOYING.equals(deployState)) {
            element.setDefinitiondeploy(compositionElement.elementDefinitionId()), instanceElement);
        element.setOrderedState(instanceElement.orderedState())    return;
        element.setProperties(instanceElement.inProperties());
}
        if migrate(instanceElementMigrateDeployState.UNDEPLOYING.instanceIdequals(deployState)), element, compositionElementTarget.compositionId(), {
            element.getProperties());
undeploy(compositionElement, instanceElement);
        }

    publicreturn;
 abstract void migrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId,}
        Map<String, Object> properties) throws PfModelException;

if (DeployState.UPDATING.equals(deployState)) {
      @Override
    public void migratePrecheckupdate(CompositionElementDto compositionElement,
   instanceElement, instanceElement);
     CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement,
    return;
    InstanceElementDto instanceElementMigrate) throws PfModelException {}

        if intermediaryApi.updateAutomationCompositionElementState(instanceElementMigrate.instanceId(),(DeployState.DELETING.equals(deployState)) {
            instanceElementMigrate.elementIddelete(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,compositionElement, instanceElement);
            "Migratereturn;
 precheck not supported");
     }
}

With that solution a Participant that was developed in Montreal release, could be use the wrapper "AcElementListenerMontreal" and do not need other changes.

Code Block
languagejava
titleAutomationCompositionElementHandler
@Component
public class AutomationCompositionElementHandler extends AcElementListenerMontreal {

        if (LockState.LOCKING.equals(lockState)) {
    private final ParticipantIntermediaryApi intermediaryApi;

    protected AutomationCompositionElementHandlerlock(ParticipantIntermediaryApicompositionElement, intermediaryApiinstanceElement);
    {
        super(intermediaryApi)return;
         this.intermediaryApi = intermediaryApi;
    }

}
        if (LockState.UNLOCKING.equals(lockState)) {
      @Override
    public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
unlock(compositionElement, instanceElement);
            return;
      throws PfModelException {
----------

If participant needs the functionality of New Delhi version, they need to use "AcElementListenerNewDelhi"

Code Block
languagejava
/**
 * Wrapper of AutomationCompositionElementListener.
 * Valid since New Delhi release.
 */
public abstract class AcElementListenerNewDelhi implements AutomationCompositionElementListener {
 }
        intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(),
            deployState, lockState, StateChangeResult.NO_ERROR, "Restarted");
    }
  }