1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3 .. Copyright (c) Nordix Foundation. All rights reserved.
5 .. _acm-participant-guide-label:
7 Participant developer guide
8 ###########################
13 The ACM runtime delegates the user requests to the participants for performing the actual operations.
14 Hence the participant module in ACM is implemented adhering to a list of ACM protocols along with their own functional logic.
15 It works in a contract with the Participant Intermediary module for communicating with ACM-R.
16 This guide explains the design considerations for a new participant implementation in ACM.
18 Please refer the following section for a detailed understanding of Inbound and outbound messages a participant interacts with.
23 design-impl/participants/participants
25 Design considerations for a participant
26 ---------------------------------------
28 In ONAP, the ACM-runtime and participant modules are implemented in Java spring boot. The participant Intermediary module
29 which is added as a maven dependency to the participants has the default implementations available for listening the kafka
30 events coming in from the ACM-runtime, process them and delegate them to the appropriate handler class. Similarly the
31 Intermediary module also has the publisher class implementations for publishing events back from the participants to the ACM-runtime.
33 Hence the new participants has to have this Participant Intermediary module as a dependency and should:
35 * Configure SpringBoot to scan the components located into the package "org.onap.policy.clamp.acm.participant.intermediary".
36 * Implement the following interfaces from the Participant Intermediary.
37 * Provide the following mandatory properties in order to make the participant work in synchronisation with ACM-runtime.
39 The participant application should be provided with the following Intermediary parameter values in the application properties
40 and the same is configured for the 'ParticipantIntermediaryParameters' object in the code.
42 1. participantId - A unique participant UUID that is used by the runtime to identify the participant.
43 2. ReportingTimeIntervalMs - Time inertval the participant should report the status/heartbeat to the runtime.
44 3. clampAutomationCompositionTopics - This property takes in the kafka topic names and servers for the intermediary module to use.
45 These values should be provided for both source and sink configs.
46 (**Note**: In order to avoid a connection to Kafka when Unit Tests are running, set topicCommInfrastructure: NOOP in properties file for tests).
47 The following example shows the topic parameters set for using Kafka.
51 clampAutomationCompositionTopics:
54 topic: POLICY-ACRUNTIME-PARTICIPANT
56 - ${topicServer:localhost}:9092
57 topicCommInfrastructure: kafka
61 topic: POLICY-ACRUNTIME-PARTICIPANT
63 - ${topicServer:localhost}:9092
64 topicCommInfrastructure: kafka
66 4. participantSupportedElementTypes - This property takes a list of typeName and typeVersion fields to define the types of AC elements the participant deals with.
67 These are user defined name and version and the same should be defined for the AC elements that are included in the TOSCA based AC definitions.
71 participantSupportedElementTypes:
73 typeName: org.onap.policy.clamp.acm.PolicyAutomationCompositionElement
76 Interfaces to Implement
77 -----------------------
78 AutomationCompositionElementListener:
79 Every participant should implement a handler class that implements the AutomationCompositionElementListener interface
80 from the Participant Intermediary. The intermediary listener class listens for the incoming events from the ACM-runtime
81 and invoke the handler class implementations for various operations. This class implements the methods for deploying,
82 undeploying, locking, unlocking , deleting, updating, migrating, priming, depriming requests that are coming from the ACM-runtime.
83 The methods are as follows.
87 1. void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;
88 2. void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;
89 3. void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;
90 4. void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;
91 5. void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException;
92 6. void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, InstanceElementDto instanceElementUpdated) throws PfModelException;
93 7. void prime(CompositionDto composition) throws PfModelException;
94 8. void deprime(CompositionDto composition) throws PfModelException;
95 9. void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException;
96 10. void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement, DeployState deployState, LockState lockState) throws PfModelException;
97 11. void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) throws PfModelException;
99 These method from the interface are implemented independently as per the user requirement. These methods after handling the
100 appropriate requests should also invoke the intermediary's publisher apis to notify the ACM-runtime with the acknowledgement events.
102 ParticipantParameters:
103 Every participant should implement a properties class that contains the values of all Intermediary parameter properties.
104 This class implements the method getIntermediaryParameters that returns 'ParticipantIntermediaryParameters' object. The method is as follows.
108 ParticipantIntermediaryParameters getIntermediaryParameters()
110 Abstract class AcElementListenerV1
111 ----------------------------------
112 This abstract class is introduced to help to maintain the java backward compatibility with AutomationCompositionElementListener implemented in 7.1.0 version.
113 So developers can decide to align to new functionality later. Any new functionality in the future will be wrapped by this class.
115 The Abstract class AcElementListenerV1 supports the follow methods.
119 1. void undeploy(UUID instanceId, UUID elementId) throws PfModelException;
120 2. void deploy(UUID instanceId, AcElementDeploy element, Map<String, Object> inProperties) throws PfModelException;
121 3. void lock(UUID instanceId, UUID elementId) throws PfModelException;
122 4. void unlock(UUID instanceId, UUID elementId) throws PfModelException;
123 5. void delete(UUID instanceId, UUID elementId) throws PfModelException;
124 6. void update(UUID instanceId, AcElementDeploy element, Map<String, Object> inProperties) throws PfModelException;
125 7. void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList) throws PfModelException;
126 8. void deprime(UUID compositionId) throws PfModelException;
127 9. void handleRestartComposition(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state) throws PfModelException;
128 10. void handleRestartInstance(UUID instanceId, AcElementDeploy element, Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException;
129 11. void migrate(UUID instanceId, AcElementDeploy element, UUID compositionTargetId, Map<String, Object> properties) throws PfModelException;
131 **Note**: this class needs intermediaryApi and it should be passed by constructor. It is declared as protected and can be used.
132 Default implementation are supported for the methods: lock, unlock, update, migrate, delete, prime, deprime, handleRestartComposition and handleRestartInstance.
134 Un example of AutomationCompositionElementHandler implemented in 7.1.0 version and how to use AcElementListenerV1 abstract class:
139 @RequiredArgsConstructor
140 public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
142 private final ParticipantIntermediaryApi intermediaryApi;
143 private final otherService otherService;
144 ..............................
148 public class AutomationCompositionElementHandler extends AcElementListenerV1 {
150 private final OtherService otherService;
152 public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, OtherService otherService) {
153 super(intermediaryApi);
154 this.otherService = otherService;
156 ..............................
166 public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
169 private ParticipantIntermediaryApi intermediaryApi;
172 private otherService otherService;
173 ..............................
177 public class AutomationCompositionElementHandler extends AcElementListenerV1 {
180 private otherService otherService;
182 public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi) {
183 super(intermediaryApi);
185 ..............................
188 Abstract class AcElementListenerV2
189 ----------------------------------
190 This abstract class is introduced to help to maintain the java backward compatibility with AutomationCompositionElementListener from new releases.
191 Any new functionality in the future will be wrapped by this class.
193 **Note**: this class needs intermediaryApi and it should be passed by constructor. It is declared as protected and can be used.
194 Default implementation are supported for the methods: lock, unlock, update, migrate, delete, prime, deprime, handleRestartComposition and handleRestartInstance.
197 Methods: deploy, undeploy, lock, unlock and delete
199 ====================== =======================================
200 **field** **description**
201 ====================== =======================================
202 compositionId composition definition Id
203 elementDefinitionId composition definition element Id
204 inProperties composition definition in-properties
205 outProperties composition definition out-properties
206 ====================== =======================================
208 ============================== ===========================
209 **field** **description**
210 ============================== ===========================
211 instanceId instance id
212 elementId instance element id
213 toscaServiceTemplateFragment policies and policy types
214 inProperties instance in-properties
215 outProperties instance out-properties
216 ============================== ===========================
220 ====================== =======================================
221 **field** **description**
222 ====================== =======================================
223 compositionId composition definition Id
224 elementDefinitionId composition definition element Id
225 inProperties composition definition in-properties
226 outProperties composition definition out-properties
227 ====================== =======================================
229 ============================== ================================================
230 **field** **description**
231 ============================== ================================================
232 instanceId instance id
233 elementId instance element id
234 toscaServiceTemplateFragment
235 inProperties instance in-properties **(before the update)**
236 outProperties instance out-properties
237 ============================== ================================================
238 instanceElementUpdated:
239 ============================== ======================================
240 **field** **description**
241 ============================== ======================================
242 instanceId instance id
243 elementId instance element id
244 toscaServiceTemplateFragment
245 inProperties instance in-properties **(updated)**
246 outProperties instance out-properties
247 ============================== ======================================
249 Methods: prime, deprime
251 ====================== ===================================================================
252 **field** **description**
253 ====================== ===================================================================
254 compositionId composition definition Id
255 inProperties composition definition in-properties for each definition element
256 outProperties composition definition out-properties for each definition element
257 ====================== ===================================================================
261 ====================== =======================================
262 **field** **description**
263 ====================== =======================================
264 compositionId composition definition Id
265 elementDefinitionId composition definition element Id
266 inProperties composition definition in-properties
267 outProperties composition definition out-properties
268 ====================== =======================================
269 compositionElementTarget:
270 ====================== ==============================================
271 **field** **description**
272 ====================== ==============================================
273 compositionId composition definition target Id
274 elementDefinitionId composition definition target element Id
275 inProperties composition definition target in-properties
276 outProperties composition definition target out-properties
277 ====================== ==============================================
279 ============================== ===================================================
280 **field** **description**
281 ============================== ===================================================
282 instanceId instance id
283 elementId instance element id
284 toscaServiceTemplateFragment
285 inProperties instance in-properties **(before the migration)**
286 outProperties instance out-properties
287 ============================== ===================================================
288 instanceElementMigrate:
289 ============================== ======================================
290 **field** **description**
291 ============================== ======================================
292 instanceId instance id
293 elementId instance element id
294 toscaServiceTemplateFragment
295 inProperties instance in-properties **(updated)**
296 outProperties instance out-properties
297 ============================== ======================================
301 ParticipantIntermediaryApi:
302 The participant intermediary api has the following methods that can be invoked from the participant for the following purposes.
304 #. The requested operations are completed in the handler class and the ACM-runtime needs to be notified.
305 #. Collect all instances data.
306 #. Send out Properties to ACM-runtime.
308 The methods are as follows:
310 This following methods could be invoked to fetch data during each operation in the participant.
314 1. Map<UUID, AutomationComposition> getAutomationCompositions();
315 2. AutomationComposition getAutomationComposition(UUID instanceId);
316 3. AutomationCompositionElement getAutomationCompositionElement(UUID instanceId, UUID elementId);
317 4. Map<UUID, Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition>> getAcElementsDefinitions();
318 5. Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> getAcElementsDefinitions(UUID compositionId);
319 6. AutomationCompositionElementDefinition getAcElementDefinition(UUID compositionId, ToscaConceptIdentifier elementId);
321 This following methods are invoked to update the outProperties during each operation in the participant.
325 1. void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId, Map<String, Object> outProperties);
326 2. void sendAcElementInfo(UUID instanceId, UUID elementId, String useState, String operationalState, Map<String, Object> outProperties);
328 This following methods are invoked to update the AC element state or AC element definition state after each operation is completed in the participant.
332 1. void updateAutomationCompositionElementState(UUID instanceId, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message);
333 2. void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult, String message);
335 In/Out composition Properties
336 -----------------------------
337 The 'Common Properties' could be created or updated by ACM-runtime.
338 Participants will receive that Properties during priming and deprime events by CompositionDto class.
343 public void prime(CompositionDto composition) throws PfModelException {
344 for (var entry : composition.inPropertiesMap().entrySet()) {
345 var elementDefinitionId = entry.getKey();
346 var inProperties = entry.getValue();
352 Participants will receive the Properties related to the element definition by CompositionElementDto class.
357 public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
358 var inCompositionProperties = compositionElement.inProperties();
362 The 'Out Properties' could be created or updated by participants. ACM-runtime will receive that Properties during ParticipantStatus event.
363 The participant can trigger this event using the method sendAcDefinitionInfo.
365 Participants will receive that outProperties during priming and deprime events by CompositionDto class.
370 public void deprime(CompositionDto composition) throws PfModelException {
371 for (var entry : composition.outPropertiesMap().entrySet()) {
372 var elementDefinitionId = entry.getKey();
373 var outProperties = entry.getValue();
379 Participants will receive the outProperties related to the element definition by CompositionElementDto class.
384 public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
385 var outCompositionProperties = compositionElement.outProperties();
389 Is allowed to the participant to read all In/Out Properties of all compositions handled by the participant using the method getAcElementsDefinitions.
390 The following code is an example how to update the property 'myProperty' and send to ACM-runtime:
394 var acElement = intermediaryApi.getAcElementDefinition(compositionId, elementDefinitionId);
395 var outProperties = acElement.getOutProperties();
396 outProperties.put("myProperty", myProperty);
397 intermediaryApi.sendAcDefinitionInfo(compositionId, elementDefinitionId, outProperties);
399 In/Out instance Properties
400 --------------------------
401 The 'In/Out Properties' are stored into the instance elements, so each element has its own In/Out Properties.
403 The 'In Properties' could be created or updated by ACM-runtime. Participants will receive that Properties during deploy and update events.
405 The 'Out Properties' could be created or updated by participants. ACM-runtime will receive that Properties during ParticipantStatus event.
406 The participant can trigger this event using the method sendAcElementInfo. The 'useState' and 'operationalState' can be used as well.
407 The 'Out Properties' could be **cleaned**:
409 * by the participant using the method sendAcElementInfo
410 * by intermediary automatically during deleting of the instance
411 * by an update when the instance is in UNDEPLOYED state (changing the elementId)
413 The 'Out Properties' will be **not cleaned** by intermediary:
415 * during DEPLOIYNG (Out Properties will be take from last changes matching by elementId)
417 * during LOCKING/UNLOCKING
418 * during UPDATING/MIGRATING
420 Participants will receive the in/out instance Properties related to the element by InstanceElementDto class.
425 public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
426 var inProperties = instanceElement.inProperties();
427 var outProperties = instanceElement.outProperties();
431 Is allowed to the participant to read all In/Out Properties and state of all instances handled by the participant using the method getAutomationCompositions.
432 The following code is an example how to update the property 'myProperty' and send to ACM-runtime:
436 var acElement = intermediaryApi.getAutomationCompositionElement(instanceId, elementId);
437 var outProperties = acElement.getOutProperties();
438 outProperties.put("myProperty", myProperty);
439 intermediaryApi.sendAcElementInfo(instanceId, elementId, acElement.getUseState(), acElement.getOperationalState(), outProperties);
441 **Note**: In update and migrate Participants will receive the instance Properties before the merge (instanceElement) and the instance Properties merged (instanceElementUpdated / instanceElementMigrate).
445 Restart methods handle the scenario when participant shut down and restart.
446 During RESTARTING, compositions and instances will be stored in participant memory with In/Out Properties, 'useState' and 'operationalState'.
447 The method handleRestartComposition will be called for each composition and will be present the 'state' at the time the participant shut down.
448 The method handleRestartInstance will be called for each instance element and will be present the 'deployState' and the 'lockState' at the time the participant shut down.
450 In ONAP, the following participants are already implemented in java spring boot for various requirements. The maven modules
451 can be referred here:
453 * `HTTP participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-http>`_.
454 * `Kubernetes participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-kubernetes>`_.
455 * `Policy participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-policy>`_.
456 * `A1PMS participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-a1pms>`_.
457 * `Kserve participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-kserve>`_.
459 Example of Implementation
460 -------------------------
462 This following code is an example of My First Participant:
467 The Application class is configured to add the "org.onap.policy.clamp.acm.participant.intermediary" package in SpringBoot component scanning.
471 @SpringBootApplication
473 "org.onap.policy.clamp.acm.participant.myfirstparticipant",
474 "org.onap.policy.clamp.acm.participant.intermediary"
476 @ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.myfirstparticipant.parameters")
477 public class MyFirstParticipantApplication {
479 public static void main(String[] args) {
480 SpringApplication.run(Application.class, args);
484 The Participant Parameters class implements the mandatory interface ParticipantParameters.
485 It could contains additional parameters.
492 @ConfigurationProperties(prefix = "participant")
493 public class ParticipantSimParameters implements ParticipantParameters {
496 private String myparameter;
500 private ParticipantIntermediaryParameters intermediaryParameters;
503 The following example shows the topic parameters and the additional 'myparameter'.
508 myparameter: my parameter
509 intermediaryParameters:
510 reportingTimeIntervalMs: 120000
511 description: Participant Description
512 participantId: 101c62b3-8918-41b9-a747-d21eb79c6c90
513 clampAutomationCompositionTopics:
515 - topic: POLICY-ACRUNTIME-PARTICIPANT
517 - ${topicServer:localhost}:9092
518 topicCommInfrastructure: kafka
521 - topic: POLICY-ACRUNTIME-PARTICIPANT
523 - ${topicServer:localhost}:9092
524 topicCommInfrastructure: kafka
525 participantSupportedElementTypes:
527 typeName: org.onap.policy.clamp.acm.MyFirstAutomationCompositionElement
531 The following example shows the Handler implementation and how could be the implemented the mandatory notifications.
536 public class AutomationCompositionElementHandler extends AcElementListenerV2 {
539 public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
540 throws PfModelException {
542 // TODO deploy process
544 if (isDeploySuccess()) {
545 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
546 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,
549 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
550 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
556 public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
557 throws PfModelException {
559 // TODO undeploy process
561 if (isUndeploySuccess()) {
562 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
563 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
566 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
567 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED,
573 public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
574 throws PfModelException {
578 if (isLockSuccess()) {
579 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
580 instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
582 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
583 instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!");
588 public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
589 throws PfModelException {
591 // TODO unlock process
593 if (isUnlockSuccess()) {
594 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
595 instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
597 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
598 instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!");
603 public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
604 throws PfModelException {
606 // TODO delete process
608 if (isDeleteSuccess()) {
609 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
610 instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
612 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
613 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
619 public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
620 InstanceElementDto instanceElementUpdated) throws PfModelException {
622 // TODO update process
624 if (isUpdateSuccess()) {
625 intermediaryApi.updateAutomationCompositionElementState(
626 instanceElement.instanceId(), instanceElement.elementId(),
627 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
629 intermediaryApi.updateAutomationCompositionElementState(
630 instanceElement.instanceId(), instanceElement.elementId(),
631 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
636 public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
637 InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate)
638 throws PfModelException
640 // TODO migrate process
642 if (isMigrateSuccess()) {
643 intermediaryApi.updateAutomationCompositionElementState(
644 instanceElement.instanceId(), instanceElement.elementId(),
645 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
647 intermediaryApi.updateAutomationCompositionElementState(
648 instanceElement.instanceId(), instanceElement.elementId(),
649 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!");
654 public void prime(CompositionDto composition) throws PfModelException {
656 // TODO prime process
658 if (isPrimeSuccess()) {
659 intermediaryApi.updateCompositionState(composition.compositionId(),
660 AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed");
662 intermediaryApi.updateCompositionState(composition.compositionId(),
663 AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!");
668 public void deprime(CompositionDto composition) throws PfModelException {
670 // TODO deprime process
672 if (isDeprimeSuccess()) {
673 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
674 StateChangeResult.NO_ERROR, "Deprimed");
676 intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
677 StateChangeResult.FAILED, "Deprime failed!");
683 public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException {
685 // TODO restart process
688 case PRIMING -> prime(composition);
689 case DEPRIMING -> deprime(composition);
690 default -> intermediaryApi
691 .updateCompositionState(composition.compositionId(), state, StateChangeResult.NO_ERROR, "Restarted");
696 public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
697 DeployState deployState, LockState lockState) throws PfModelException {
699 // TODO restart process
701 if (DeployState.DEPLOYING.equals(deployState)) {
702 deploy(compositionElement, instanceElement);
705 if (DeployState.UNDEPLOYING.equals(deployState)) {
706 undeploy(compositionElement, instanceElement);
709 if (DeployState.UPDATING.equals(deployState)) {
710 update(compositionElement, instanceElement, instanceElement);
713 if (DeployState.DELETING.equals(deployState)) {
714 delete(compositionElement, instanceElement);
717 if (LockState.LOCKING.equals(lockState)) {
718 lock(compositionElement, instanceElement);
721 if (LockState.UNLOCKING.equals(lockState)) {
722 unlock(compositionElement, instanceElement);
725 intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
726 instanceElement.elementId(), deployState, lockState, StateChangeResult.NO_ERROR, "Restarted");
730 AC Element states in failure scenarios
731 --------------------------------------
733 During the execution of any state change order, there is always a possibility of failures or exceptions that can occur in the participant.
734 This can be tackled by the followed approaches.
736 The participant implementation can handle the exception and revert back the appropriate AC element state, by invoking the
737 'updateAutomationCompositionElementState' api from the participant intermediary.
739 Alternatively, the participant can simply throw a PfModelException from its implementation which will be handled by the participant intermediary.
740 The intermediary handles this exception and rolls back the AC element to its previous state with the appropriate stateChange Result.
741 Please refer the following table for the state change reversion that happens in the participant intermediary for the AC elements.
743 ================== ==================
744 **Error Scenario** **State Reverted**
745 ================== ==================
746 Prime fails Commissoned
750 Deploy fails Undeployed
752 Undeploy fails Deployed
754 Update fails Deployed
756 Delete fails Undeployed
762 Migrate fails Deployed
763 ================== ==================
765 Considering the above mentioned behavior of the participant Intermediary, it is the responsibility of the developer to tackle the
766 error scenarios in the participant with the suitable approach.
769 If the participant tries to undeploy an element which doesn’t exist in the system any more (due to various other external factors),
770 it could update the element state to ‘undeployed’ using the Intermediary api.