Improvement related to Updating ACM-r message 80/140280/1
authorFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 30 Jan 2025 11:28:26 +0000 (11:28 +0000)
committerFrancesco Fiora <francesco.fiora@est.tech>
Thu, 20 Feb 2025 16:30:17 +0000 (16:30 +0000)
Improvement related to Updating ACM-r message,
and add transactional message handling.

Issue-ID: POLICY-5287
Change-Id: Ib1e1a3c6873694e26536257b0346f703dcc89648
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationComposition.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProvider.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/repository/AutomationCompositionElementRepository.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProvider.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java [new file with mode: 0644]
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java

index 001f2e7..cb05eda 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2025 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -207,22 +207,6 @@ public class JpaAutomationComposition extends Validated
 
     @Override
     public void fromAuthorative(@NonNull final AutomationComposition automationComposition) {
-        this.fromAuthorativeBase(automationComposition);
-        this.elements = new ArrayList<>(automationComposition.getElements().size());
-        for (var elementEntry : automationComposition.getElements().entrySet()) {
-            var jpaAutomationCompositionElement =
-                    new JpaAutomationCompositionElement(elementEntry.getKey().toString(), this.instanceId);
-            jpaAutomationCompositionElement.fromAuthorative(elementEntry.getValue());
-            this.elements.add(jpaAutomationCompositionElement);
-        }
-    }
-
-    /**
-     * Set an instance of the persist concept to the equivalent values as the other concept without copy the elements.
-     *
-     * @param automationComposition the authorative concept
-     */
-    public void fromAuthorativeBase(@NonNull final AutomationComposition automationComposition) {
         this.instanceId = automationComposition.getInstanceId().toString();
         this.name = automationComposition.getName();
         this.version = automationComposition.getVersion();
@@ -237,6 +221,13 @@ public class JpaAutomationComposition extends Validated
         this.subState = automationComposition.getSubState();
         this.description = automationComposition.getDescription();
         this.stateChangeResult = automationComposition.getStateChangeResult();
+        this.elements = new ArrayList<>(automationComposition.getElements().size());
+        for (var elementEntry : automationComposition.getElements().entrySet()) {
+            var jpaAutomationCompositionElement =
+                    new JpaAutomationCompositionElement(elementEntry.getKey().toString(), this.instanceId);
+            jpaAutomationCompositionElement.fromAuthorative(elementEntry.getValue());
+            this.elements.add(jpaAutomationCompositionElement);
+        }
     }
 
     @Override
index bd99a75..b8f7be9 100644 (file)
@@ -148,7 +148,7 @@ public class AcDefinitionProvider {
      * @param compositionId The UUID of the automation composition definition to delete
      * @return the TOSCA service template that was deleted
      */
-    public ToscaServiceTemplate deleteAcDefintion(UUID compositionId) {
+    public ToscaServiceTemplate deleteAcDefinition(UUID compositionId) {
         var jpaDelete = acmDefinitionRepository.findById(compositionId.toString());
         if (jpaDelete.isEmpty()) {
             String errorMessage = "delete of Automation Composition Definition \"" + compositionId
index d0a996e..e375e1f 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2024 Nordix Foundation.
+ * Copyright (C) 2025 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package org.onap.policy.clamp.models.acm.persistence.repository;
 
-import jakarta.persistence.LockModeType;
 import java.util.List;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionElement;
 import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Lock;
-import org.springframework.lang.NonNull;
 
 public interface AutomationCompositionElementRepository extends JpaRepository<JpaAutomationCompositionElement, String> {
 
-    @NonNull
-    @Override
-    @Lock(LockModeType.PESSIMISTIC_READ)
-    JpaAutomationCompositionElement getReferenceById(@NonNull String id);
-
     List<JpaAutomationCompositionElement> findByParticipantId(String participantId);
 }
index bc0a093..3940dc5 100644 (file)
@@ -244,8 +244,7 @@ class AcDefinitionProviderTest {
                 .thenReturn(Optional.of(new JpaAutomationCompositionDefinition(acmDefinition)));
 
         var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
-        var result = acDefinitionProvider.deleteAcDefintion(acmDefinition.getCompositionId());
-
+        var result = acDefinitionProvider.deleteAcDefinition(acmDefinition.getCompositionId());
         assertThat(result).isEqualTo(docServiceTemplate.toAuthorative());
     }
 
@@ -254,7 +253,7 @@ class AcDefinitionProviderTest {
         var compositionId = UUID.randomUUID();
         var acmDefinitionRepository = mock(AutomationCompositionDefinitionRepository.class);
         var acDefinitionProvider = new AcDefinitionProvider(acmDefinitionRepository);
-        assertThatThrownBy(() -> acDefinitionProvider.deleteAcDefintion(compositionId))
+        assertThatThrownBy(() -> acDefinitionProvider.deleteAcDefinition(compositionId))
                 .hasMessage("delete of Automation Composition Definition \"" + compositionId
                         + "\" failed, Automation Composition Definition does not exist");
     }
index 48b1394..d225d44 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2024 Nordix Foundation.
+ * Copyright (C) 2021-2025 Nordix Foundation.
  * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -137,7 +137,7 @@ public class CommissioningProvider {
             throw new PfModelRuntimeException(Status.BAD_REQUEST,
                     "ACM not in COMMISSIONED state, Delete of ACM Definition not allowed");
         }
-        var serviceTemplate = acDefinitionProvider.deleteAcDefintion(compositionId);
+        var serviceTemplate = acDefinitionProvider.deleteAcDefinition(compositionId);
         return createCommissioningResponse(compositionId, serviceTemplate);
     }
 
index 9ef979f..b52e47d 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2024 Nordix Foundation.
+ *  Copyright (C) 2021-2025 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
 package org.onap.policy.clamp.acm.runtime.supervision;
 
 import java.io.Closeable;
-import java.io.IOException;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -71,7 +70,7 @@ public class SupervisionAspect implements Closeable {
     }
 
     @Override
-    public void close() throws IOException {
+    public void close() {
         executor.shutdown();
     }
 }
index 718bcce..355d20e 100644 (file)
@@ -26,21 +26,11 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import lombok.RequiredArgsConstructor;
-import org.onap.policy.clamp.acm.runtime.supervision.scanner.AcDefinitionScanner;
-import org.onap.policy.clamp.acm.runtime.supervision.scanner.PhaseScanner;
-import org.onap.policy.clamp.acm.runtime.supervision.scanner.SimpleScanner;
-import org.onap.policy.clamp.acm.runtime.supervision.scanner.StageScanner;
-import org.onap.policy.clamp.acm.runtime.supervision.scanner.UpdateSync;
-import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.acm.runtime.supervision.scanner.MonitoringScanner;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
-import org.onap.policy.clamp.models.acm.concepts.DeployState;
-import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
-import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
 import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider;
-import org.onap.policy.clamp.models.acm.utils.AcmUtils;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -55,11 +45,8 @@ public class SupervisionScanner {
 
     private final AutomationCompositionProvider automationCompositionProvider;
     private final AcDefinitionProvider acDefinitionProvider;
-    private final AcDefinitionScanner acDefinitionScanner;
-    private final StageScanner stageScanner;
-    private final SimpleScanner simpleScanner;
-    private final PhaseScanner phaseScanner;
     private final MessageProvider messageProvider;
+    private final MonitoringScanner monitoringScanner;
 
     /**
      * Run Scanning.
@@ -89,16 +76,7 @@ public class SupervisionScanner {
         if (optJobId.isEmpty()) {
             return;
         }
-        var messages = messageProvider.getAllMessages(compositionId);
-        var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
-        var updateSync = new UpdateSync();
-        for (var message : messages) {
-            acDefinitionOpt.ifPresent(
-                    acDefinition -> updateSync.or(acDefinitionScanner.scanMessage(acDefinition, message)));
-            messageProvider.removeMessage(message.getMessageId());
-        }
-        acDefinitionOpt.ifPresent(acDefinition ->
-                acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, updateSync));
+        monitoringScanner.scanAcDefinition(compositionId);
         messageProvider.removeJob(optJobId.get());
     }
 
@@ -108,45 +86,7 @@ public class SupervisionScanner {
         if (optJobId.isEmpty()) {
             return;
         }
-        var messages = messageProvider.getAllMessages(instanceId);
-        var automationCompositionOpt = automationCompositionProvider.findAutomationComposition(instanceId);
-        var updateSync = new UpdateSync();
-        for (var message : messages) {
-            automationCompositionOpt.ifPresent(ac -> updateSync.or(simpleScanner.scanMessage(ac, message)));
-            messageProvider.removeMessage(message.getMessageId());
-        }
-        if (automationCompositionOpt.isPresent()) {
-            var automationComposition = automationCompositionOpt.get();
-            var compositionId = automationComposition.getCompositionTargetId() != null
-                    ? automationComposition.getCompositionTargetId() : automationComposition.getCompositionId();
-            var acDefinition = acDefinitionMap.computeIfAbsent(compositionId, acDefinitionProvider::getAcDefinition);
-            scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate(), updateSync);
-        }
-
+        monitoringScanner.scanAutomationComposition(instanceId, acDefinitionMap);
         messageProvider.removeJob(optJobId.get());
     }
-
-    private void scanAutomationComposition(final AutomationComposition automationComposition,
-            ToscaServiceTemplate serviceTemplate, UpdateSync updateSync) {
-        LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId());
-
-        if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(),
-                automationComposition.getLockState(), automationComposition.getSubState())
-                || StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
-            LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId());
-            simpleScanner.saveAndSync(automationComposition, updateSync);
-            return;
-        }
-
-        if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
-            stageScanner.scanStage(automationComposition, serviceTemplate, updateSync);
-        } else if (DeployState.UPDATING.equals(automationComposition.getDeployState())
-                || SubState.REVIEWING.equals(automationComposition.getSubState())
-                || SubState.PREPARING.equals(automationComposition.getSubState())
-                || SubState.MIGRATION_PRECHECKING.equals(automationComposition.getSubState())) {
-            simpleScanner.simpleScan(automationComposition, updateSync);
-        } else {
-            phaseScanner.scanWithPhase(automationComposition, serviceTemplate, updateSync);
-        }
-    }
 }
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java
new file mode 100644 (file)
index 0000000..66875fa
--- /dev/null
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2025 Nordix Foundation.
+ * ================================================================================
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.runtime.supervision.scanner;
+
+import jakarta.transaction.Transactional;
+import java.util.Map;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+@Transactional
+public class MonitoringScanner {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringScanner.class);
+
+    private final AutomationCompositionProvider automationCompositionProvider;
+    private final AcDefinitionProvider acDefinitionProvider;
+    private final AcDefinitionScanner acDefinitionScanner;
+    private final StageScanner stageScanner;
+    private final SimpleScanner simpleScanner;
+    private final PhaseScanner phaseScanner;
+    private final MessageProvider messageProvider;
+
+    /**
+     * Scan Composition Definition by compositionId.
+     *
+     * @param compositionId the Composition Definition id
+     */
+    public void scanAcDefinition(UUID compositionId) {
+        var messages = messageProvider.getAllMessages(compositionId);
+        var acDefinitionOpt = acDefinitionProvider.findAcDefinition(compositionId);
+        var updateSync = new UpdateSync();
+        for (var message : messages) {
+            acDefinitionOpt.ifPresent(
+                    acDefinition -> updateSync.or(acDefinitionScanner.scanMessage(acDefinition, message)));
+            messageProvider.removeMessage(message.getMessageId());
+        }
+        acDefinitionOpt.ifPresent(acDefinition ->
+                acDefinitionScanner.scanAutomationCompositionDefinition(acDefinition, updateSync));
+    }
+
+    /**
+     * Scan AutomationComposition Instance by instanceId.
+     *
+     * @param instanceId the AutomationComposition Instance id
+     * @param acDefinitionMap Map of Composition Definitions
+     */
+    public void scanAutomationComposition(UUID instanceId,
+            Map<UUID, AutomationCompositionDefinition> acDefinitionMap) {
+        var messages = messageProvider.getAllMessages(instanceId);
+        var automationCompositionOpt = automationCompositionProvider.findAutomationComposition(instanceId);
+        var updateSync = new UpdateSync();
+        for (var message : messages) {
+            automationCompositionOpt.ifPresent(ac -> updateSync.or(simpleScanner.scanMessage(ac, message)));
+            messageProvider.removeMessage(message.getMessageId());
+        }
+        if (automationCompositionOpt.isPresent()) {
+            var automationComposition = automationCompositionOpt.get();
+            var compositionId = automationComposition.getCompositionTargetId() != null
+                    ? automationComposition.getCompositionTargetId() : automationComposition.getCompositionId();
+            var acDefinition = acDefinitionMap.computeIfAbsent(compositionId, acDefinitionProvider::getAcDefinition);
+            scanAutomationComposition(automationComposition, acDefinition.getServiceTemplate(), updateSync);
+        }
+    }
+
+    private void scanAutomationComposition(final AutomationComposition automationComposition,
+            ToscaServiceTemplate serviceTemplate, UpdateSync updateSync) {
+        LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId());
+
+        if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(),
+                automationComposition.getLockState(), automationComposition.getSubState())
+                || StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
+            LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId());
+            simpleScanner.saveAndSync(automationComposition, updateSync);
+            return;
+        }
+
+        if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
+            stageScanner.scanStage(automationComposition, serviceTemplate, updateSync);
+        } else if (DeployState.UPDATING.equals(automationComposition.getDeployState())
+                || SubState.REVIEWING.equals(automationComposition.getSubState())
+                || SubState.PREPARING.equals(automationComposition.getSubState())
+                || SubState.MIGRATION_PRECHECKING.equals(automationComposition.getSubState())) {
+            simpleScanner.simpleScan(automationComposition, updateSync);
+        } else {
+            phaseScanner.scanWithPhase(automationComposition, serviceTemplate, updateSync);
+        }
+    }
+}
index 8c76bae..e168210 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2024 Nordix Foundation.
+ *  Copyright (C) 2021-2025 Nordix Foundation.
  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -138,7 +138,7 @@ class CommissioningProviderTest {
         var compositionId = UUID.randomUUID();
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         assertNotNull(serviceTemplate);
-        when(acDefinitionProvider.deleteAcDefintion(compositionId)).thenReturn(serviceTemplate);
+        when(acDefinitionProvider.deleteAcDefinition(compositionId)).thenReturn(serviceTemplate);
 
         var acmDefinition = new AutomationCompositionDefinition();
         acmDefinition.setCompositionId(compositionId);
@@ -151,7 +151,7 @@ class CommissioningProviderTest {
 
         provider.deleteAutomationCompositionDefinition(compositionId);
 
-        verify(acDefinitionProvider).deleteAcDefintion(compositionId);
+        verify(acDefinitionProvider).deleteAcDefinition(compositionId);
     }
 
     @Test
index ab1564b..bd18500 100644 (file)
@@ -38,6 +38,7 @@ import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 import org.onap.policy.clamp.acm.runtime.supervision.scanner.AcDefinitionScanner;
+import org.onap.policy.clamp.acm.runtime.supervision.scanner.MonitoringScanner;
 import org.onap.policy.clamp.acm.runtime.supervision.scanner.PhaseScanner;
 import org.onap.policy.clamp.acm.runtime.supervision.scanner.SimpleScanner;
 import org.onap.policy.clamp.acm.runtime.supervision.scanner.StageScanner;
@@ -64,12 +65,11 @@ class SupervisionScannerTest {
     private static final UUID INSTANCE_ID = UUID.randomUUID();
     private static final String JOB_ID = "JOB_ID";
 
-    private AutomationCompositionDefinition createAutomationCompositionDefinition(
-            AcTypeState acTypeState, StateChangeResult stateChangeResult) {
+    private AutomationCompositionDefinition createAutomationCompositionDefinition(AcTypeState acTypeState) {
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         var acDefinition = new AutomationCompositionDefinition();
         acDefinition.setState(acTypeState);
-        acDefinition.setStateChangeResult(stateChangeResult);
+        acDefinition.setStateChangeResult(StateChangeResult.NO_ERROR);
         acDefinition.setCompositionId(COMPOSITION_ID);
         acDefinition.setLastMsg(TimestampHelper.now());
         acDefinition.setServiceTemplate(Objects.requireNonNull(serviceTemplate));
@@ -96,18 +96,13 @@ class SupervisionScannerTest {
         return acDefinitionProvider;
     }
 
-    private AcDefinitionProvider createAcDefinitionProvider(AcTypeState acTypeState,
-        StateChangeResult stateChangeResult) {
-        return createAcDefinitionProvider(createAutomationCompositionDefinition(acTypeState, stateChangeResult));
-    }
-
-    private AcDefinitionProvider createAcDefinitionProvider() {
-        return createAcDefinitionProvider(AcTypeState.PRIMED, StateChangeResult.NO_ERROR);
+    private AcDefinitionProvider createAcDefinitionProvider(AcTypeState acTypeState) {
+        return createAcDefinitionProvider(createAutomationCompositionDefinition(acTypeState));
     }
 
     @Test
     void testAcDefinition() {
-        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING);
         var acDefinitionScanner = mock(AcDefinitionScanner.class);
         when(acDefinitionScanner.scanMessage(any(), any())).thenReturn(new UpdateSync());
         var messageProvider = mock(MessageProvider.class);
@@ -115,9 +110,12 @@ class SupervisionScannerTest {
         when(messageProvider.findCompositionMessages()).thenReturn(Set.of(COMPOSITION_ID));
         var message = new DocMessage();
         when(messageProvider.getAllMessages(COMPOSITION_ID)).thenReturn(List.of(message));
-        var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider,
+        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 acDefinitionScanner, mock(StageScanner.class), mock(SimpleScanner.class), mock(PhaseScanner.class),
                 messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
         supervisionScanner.run();
         verify(acDefinitionScanner).scanAutomationCompositionDefinition(any(), any());
         verify(messageProvider).removeMessage(message.getMessageId());
@@ -126,14 +124,17 @@ class SupervisionScannerTest {
 
     @Test
     void testAcDefinitionJobExist() {
-        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING, StateChangeResult.NO_ERROR);
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMING);
         var acDefinitionScanner = mock(AcDefinitionScanner.class);
         var messageProvider = mock(MessageProvider.class);
         when(messageProvider.createJob(COMPOSITION_ID)).thenReturn(Optional.empty());
         when(messageProvider.findCompositionMessages()).thenReturn(Set.of());
-        var supervisionScanner = new SupervisionScanner(mock(AutomationCompositionProvider.class), acDefinitionProvider,
+        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 acDefinitionScanner, mock(StageScanner.class), mock(SimpleScanner.class), mock(PhaseScanner.class),
                 messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
         supervisionScanner.run();
         verify(acDefinitionScanner, times(0)).scanAutomationCompositionDefinition(any(), any());
     }
@@ -152,8 +153,11 @@ class SupervisionScannerTest {
         var simpleScanner = mock(SimpleScanner.class);
         var phaseScanner = mock(PhaseScanner.class);
         var messageProvider = mock(MessageProvider.class);
-        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 mock(AcDefinitionScanner.class), stageScanner, simpleScanner, phaseScanner, messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
 
         // not in transition
         supervisionScanner.run();
@@ -187,8 +191,11 @@ class SupervisionScannerTest {
         var phaseScanner = mock(PhaseScanner.class);
         var messageProvider = mock(MessageProvider.class);
         when(messageProvider.createJob(automationComposition.getInstanceId())).thenReturn(Optional.of(JOB_ID));
-        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 mock(AcDefinitionScanner.class), stageScanner, simpleScanner, phaseScanner, messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
 
         // automationComposition not present in DB
         supervisionScanner.run();
@@ -227,8 +234,11 @@ class SupervisionScannerTest {
         when(messageProvider.getAllMessages(INSTANCE_ID)).thenReturn(List.of(message));
         when(messageProvider.findInstanceMessages()).thenReturn(Set.of(INSTANCE_ID));
 
-        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 mock(AcDefinitionScanner.class), stageScanner, simpleScanner, phaseScanner, messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
 
         supervisionScanner.run();
         verify(stageScanner, times(0)).scanStage(any(), any(), any());
@@ -261,18 +271,19 @@ class SupervisionScannerTest {
         when(automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId()))
                 .thenReturn(Optional.of(automationComposition));
 
-        var definitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED, StateChangeResult.NO_ERROR);
+        var definitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED);
         definitionTarget.setCompositionId(compositionTargetId);
-        var acDefinitionProvider = createAcDefinitionProvider();
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
         when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(definitionTarget);
         var stageScanner = mock(StageScanner.class);
 
         var messageProvider = mock(MessageProvider.class);
         when(messageProvider.createJob(automationComposition.getInstanceId())).thenReturn(Optional.of(JOB_ID));
-
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
+                mock(AcDefinitionScanner.class), stageScanner, mock(SimpleScanner.class), mock(PhaseScanner.class),
+                messageProvider);
         var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
-                mock(AcDefinitionScanner.class), stageScanner, mock(SimpleScanner.class),
-                mock(PhaseScanner.class), messageProvider);
+                messageProvider, monitoringScanner);
 
         supervisionScanner.run();
         verify(stageScanner).scanStage(automationComposition, definitionTarget.getServiceTemplate(),
@@ -301,9 +312,12 @@ class SupervisionScannerTest {
         when(messageProvider.createJob(automationComposition.getInstanceId())).thenReturn(Optional.of(JOB_ID));
 
         var simpleScanner = mock(SimpleScanner.class);
-        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 mock(AcDefinitionScanner.class), mock(StageScanner.class), simpleScanner, mock(PhaseScanner.class),
                 messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
         supervisionScanner.run();
         verify(simpleScanner).simpleScan(automationComposition, new UpdateSync());
         verify(messageProvider).removeJob(JOB_ID);
@@ -359,8 +373,11 @@ class SupervisionScannerTest {
 
         var phaseScanner = mock(PhaseScanner.class);
         var stageScanner = mock(StageScanner.class);
-        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(),
+        var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED);
+        var monitoringScanner = new MonitoringScanner(automationCompositionProvider, acDefinitionProvider,
                 mock(AcDefinitionScanner.class), stageScanner, simpleScanner, phaseScanner, messageProvider);
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                messageProvider, monitoringScanner);
 
         supervisionScanner.run();
         verifyNoInteraction(stageScanner, simpleScanner, phaseScanner);
@@ -368,5 +385,4 @@ class SupervisionScannerTest {
         verify(messageProvider).removeMessage(message.getMessageId());
         verify(messageProvider).removeJob(JOB_ID);
     }
-
 }