aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/clamp/acm/design-impl/clamp-runtime-acm.rst54
-rw-r--r--docs/clamp/acm/draw.io/acm-consumer-producer.drawio76
-rw-r--r--docs/clamp/acm/draw.io/acm-scheduling-job.drawio114
-rw-r--r--docs/clamp/acm/images/acm-consumer-producer-messages.pngbin0 -> 24814 bytes
-rw-r--r--docs/clamp/acm/images/acm-scheduling-job.pngbin0 -> 42845 bytes
5 files changed, 235 insertions, 9 deletions
diff --git a/docs/clamp/acm/design-impl/clamp-runtime-acm.rst b/docs/clamp/acm/design-impl/clamp-runtime-acm.rst
index a3c22e69..802e9a0e 100644
--- a/docs/clamp/acm/design-impl/clamp-runtime-acm.rst
+++ b/docs/clamp/acm/design-impl/clamp-runtime-acm.rst
@@ -349,46 +349,61 @@ PARTICIPANT_REGISTER
- A participant replica starts and send a PARTICIPANT_REGISTER message with participantId, replicaId and supported Element Types
- ACM-runtime collects the message from Message Broker by ParticipantRegisterListener
- if not present, it saves participant replica reference with status ON_LINE to DB
+- it sends PARTICIPANT_REGISTER_ACK to participant replica
PARTICIPANT_PRIME_ACK
++++++++++++++++++++++
- A participant sends PARTICIPANT_PRIME_ACK message in response to a PARTICIPANT_PRIME message
- ParticipantPrimeAckListener collects the message from Message Broker
-- It updates AC Definition to DB with PRIMED/DEPRIMED as status
-- If AC Definition is fully PRIMED, ACM-runtime sends sync message to all participants replica
+- It stores the message into the DB
+- MessageIntercept intercepts that event and adds a task to handle a monitoring execution in SupervisionScanner
+- Monitoring updates AC Definition to DB with PRIMED/DEPRIMED as status
+- If AC Definition is fully PRIMED, Monitoring sends sync message to all participants replica
PARTICIPANT_STATUS
++++++++++++++++++
-- A participant sends a scheduled PARTICIPANT_STATUS message with participantId, replicaId and supported Element Types
+- A participant sends a scheduled PARTICIPANT_STATUS message with participantId, replicaId and supported Element Types. Same message could be used by participant to update OutProperties of an AC instance/AC definition.
- ACM-runtime collects the message from Message Broker by ParticipantStatusListener
-- if not present, it saves participant replica reference with status ON_LINE to DB
+- If not present, it saves participant replica reference with status ON_LINE to DB
+- If the message contains OutProperties of an AC instance/AC definition it stores the message into the DB
+- MessageIntercept intercepts that event and adds a task to handle a monitoring execution in SupervisionScanner
+- Monitoring updates the AC instance/AC definition
+- Monitoring sends a sync message to all participants replica
AUTOMATION_COMPOSITION_DEPLOY_ACK
+++++++++++++++++++++++++++++++++
- A participant sends AUTOMATION_COMPOSITION_DEPLOY_ACK message in response to a AUTOMATION_COMPOSITION_DEPLOY message. It will send a AUTOMATION_COMPOSITION_DEPLOY_ACK - for each AC elements moved to the DEPLOYED state
- AutomationCompositionUpdateAckListener collects the message from Message Broker
-- It checks the status of all Automation Composition elements and checks if the Automation Composition is fully DEPLOYED
-- It updates the AC to DB
+- It store the message into the DB
- MessageIntercept intercepts that event and adds a task to handle a monitoring execution in SupervisionScanner
+- Monitoring checks the status of all Automation Composition elements and checks if the Automation Composition is fully DEPLOYED
+- Monitoring updates the AC instance to DB
+- If the Automation Composition is fully DEPLOYED Monitoring sends a sync message to all participants replica
AUTOMATION_COMPOSITION_STATECHANGE_ACK
++++++++++++++++++++++++++++++++++++++
- A participant sends AUTOMATION_COMPOSITION_STATECHANGE_ACK message in response to a AUTOMATION_COMPOSITION_STATECHANGE message. It will send a AUTOMATION_COMPOSITION_DEPLOY_ACK - for each AC elements moved to the ordered state
- AutomationCompositionStateChangeAckListener collects the message from Message Broker
-- It checks the status of all Automation Composition elements and checks if the transition process of the Automation Composition is terminated
-- It updates the AC to DB
+- It store the message into the DB
- MessageIntercept intercepts that event and adds a task to handle a monitoring execution in SupervisionScanner
+- Monitoring checks the status of all Automation Composition elements and checks if the transition process of the Automation Composition is terminated
+- Monitoring updates the AC instance to DB
+- If the transition process is terminated, Monitoring sends a sync message to all participants replica
Design of monitoring execution in SupervisionScanner
****************************************************
Monitoring is designed to process the follow operations:
+- to elaborate the messages from participants
- to determine the next startPhase in a AUTOMATION_COMPOSITION_DEPLOY message
+- to determine the next stage in a AUTOMATION_COMPOSITION_MIGRATION message
- to update AC deployState: in a scenario that "AutomationComposition.deployState" is in a kind of transitional state (example DEPLOYING), if all - AC elements are moved properly to the specific state, the "AutomationComposition.deployState" will be updated to that and saved to DB
- to update AC lockState: in a scenario that "AutomationComposition.lockState" is in a kind of transitional state (example LOCKING), if all - AC elements are moved properly to the specific state, the "AutomationComposition.lockState" will be updated to that and saved to DB
+- to update AC subState: in a scenario that "AutomationComposition.subState" is in a kind of transitional state (example PREPARING), if all - AC elements are moved properly to NONE state, the "AutomationComposition.subState" will be updated to NONE and saved to DB
- to delete AC Instance: in a scenario that "AutomationComposition.deployState" is in DELETING, if all - AC elements are moved properly to DELETED, the AC Instance will be deleted from DB
- to retry AUTOMATION_COMPOSITION_DEPLOY/AUTOMATION_COMPOSITION_STATE_CHANGE messages. if there is an AC instance with startPhase completed, it will be moved to the next startPhase and retry a broadcast message with the new startPhase
-- to send sync message to all participants replica: in scenario where AC instance transition is fully completed
+- to retry AUTOMATION_COMPOSITION_MIGRATION messages. if there is an AC instance with stage completed, it will be moved to the next stage and retry a broadcast message with the new stage
+- to send sync message to all participants replica: in scenario where AC instance transition is fully completed or OutProperties has been changed
The solution Design timeout and reporting for all Participant message dialogues are implemented into the monitoring execution.
@@ -396,6 +411,27 @@ The solution Design timeout and reporting for all Participant message dialogues
- ThreadPoolExecutor executes the task
- set AC instance stateChangeResult in timeout, if ACM-runtime do no receive Act message before MaxWaitMs milliseconds
+Producer and Consumer and Scheduling job mechanisms
++++++++++++++++++++++++++++++++++++++++++++++++++++
+To avoid conflicts, for example when an ACM-r pod is receiving a messages to change outProperties of an AC instance and other ACM-r pod is receiving a messages to change the status of an element of the same instance,
+Producer and Consumer and Scheduling job mechanisms has been implemented.
+With the Producer and Consumer mechanism, any ACM-r replica monitoring could elaborate a message independently from what ACM-r replica has fetched the message.
+Listeners of ACM-r will fetch messages from kafka and store to a message FIFO queue stored in DB.
+
+.. image:: ../images/acm-consumer-producer-messages.png
+
+Monitoring of a ACM-r replica will fetch messages from that queue.
+All Monitoring from different ACM-r pods are synchronized with Scheduling job to avoid to fetch messages related to same AC instance or AC definition at same time.
+InstanceIds and a compositionIds are generated with UUID as unique key and could be used as identificationId for messages.
+
+.. image:: ../images/acm-scheduling-job.png
+
+Edge case scenario: ACM-r pod has been terminated from Kubernetes
+-----------------------------------------------------------------
+Full elaboration of a monitoring for an AC instance or for a AC definition is protected by a transaction.
+If an ACM-r pod has been terminated from Kubernetes, the monitoring not full completed will be rollback from database.
+The monitoring job not completed wil be deleted after 200 seconds. All message of that AC definition or AC instance will processed by other monitoring.
+
Design of Exception handling
****************************
GlobalControllerExceptionHandler
diff --git a/docs/clamp/acm/draw.io/acm-consumer-producer.drawio b/docs/clamp/acm/draw.io/acm-consumer-producer.drawio
new file mode 100644
index 00000000..50022556
--- /dev/null
+++ b/docs/clamp/acm/draw.io/acm-consumer-producer.drawio
@@ -0,0 +1,76 @@
+<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0" modified="2025-02-24T15:17:34.768Z" version="24.3.0" etag="oOdE97yUTVgThpAVyM50" type="device">
+ <diagram name="Page-1" id="13e1069c-82ec-6db2-03f1-153e76fe0fe0">
+ <mxGraphModel dx="1666" dy="781" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" background="none" math="0" shadow="0">
+ <root>
+ <mxCell id="0" />
+ <mxCell id="1" parent="0" />
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-2" value="DB" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" parent="1" vertex="1">
+ <mxGeometry x="410" y="390" width="100" height="120" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-7" value="Producers" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+ <mxGeometry x="280" y="150" width="118" height="30" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-8" value="Consumers" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
+ <mxGeometry x="510" y="150" width="120" height="30" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-13" value="Kafka" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="150" y="160" width="60" height="200" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-20" value="ACM-r pod1" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;" parent="1" vertex="1">
+ <mxGeometry x="257" y="180" width="390" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-17" value="ACM-r pod 1&lt;div&gt;Monitoring&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="525" y="193" width="90" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-9" value="ACM-r pod 1&lt;div&gt;Listener&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="294" y="193" width="90" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-21" value="ACM-r pod2" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;" parent="1" vertex="1">
+ <mxGeometry x="257" y="277" width="390" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-18" value="ACM-r pod 2&lt;div&gt;Monitoring&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="525" y="287" width="90" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-10" value="ACM-r pod 2&lt;div&gt;Listener&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="294" y="287" width="90" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-11" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.145;entryY=0;entryDx=0;entryDy=4.35;entryPerimeter=0;" parent="1" source="kN3JDQdCuxnZuiGcsfEb-9" target="kN3JDQdCuxnZuiGcsfEb-2" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="520" y="420" as="sourcePoint" />
+ <mxPoint x="570" y="370" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-12" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.06;entryY=0.042;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="kN3JDQdCuxnZuiGcsfEb-10" target="kN3JDQdCuxnZuiGcsfEb-2" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="394" y="261" as="sourcePoint" />
+ <mxPoint x="420" y="390" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-14" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.35;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="kN3JDQdCuxnZuiGcsfEb-13" target="kN3JDQdCuxnZuiGcsfEb-9" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="110" y="475" as="sourcePoint" />
+ <mxPoint x="160" y="425" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-15" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.022;entryY=0.383;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.967;exitY=0.705;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="kN3JDQdCuxnZuiGcsfEb-13" target="kN3JDQdCuxnZuiGcsfEb-10" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="120" y="485" as="sourcePoint" />
+ <mxPoint x="170" y="435" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-22" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.7;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="kN3JDQdCuxnZuiGcsfEb-2" target="kN3JDQdCuxnZuiGcsfEb-17" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="680" y="420" as="sourcePoint" />
+ <mxPoint x="760" y="250" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="kN3JDQdCuxnZuiGcsfEb-23" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="kN3JDQdCuxnZuiGcsfEb-18" edge="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="480" y="390" as="sourcePoint" />
+ <mxPoint x="647" y="366.5" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ </root>
+ </mxGraphModel>
+ </diagram>
+</mxfile>
diff --git a/docs/clamp/acm/draw.io/acm-scheduling-job.drawio b/docs/clamp/acm/draw.io/acm-scheduling-job.drawio
new file mode 100644
index 00000000..9591ada6
--- /dev/null
+++ b/docs/clamp/acm/draw.io/acm-scheduling-job.drawio
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mxfile host="ac.draw.io" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36" version="26.0.16">
+ <diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
+ <mxGraphModel dx="1434" dy="772" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
+ <root>
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-2" value="" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="WIyWlLk6GJQsqaUBKTNV-3" target="8UuhrBDbArfPKTQupupm-0" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="220" y="170" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-3" value="Fetch the list of composition ids&lt;div&gt;and instance ids that have&lt;/div&gt;&lt;div&gt;to be monitored&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="10" width="210" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-8" value="No" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="WIyWlLk6GJQsqaUBKTNV-10" edge="1">
+ <mxGeometry x="0.3333" y="20" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ <mxPoint x="850" y="200" as="sourcePoint" />
+ <mxPoint x="220" y="400" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-9" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="WIyWlLk6GJQsqaUBKTNV-10" target="8UuhrBDbArfPKTQupupm-0" edge="1">
+ <mxGeometry y="10" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ <mxPoint x="410" y="325" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="400" y="295" />
+ <mxPoint x="400" y="160" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-0" value="Fetch next indentification id&lt;div&gt;from the list&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="120" width="210" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-2" value="" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="8UuhrBDbArfPKTQupupm-0" target="WIyWlLk6GJQsqaUBKTNV-10" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="220" y="220" as="sourcePoint" />
+ <mxPoint x="370" y="250" as="targetPoint" />
+ <Array as="points" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="WIyWlLk6GJQsqaUBKTNV-10" value="is this&lt;div&gt;indentification&amp;nbsp;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;id&lt;/span&gt;&lt;div&gt;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;present into&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;the messagejob?&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;" style="rhombus;whiteSpace=wrap;html=1;shadow=0;fontFamily=Helvetica;fontSize=12;align=center;strokeWidth=1;spacing=6;spacingTop=-4;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="140" y="230" width="160" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-3" value="Save the identification id&lt;div&gt;into the messagejob&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="400" width="210" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-5" value="Handle all messages by the identification id and remove&lt;div&gt;those messages when completed&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="520" width="210" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-7" value="" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="8UuhrBDbArfPKTQupupm-3" target="8UuhrBDbArfPKTQupupm-5" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="400" y="420" as="sourcePoint" />
+ <mxPoint x="266" y="240" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="220" y="500" />
+ <mxPoint x="220" y="500" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-8" value="When all messages are completed remove the identification id&lt;div&gt;from the messagejob&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="640" width="210" height="80" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-9" value="" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" target="8UuhrBDbArfPKTQupupm-8" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="220" y="600" as="sourcePoint" />
+ <mxPoint x="266" y="360" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="220" y="620" />
+ <mxPoint x="220" y="620" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-10" value="No" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="8UuhrBDbArfPKTQupupm-12" target="8UuhrBDbArfPKTQupupm-0" edge="1">
+ <mxGeometry x="0.3333" y="20" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ <mxPoint x="170" y="820" as="sourcePoint" />
+ <mxPoint x="60" y="150" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="60" y="815" />
+ <mxPoint x="60" y="160" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-11" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="8UuhrBDbArfPKTQupupm-12" edge="1">
+ <mxGeometry y="10" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ <mxPoint x="220" y="930" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="220" y="880" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-12" value="Is the indentification id&lt;div&gt;list empty?&lt;/div&gt;" style="rhombus;whiteSpace=wrap;html=1;shadow=0;fontFamily=Helvetica;fontSize=12;align=center;strokeWidth=1;spacing=6;spacingTop=-4;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="140" y="750" width="160" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-13" value="" style="rounded=0;html=1;jettySize=auto;orthogonalLoop=1;fontSize=11;endArrow=block;endFill=0;endSize=8;strokeWidth=1;shadow=0;labelBackgroundColor=none;edgeStyle=orthogonalEdgeStyle;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="8UuhrBDbArfPKTQupupm-8" target="8UuhrBDbArfPKTQupupm-12" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="230" y="717" as="sourcePoint" />
+ <mxPoint x="230" y="747" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="220" y="730" />
+ <mxPoint x="220" y="730" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="8UuhrBDbArfPKTQupupm-14" value="Monitoring completed" style="rounded=1;whiteSpace=wrap;html=1;fontSize=12;glass=0;strokeWidth=1;shadow=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
+ <mxGeometry x="115" y="930" width="210" height="80" as="geometry" />
+ </mxCell>
+ </root>
+ </mxGraphModel>
+ </diagram>
+</mxfile>
diff --git a/docs/clamp/acm/images/acm-consumer-producer-messages.png b/docs/clamp/acm/images/acm-consumer-producer-messages.png
new file mode 100644
index 00000000..0076b16b
--- /dev/null
+++ b/docs/clamp/acm/images/acm-consumer-producer-messages.png
Binary files differ
diff --git a/docs/clamp/acm/images/acm-scheduling-job.png b/docs/clamp/acm/images/acm-scheduling-job.png
new file mode 100644
index 00000000..3ded9e9e
--- /dev/null
+++ b/docs/clamp/acm/images/acm-scheduling-job.png
Binary files differ