Update dmaap references in policy documentation files
[policy/parent.git] / docs / clamp / acm / acm-participant-guide.rst
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.
4
5 .. _acm-participant-guide-label:
6
7 Participant developer guide
8 ###########################
9
10 .. contents::
11     :depth: 4
12
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.
17
18 Please refer the following section for a detailed understanding of Inbound and outbound messages a participant interacts with.
19
20 .. toctree::
21    :maxdepth: 2
22
23    design-impl/participants/participants
24
25 Design considerations for a participant
26 ---------------------------------------
27
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.
32
33 Hence the new participants has to have this Participant Intermediary module as a dependency and should:
34
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.
38
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.
41
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.
48
49 .. code-block:: bash
50
51     clampAutomationCompositionTopics:
52           topicSources:
53             -
54               topic: POLICY-ACRUNTIME-PARTICIPANT
55               servers:
56                 - ${topicServer:localhost}:9092
57               topicCommInfrastructure: kafka
58               fetchTimeout: 15000
59           topicSinks:
60             -
61               topic: POLICY-ACRUNTIME-PARTICIPANT
62               servers:
63                 - ${topicServer:localhost}:9092
64               topicCommInfrastructure: kafka
65
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.
68
69 .. code-block:: bash
70
71     participantSupportedElementTypes:
72       -
73         typeName: org.onap.policy.clamp.acm.PolicyAutomationCompositionElement
74         typeVersion: 1.0.0
75
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.
84
85 .. code-block:: java
86
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;
98
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.
101
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.
105
106 .. code-block:: java
107
108   ParticipantIntermediaryParameters getIntermediaryParameters()
109
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.
114
115 The Abstract class AcElementListenerV1 supports the follow methods.
116
117 .. code-block:: java
118
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;
130
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.
133
134 Un example of AutomationCompositionElementHandler implemented in 7.1.0 version and how to use AcElementListenerV1 abstract class:
135
136 .. code-block:: java
137
138   @Component
139   @RequiredArgsConstructor
140   public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
141
142     private final ParticipantIntermediaryApi intermediaryApi;
143     private final otherService otherService;
144     ..............................
145   }
146
147   @Component
148   public class AutomationCompositionElementHandler extends AcElementListenerV1 {
149
150     private final OtherService otherService;
151
152     public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi, OtherService otherService) {
153         super(intermediaryApi);
154         this.otherService = otherService;
155     }
156     ..............................
157   }
158
159
160
161 A second example:
162
163 .. code-block:: java
164
165   @Component
166   public class AutomationCompositionElementHandler implements AutomationCompositionElementListener {
167
168     @Autowired
169     private ParticipantIntermediaryApi intermediaryApi;
170
171     @Autowired
172     private otherService otherService;
173     ..............................
174   }
175
176   @Component
177   public class AutomationCompositionElementHandler extends AcElementListenerV1 {
178
179     @Autowired
180     private otherService otherService;
181
182     public AutomationCompositionElementHandler(ParticipantIntermediaryApi intermediaryApi) {
183         super(intermediaryApi);
184     }
185     ..............................
186   }
187
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.
192
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.
195
196
197 APIs to invoke
198 --------------
199 ParticipantIntermediaryApi:
200   The participant intermediary api has the following methods that can be invoked from the participant for the following purposes.
201
202   #. The requested operations are completed in the handler class and the ACM-runtime needs to be notified.
203   #. Collect all instances data.
204   #. Send out Properties to ACM-runtime.
205
206   The methods are as follows:
207
208 This following methods could be invoked to fetch data during each operation in the participant.
209
210 .. code-block:: java
211
212   1.  Map<UUID, AutomationComposition> getAutomationCompositions();
213   2.  AutomationComposition getAutomationComposition(UUID instanceId);
214   3.  AutomationCompositionElement getAutomationCompositionElement(UUID instanceId, UUID elementId);
215   4.  Map<UUID, Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition>> getAcElementsDefinitions();
216   5.  Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> getAcElementsDefinitions(UUID compositionId);
217   6.  AutomationCompositionElementDefinition getAcElementDefinition(UUID compositionId, ToscaConceptIdentifier elementId);
218
219 This following methods are invoked to update the outProperties during each operation in the participant.
220
221 .. code-block:: java
222
223   1.  void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId, Map<String, Object> outProperties);
224   2.  void sendAcElementInfo(UUID instanceId, UUID elementId, String useState, String operationalState, Map<String, Object> outProperties);
225
226 This following methods are invoked to update the AC element state or AC element definition state after each operation is completed in the participant.
227
228 .. code-block:: java
229
230   1.  void updateAutomationCompositionElementState(UUID instanceId, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message);
231   2.  void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult, String message);
232
233 In/Out composition Properties
234 -----------------------------
235 The 'Common Properties' could be created or updated by ACM-runtime.
236 Participants will receive that Properties during priming and deprime events by CompositionDto class.
237
238 .. code-block:: java
239
240   @Override
241   public void prime(CompositionDto composition) throws PfModelException {
242       for (var entry : composition.inPropertiesMap().entrySet()) {
243           var elementDefinitionId = entry.getKey();
244           var inProperties = entry.getValue();
245           .......
246       }
247       .......
248   }
249
250 Participants will receive the Properties related to the element definition by CompositionElementDto class.
251
252 .. code-block:: java
253
254   @Override
255   public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
256       var inCompositionProperties = compositionElement.inProperties();
257       .......
258   }
259
260 The 'Out Properties' could be created or updated by participants. ACM-runtime will receive that Properties during ParticipantStatus event.
261 The participant can trigger this event using the method sendAcDefinitionInfo.
262
263 Participants will receive that outProperties during priming and deprime events by CompositionDto class.
264
265 .. code-block:: java
266
267   @Override
268   public void deprime(CompositionDto composition) throws PfModelException {
269       for (var entry : composition.outPropertiesMap().entrySet()) {
270           var elementDefinitionId = entry.getKey();
271           var outProperties = entry.getValue();
272           .......
273       }
274       .......
275   }
276
277 Participants will receive the outProperties related to the element definition by CompositionElementDto class.
278
279 .. code-block:: java
280
281   @Override
282   public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
283       var outCompositionProperties = compositionElement.outProperties();
284       .......
285   }
286
287 Is allowed to the participant to read all In/Out Properties of all compositions handled by the participant using the method getAcElementsDefinitions.
288 The following code is an example how to update the property 'myProperty' and send to ACM-runtime:
289
290 .. code-block:: java
291
292   var acElement = intermediaryApi.getAcElementDefinition(compositionId, elementDefinitionId);
293   var outProperties = acElement.getOutProperties();
294   outProperties.put("myProperty", myProperty);
295   intermediaryApi.sendAcDefinitionInfo(compositionId, elementDefinitionId, outProperties);
296
297 In/Out instance Properties
298 --------------------------
299   The 'In/Out Properties' are stored into the instance elements, so each element has its own In/Out Properties.
300
301   The 'In Properties' could be created or updated by ACM-runtime. Participants will receive that Properties during deploy and update events.
302
303   The 'Out Properties' could be created or updated by participants. ACM-runtime will receive that Properties during ParticipantStatus event.
304   The participant can trigger this event using the method sendAcElementInfo. The 'useState' and 'operationalState' can be used as well.
305   The 'Out Properties' could be **cleaned**:
306
307   * by the participant using the method sendAcElementInfo
308   * by intermediary automatically during deleting of the instance
309   * by an update when the instance is in UNDEPLOYED state (changing the elementId)
310
311   The 'Out Properties' will be **not cleaned** by intermediary:
312
313   * during DEPLOIYNG (Out Properties will be take from last changes matching by elementId)
314   * during UNDEPLOING
315   * during LOCKING/UNLOCKING
316   * during UPDATING/MIGRATING
317
318 Participants will receive the in/out instance Properties related to the element by InstanceElementDto class.
319
320 .. code-block:: java
321
322   @Override
323   public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) throws PfModelException {
324       var inProperties = instanceElement.inProperties();
325       var outProperties = instanceElement.outProperties();
326       .......
327   }
328
329 Is allowed to the participant to read all In/Out Properties and state of all instances handled by the participant using the method getAutomationCompositions.
330 The following code is an example how to update the property 'myProperty' and send to ACM-runtime:
331
332 .. code-block:: java
333
334   var acElement = intermediaryApi.getAutomationCompositionElement(instanceId, elementId);
335   var outProperties = acElement.getOutProperties();
336   outProperties.put("myProperty", myProperty);
337   intermediaryApi.sendAcElementInfo(instanceId, elementId, acElement.getUseState(), acElement.getOperationalState(), outProperties);
338
339 **Note**: In update and migrate Participants will receive the instance Properties before the merge (instanceElement) and the instance Properties merged (instanceElementUpdated / instanceElementMigrate).
340
341 Restart scenario
342 ----------------
343   Restart methods handle the scenario when participant shut down and restart.
344   During RESTARTING, compositions and instances will be stored in participant memory with In/Out Properties, 'useState' and 'operationalState'.
345   The method handleRestartComposition will be called for each composition and will be present the 'state' at the time the participant shut down.
346   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.
347
348 In ONAP, the following participants are already implemented in java spring boot for various requirements. The maven modules
349 can be referred here:
350
351   * `HTTP participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-http>`_.
352   * `Kubernetes participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-kubernetes>`_.
353   * `Policy participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-policy>`_.
354   * `A1PMS participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-a1pms>`_.
355   * `Kserve participant <https://github.com/onap/policy-clamp/tree/master/participant/participant-impl/participant-impl-kserve>`_.
356
357 Example of Implementation
358 -------------------------
359
360 This following code is an example of My First Participant:
361   * Application
362   * Parameters
363   * Handler
364
365 The Application class is configured to add the "org.onap.policy.clamp.acm.participant.intermediary" package in SpringBoot component scanning.
366
367 .. code-block:: java
368
369   @SpringBootApplication
370   @ComponentScan({
371     "org.onap.policy.clamp.acm.participant.myfirstparticipant",
372     "org.onap.policy.clamp.acm.participant.intermediary"
373   })
374   @ConfigurationPropertiesScan("org.onap.policy.clamp.acm.participant.myfirstparticipant.parameters")
375   public class MyFirstParticipantApplication {
376
377     public static void main(String[] args) {
378       SpringApplication.run(Application.class, args);
379     }
380   }
381
382 The Participant Parameters class implements the mandatory interface ParticipantParameters.
383 It could contains additional parameters.
384
385 .. code-block:: java
386
387   @Validated
388   @Getter
389   @Setter
390   @ConfigurationProperties(prefix = "participant")
391   public class ParticipantSimParameters implements ParticipantParameters {
392
393     @NotBlank
394     private String myparameter;
395
396     @NotNull
397     @Valid
398     private ParticipantIntermediaryParameters intermediaryParameters;
399   }
400
401 The following example shows the topic parameters and the additional 'myparameter'.
402
403 .. code-block:: bash
404
405   participant:
406     myparameter: my parameter
407     intermediaryParameters:
408       reportingTimeIntervalMs: 120000
409       description: Participant Description
410       participantId: 101c62b3-8918-41b9-a747-d21eb79c6c90
411       clampAutomationCompositionTopics:
412         topicSources:
413           - topic: POLICY-ACRUNTIME-PARTICIPANT
414             servers:
415               - ${topicServer:localhost}:9092
416             topicCommInfrastructure: kafka
417             fetchTimeout: 15000
418         topicSinks:
419           - topic: POLICY-ACRUNTIME-PARTICIPANT
420             servers:
421               - ${topicServer:localhost}:9092
422             topicCommInfrastructure: kafka
423       participantSupportedElementTypes:
424         -
425           typeName: org.onap.policy.clamp.acm.MyFirstAutomationCompositionElement
426           typeVersion: 1.0.0
427
428
429 The following example shows the Handler implementation and how could be the implemented the mandatory notifications.
430
431 .. code-block:: java
432
433   @Component
434   public class AutomationCompositionElementHandler extends AcElementListenerV2 {
435
436     @Override
437     public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
438             throws PfModelException {
439
440         // TODO deploy process
441
442         if (isDeploySuccess()) {
443             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
444                 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR,
445                 "Deployed");
446         } else {
447             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
448                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
449                 "Deploy failed!");
450         }
451     }
452
453     @Override
454     public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
455             throws PfModelException {
456
457         // TODO undeploy process
458
459         if (isUndeploySuccess()) {
460             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
461                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR,
462                     "Undeployed");
463         } else {
464             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
465                 instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.FAILED,
466                     "Undeploy failed!");
467         }
468     }
469
470     @Override
471     public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
472             throws PfModelException {
473
474         // TODO lock process
475
476         if (isLockSuccess()) {
477             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
478                 instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
479         } else {
480             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
481                 instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.FAILED, "Lock failed!");
482         }
483     }
484
485     @Override
486     public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
487             throws PfModelException {
488
489         // TODO unlock process
490
491         if (isUnlockSuccess()) {
492             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
493                 instanceElement.elementId(), null, LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
494         } else {
495             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
496                 instanceElement.elementId(), null, LockState.LOCKED, StateChangeResult.FAILED, "Unlock failed!");
497         }
498     }
499
500     @Override
501     public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement)
502             throws PfModelException {
503
504         // TODO delete process
505
506         if (isDeleteSuccess()) {
507             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
508                 instanceElement.elementId(), DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
509         } else {
510             intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
511                 instanceElement.elementId(), DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
512                 "Delete failed!");
513         }
514     }
515
516     @Override
517     public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
518                        InstanceElementDto instanceElementUpdated) throws PfModelException {
519
520         // TODO update process
521
522         if (isUpdateSuccess()) {
523             intermediaryApi.updateAutomationCompositionElementState(
524                 instanceElement.instanceId(), instanceElement.elementId(),
525                 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
526         } else {
527             intermediaryApi.updateAutomationCompositionElementState(
528                 instanceElement.instanceId(), instanceElement.elementId(),
529                 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Update failed!");
530         }
531     }
532
533     @Override
534     public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget,
535                         InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate)
536         throws PfModelException
537
538         // TODO migrate process
539
540         if (isMigrateSuccess()) {
541             intermediaryApi.updateAutomationCompositionElementState(
542                 instanceElement.instanceId(), instanceElement.elementId(),
543                 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated");
544         } else {
545             intermediaryApi.updateAutomationCompositionElementState(
546                 instanceElement.instanceId(), instanceElement.elementId(),
547                 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Migrate failed!");
548         }
549     }
550
551     @Override
552     public void prime(CompositionDto composition) throws PfModelException {
553
554         // TODO prime process
555
556         if (isPrimeSuccess()) {
557             intermediaryApi.updateCompositionState(composition.compositionId(),
558                 AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "Primed");
559         } else {
560             intermediaryApi.updateCompositionState(composition.compositionId(),
561                 AcTypeState.COMMISSIONED, StateChangeResult.FAILED, "Prime failed!");
562         }
563     }
564
565     @Override
566     public void deprime(CompositionDto composition) throws PfModelException {
567
568         // TODO deprime process
569
570         if (isDeprimeSuccess()) {
571             intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.COMMISSIONED,
572                 StateChangeResult.NO_ERROR, "Deprimed");
573         } else {
574             intermediaryApi.updateCompositionState(composition.compositionId(), AcTypeState.PRIMED,
575                 StateChangeResult.FAILED, "Deprime failed!");
576         }
577     }
578
579
580     @Override
581     public void handleRestartComposition(CompositionDto composition, AcTypeState state) throws PfModelException {
582
583          // TODO restart process
584
585         switch (state) {
586             case PRIMING -> prime(composition);
587             case DEPRIMING -> deprime(composition);
588             default -> intermediaryApi
589                 .updateCompositionState(composition.compositionId(), state, StateChangeResult.NO_ERROR, "Restarted");
590         }
591     }
592
593     @Override
594     public void handleRestartInstance(CompositionElementDto compositionElement, InstanceElementDto instanceElement,
595         DeployState deployState, LockState lockState) throws PfModelException {
596
597          // TODO restart process
598
599         if (DeployState.DEPLOYING.equals(deployState)) {
600             deploy(compositionElement, instanceElement);
601             return;
602         }
603         if (DeployState.UNDEPLOYING.equals(deployState)) {
604             undeploy(compositionElement, instanceElement);
605             return;
606         }
607         if (DeployState.UPDATING.equals(deployState)) {
608             update(compositionElement, instanceElement, instanceElement);
609             return;
610         }
611         if (DeployState.DELETING.equals(deployState)) {
612             delete(compositionElement, instanceElement);
613             return;
614         }
615         if (LockState.LOCKING.equals(lockState)) {
616             lock(compositionElement, instanceElement);
617             return;
618         }
619         if (LockState.UNLOCKING.equals(lockState)) {
620             unlock(compositionElement, instanceElement);
621             return;
622         }
623         intermediaryApi.updateAutomationCompositionElementState(instanceElement.instanceId(),
624             instanceElement.elementId(), deployState, lockState, StateChangeResult.NO_ERROR, "Restarted");
625     }
626
627
628 AC Element states in failure scenarios
629 --------------------------------------
630
631 During the execution of any state change order, there is always a possibility of failures or exceptions that can occur in the participant.
632 This can be tackled by the followed approaches.
633
634 The participant implementation can handle the exception and revert back the appropriate AC element state, by invoking the
635 'updateAutomationCompositionElementState' api from the participant intermediary.
636
637 Alternatively, the participant can simply throw a PfModelException from its implementation which will be handled by the participant intermediary.
638 The intermediary handles this exception and rolls back the AC element to its previous state with the appropriate stateChange Result.
639 Please refer the following table for the state change reversion that happens in the participant intermediary for the AC elements.
640
641 ================== ==================
642 **Error Scenario** **State Reverted**
643 ================== ==================
644 Prime fails        Commissoned
645
646 Deprime fails      Primed
647
648 Deploy fails       Undeployed
649
650 Undeploy fails     Deployed
651
652 Update fails       Deployed
653
654 Delete fails       Undeployed
655
656 Lock fails         Unlocked
657
658 Unlock fails       Locked
659
660 Migrate fails      Deployed
661 ================== ==================
662
663 Considering the above mentioned behavior of the participant Intermediary, it is the responsibility of the developer to tackle the
664 error scenarios in the participant with the suitable approach.
665
666 Tips:
667 If the participant tries to undeploy an element which doesn’t exist in the system any more (due to various other external factors),
668 it could update the element state to ‘undeployed’ using the Intermediary api.