Refactor Prime and Deprime messages in ACM 51/133051/2
authorFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 26 Jan 2023 17:31:46 +0000 (17:31 +0000)
committerLiam Fallon <liam.fallon@est.tech>
Mon, 30 Jan 2023 16:39:27 +0000 (16:39 +0000)
Issue-ID: POLICY-4502
Change-Id: Ib0ecc513285bf971a0c25cec528dcdeec5ad63a2
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
24 files changed:
models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java
models/src/main/java/org/onap/policy/clamp/models/acm/messages/dmaap/participant/ParticipantAckMessage.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaAutomationCompositionDefinition.java
models/src/main/java/org/onap/policy/clamp/models/acm/persistence/concepts/JpaNodeTemplateState.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/provider/ParticipantProvider.java
models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java
models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcDefinitionProviderTest.java
models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/ParticipantProviderTest.java
models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.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/instantiation/AutomationCompositionInstantiationProvider.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/main/rest/CommissioningController.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandler.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/ParticipantUpdatePublisher.java
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/commissioning/rest/CommissioningControllerTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java

index 015a96a..54e6db1 100644 (file)
@@ -32,8 +32,6 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 public final class ParticipantUtils {
 
     private static final Coder CODER = new StandardCoder();
-    private static final String AUTOMATION_COMPOSITION_ELEMENT =
-        "org.onap.policy.clamp.acm.AutomationCompositionElement";
 
     /**
      * Get the First StartPhase.
@@ -75,27 +73,4 @@ public final class ParticipantUtils {
         }
         return 0;
     }
-
-    /**
-     * Checks if a NodeTemplate is an AutomationCompositionElement.
-     *
-     * @param nodeTemplate the ToscaNodeTemplate
-     * @param toscaServiceTemplate the ToscaServiceTemplate
-     * @return true if the NodeTemplate is an AutomationCompositionElement
-     */
-    public static boolean checkIfNodeTemplateIsAutomationCompositionElement(ToscaNodeTemplate nodeTemplate,
-        ToscaServiceTemplate toscaServiceTemplate) {
-        if (nodeTemplate.getType().contains(AUTOMATION_COMPOSITION_ELEMENT)) {
-            return true;
-        } else {
-            var nodeType = toscaServiceTemplate.getNodeTypes().get(nodeTemplate.getType());
-            if (nodeType != null) {
-                var derivedFrom = nodeType.getDerivedFrom();
-                if (derivedFrom != null) {
-                    return derivedFrom.contains(AUTOMATION_COMPOSITION_ELEMENT);
-                }
-            }
-        }
-        return false;
-    }
 }
index bdb2be8..e73f2e7 100644 (file)
@@ -46,6 +46,8 @@ public class ParticipantAckMessage {
 
     private ParticipantMessageType messageType;
 
+    private UUID compositionId;
+
     /**
      * Participant ID, or {@code null} for messages from participants.
      */
index fcaa6e6..11e3f58 100644 (file)
@@ -89,8 +89,9 @@ public class JpaAutomationCompositionDefinition extends Validated
     @Override
     public AutomationCompositionDefinition toAuthorative() {
         var acmDefinition = new AutomationCompositionDefinition();
-        acmDefinition.setCompositionId(UUID.fromString(compositionId));
-        acmDefinition.setServiceTemplate(serviceTemplate.toAuthorative());
+        acmDefinition.setCompositionId(UUID.fromString(this.compositionId));
+        acmDefinition.setState(this.state);
+        acmDefinition.setServiceTemplate(this.serviceTemplate.toAuthorative());
         for (var element : this.elements) {
             var key = element.getNodeTemplateId().getName();
             acmDefinition.getElementStateMap().put(key, element.toAuthorative());
@@ -105,11 +106,12 @@ public class JpaAutomationCompositionDefinition extends Validated
         this.serviceTemplate = new DocToscaServiceTemplate(copyConcept.getServiceTemplate());
         setName(this.serviceTemplate.getName());
         setVersion(this.serviceTemplate.getVersion());
-        elements = new HashSet<>(copyConcept.getElementStateMap().size());
+        this.elements = new HashSet<>(copyConcept.getElementStateMap().size());
         for (var element : copyConcept.getElementStateMap().values()) {
             var nodeTemplateStateId = element.getNodeTemplateStateId().toString();
             var jpaNodeTemplateState = new JpaNodeTemplateState(nodeTemplateStateId, this.compositionId);
             jpaNodeTemplateState.fromAuthorative(element);
+            this.elements.add(jpaNodeTemplateState);
         }
     }
 
index a6d13a6..088bf21 100644 (file)
@@ -21,6 +21,7 @@
 package org.onap.policy.clamp.models.acm.persistence.concepts;
 
 import java.util.UUID;
+import javax.persistence.AttributeOverride;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
@@ -33,7 +34,9 @@ import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
 import org.onap.policy.common.parameters.annotations.NotNull;
 import org.onap.policy.models.base.PfAuthorative;
+import org.onap.policy.models.base.PfConceptKey;
 import org.onap.policy.models.base.Validated;
+import org.onap.policy.models.base.validation.annotations.VerifyKey;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 @Entity
@@ -54,9 +57,11 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod
     @Column
     private String participantId;
 
-    @Column
+    @VerifyKey
     @NotNull
-    private ToscaConceptIdentifier nodeTemplateId;
+    @AttributeOverride(name = "name",    column = @Column(name = "nodeTemplate_name"))
+    @AttributeOverride(name = "version", column = @Column(name = "nodeTemplate_version"))
+    private PfConceptKey nodeTemplateId;
 
     @Column
     @NotNull
@@ -86,7 +91,8 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod
         if (copyConcept.getParticipantId() != null) {
             this.participantId = copyConcept.getParticipantId().toString();
         }
-        this.nodeTemplateId = copyConcept.getNodeTemplateId();
+        this.nodeTemplateId = copyConcept.getNodeTemplateId().asConceptKey();
+        this.state = copyConcept.getState();
     }
 
     @Override
@@ -96,7 +102,7 @@ public class JpaNodeTemplateState extends Validated implements PfAuthorative<Nod
         if (this.participantId != null) {
             nodeTemplateState.setParticipantId(UUID.fromString(this.participantId));
         }
-        nodeTemplateState.setNodeTemplateId(this.nodeTemplateId);
+        nodeTemplateState.setNodeTemplateId(new ToscaConceptIdentifier(this.nodeTemplateId));
         nodeTemplateState.setState(this.state);
         return nodeTemplateState;
     }
index 3757f6c..71f510a 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition
 import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompositionDefinition;
 import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionDefinitionRepository;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.data.domain.Example;
@@ -62,6 +63,8 @@ public class AcDefinitionProvider {
         }
         serviceTemplate.getMetadata().put("compositionId", compositionId);
         acmDefinition.setServiceTemplate(serviceTemplate);
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+        acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED));
         var jpaAcmDefinition = ProviderUtils.getJpaAndValidate(acmDefinition, JpaAutomationCompositionDefinition::new,
                 "AutomationCompositionDefinition");
         var result = acmDefinitionRepository.save(jpaAcmDefinition);
@@ -80,6 +83,8 @@ public class AcDefinitionProvider {
         acmDefinition.setCompositionId(compositionId);
         acmDefinition.setState(AcTypeState.COMMISSIONED);
         acmDefinition.setServiceTemplate(serviceTemplate);
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+        acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED));
         updateAcDefinition(acmDefinition);
     }
 
@@ -137,10 +142,9 @@ public class AcDefinitionProvider {
      * @return the automation composition definition
      */
     @Transactional(readOnly = true)
-    public Optional<ToscaServiceTemplate> findAcDefinition(UUID compositionId) {
+    public Optional<AutomationCompositionDefinition> findAcDefinition(UUID compositionId) {
         var jpaGet = acmDefinitionRepository.findById(compositionId.toString());
-        return jpaGet.stream().map(JpaAutomationCompositionDefinition::getServiceTemplate)
-                .map(DocToscaServiceTemplate::toAuthorative).findFirst();
+        return jpaGet.stream().map(JpaAutomationCompositionDefinition::toAuthorative).findFirst();
     }
 
     /**
index 7b8ebc0..8e45c77 100644 (file)
@@ -20,7 +20,9 @@
 
 package org.onap.policy.clamp.models.acm.persistence.provider;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.UUID;
 import javax.ws.rs.core.Response.Status;
@@ -30,6 +32,7 @@ import org.onap.policy.clamp.models.acm.concepts.Participant;
 import org.onap.policy.clamp.models.acm.persistence.concepts.JpaParticipant;
 import org.onap.policy.clamp.models.acm.persistence.repository.ParticipantRepository;
 import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -127,4 +130,23 @@ public class ParticipantProvider {
 
         return jpaDeleteParticipantOpt.get().toAuthorative();
     }
+
+
+    /**
+     * Get a map with SupportedElement as key and the participantId as value.
+     *
+     * @return a map
+     */
+    public Map<ToscaConceptIdentifier, UUID> getSupportedElementMap() {
+        var list = participantRepository.findAll();
+        Map<ToscaConceptIdentifier, UUID> map = new HashMap<>();
+        for (var participant : list) {
+            for (var element : participant.getSupportedElements()) {
+                var supportedElement = new ToscaConceptIdentifier(element.getTypeName(), element.getTypeVersion());
+                map.put(supportedElement, UUID.fromString(participant.getParticipantId()));
+            }
+        }
+        return map;
+    }
+
 }
index 8bd9039..9f73cb1 100644 (file)
@@ -22,25 +22,31 @@ package org.onap.policy.clamp.models.acm.utils;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.UUID;
 import java.util.function.Function;
 import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
+import javax.ws.rs.core.Response;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates;
 import org.onap.policy.common.parameters.BeanValidationResult;
 import org.onap.policy.common.parameters.ObjectValidationResult;
 import org.onap.policy.common.parameters.ValidationResult;
 import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -53,6 +59,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class AcmUtils {
 
+    public static final String AUTOMATION_COMPOSITION_ELEMENT =
+            "org.onap.policy.clamp.acm.AutomationCompositionElement";
     public static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
     public static final String ENTRY = "entry ";
 
@@ -111,51 +119,107 @@ public final class AcmUtils {
     }
 
     /**
-     * Prepare ParticipantDefinitionUpdate to set in the message.
+     * Checks if a NodeTemplate is an AutomationCompositionElement.
      *
-     * @param acParticipantId participant id
-     * @param entryKey key for the entry
-     * @param entryValue value relates to toscaNodeTemplate
-     * @param participantDefinitionUpdates list of participantDefinitionUpdates
+     * @param nodeTemplate the ToscaNodeTemplate
+     * @param toscaServiceTemplate the ToscaServiceTemplate
+     * @return true if the NodeTemplate is an AutomationCompositionElement
      */
-    public static void prepareParticipantDefinitionUpdate(UUID acParticipantId, String entryKey,
-                                                          ToscaNodeTemplate entryValue,
-                                                          List<ParticipantDefinition> participantDefinitionUpdates) {
-
-        var acDefinition = new AutomationCompositionElementDefinition();
-        acDefinition.setAcElementDefinitionId(new ToscaConceptIdentifier(entryKey, entryValue.getVersion()));
-        acDefinition.setAutomationCompositionElementToscaNodeTemplate(entryValue);
-
-        List<AutomationCompositionElementDefinition> automationCompositionElementDefinitionList = new ArrayList<>();
-
-        if (participantDefinitionUpdates.isEmpty()) {
-            participantDefinitionUpdates.add(getParticipantDefinition(acDefinition, acParticipantId,
-                    automationCompositionElementDefinitionList));
+    public static boolean checkIfNodeTemplateIsAutomationCompositionElement(ToscaNodeTemplate nodeTemplate,
+            ToscaServiceTemplate toscaServiceTemplate) {
+        if (nodeTemplate.getType().contains(AUTOMATION_COMPOSITION_ELEMENT)) {
+            return true;
         } else {
-            var participantExists = false;
-            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
-                if (acParticipantId != null || participantDefinitionUpdate.getParticipantId() != null) {
-                    if (participantDefinitionUpdate.getParticipantId().equals(acParticipantId)) {
-                        participantDefinitionUpdate.getAutomationCompositionElementDefinitionList().add(acDefinition);
-                        participantExists = true;
-                    }
+            var nodeType = toscaServiceTemplate.getNodeTypes().get(nodeTemplate.getType());
+            if (nodeType != null) {
+                var derivedFrom = nodeType.getDerivedFrom();
+                if (derivedFrom != null) {
+                    return derivedFrom.contains(AUTOMATION_COMPOSITION_ELEMENT);
                 }
             }
-            if (!participantExists) {
-                participantDefinitionUpdates.add(getParticipantDefinition(acDefinition, acParticipantId,
-                        automationCompositionElementDefinitionList));
+        }
+        return false;
+    }
+
+    /**
+     * Prepare list of ParticipantDefinition for the Priming message.
+     *
+     * @param acElements the extracted AcElements from ServiceTemplate
+     * @param supportedElementMap supported Element Map
+     */
+    public static List<ParticipantDefinition> prepareParticipantPriming(
+            List<Entry<String, ToscaNodeTemplate>> acElements, Map<ToscaConceptIdentifier, UUID> supportedElementMap) {
+
+        Map<UUID, List<AutomationCompositionElementDefinition>> map = new HashMap<>();
+        for (var elementEntry : acElements) {
+            var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(),
+                    elementEntry.getValue().getTypeVersion());
+            var participantId = supportedElementMap.get(type);
+            if (participantId == null) {
+                throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+                        "Element Type " + type + " not supported");
             }
+            var acElementDefinition = new AutomationCompositionElementDefinition();
+            acElementDefinition.setAcElementDefinitionId(
+                    new ToscaConceptIdentifier(elementEntry.getKey(), elementEntry.getValue().getVersion()));
+            acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(elementEntry.getValue());
+            map.putIfAbsent(participantId, new ArrayList<>());
+            map.get(participantId).add(acElementDefinition);
+        }
+        return prepareParticipantPriming(map);
+    }
+
+    /**
+     * Prepare ParticipantPriming.
+     *
+     * @param map of AutomationCompositionElementDefinition with participantId as key
+     * @return list of ParticipantDefinition
+     */
+    public static List<ParticipantDefinition> prepareParticipantPriming(
+            Map<UUID, List<AutomationCompositionElementDefinition>> map) {
+        List<ParticipantDefinition> result = new ArrayList<>();
+        for (var entry : map.entrySet()) {
+            var participantDefinition = new ParticipantDefinition();
+            participantDefinition.setParticipantId(entry.getKey());
+            participantDefinition.setAutomationCompositionElementDefinitionList(entry.getValue());
+            result.add(participantDefinition);
         }
+        return result;
     }
 
-    private static ParticipantDefinition getParticipantDefinition(AutomationCompositionElementDefinition acDefinition,
-            UUID acParticipantId,
-            List<AutomationCompositionElementDefinition> automationCompositionElementDefinitionList) {
-        var participantDefinition = new ParticipantDefinition();
-        participantDefinition.setParticipantId(acParticipantId);
-        automationCompositionElementDefinitionList.add(acDefinition);
-        participantDefinition.setAutomationCompositionElementDefinitionList(automationCompositionElementDefinitionList);
-        return participantDefinition;
+    /**
+     * Extract AcElements from ServiceTemplate.
+     *
+     * @param serviceTemplate the ToscaServiceTemplate
+     * @return the list of Entry of AutomationCompositionElement
+     */
+    public static List<Entry<String, ToscaNodeTemplate>> extractAcElementsFromServiceTemplate(
+            ToscaServiceTemplate serviceTemplate) {
+        return serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet().stream().filter(
+                nodeTemplateEntry -> checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplateEntry.getValue(),
+                        serviceTemplate))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Create NodeTemplateState Map.
+     *
+     * @param acElements extracted AcElements from ServiceTemplate.
+     * @param state the AcTypeState
+     * @return the NodeTemplateState Map
+     */
+    public static Map<String, NodeTemplateState> createElementStateMap(
+            List<Entry<String, ToscaNodeTemplate>> acElements, AcTypeState state) {
+        Map<String, NodeTemplateState> result = new HashMap<>(acElements.size());
+        for (var entry : acElements) {
+            var nodeTemplateState = new NodeTemplateState();
+            nodeTemplateState.setNodeTemplateStateId(UUID.randomUUID());
+            nodeTemplateState.setState(state);
+            nodeTemplateState
+                    .setNodeTemplateId(new ToscaConceptIdentifier(entry.getKey(), entry.getValue().getVersion()));
+            result.put(entry.getKey(), nodeTemplateState);
+        }
+        return result;
     }
 
     /**
index b3efc27..6bb7f1e 100644 (file)
@@ -24,13 +24,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Map;
 import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.models.acm.utils.CommonTestData;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
-import org.onap.policy.common.utils.coder.StandardYamlCoder;
 import org.onap.policy.common.utils.resources.ResourceUtils;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 class ParticipantUtilsTest {
 
@@ -38,12 +36,6 @@ class ParticipantUtilsTest {
     private static final String TOSCA_TEMPLATE_YAML = "examples/acm/test-pm-subscription-handling.yaml";
     private static final String AUTOMATION_COMPOSITION_JSON =
         "src/test/resources/providers/TestAutomationCompositions.json";
-    private static final String AUTOMATION_COMPOSITION_ELEMENT =
-        "org.onap.policy.clamp.acm.AutomationCompositionElement";
-    private static final String POLICY_AUTOMATION_COMPOSITION_ELEMENT =
-        "org.onap.policy.clamp.acm.PolicyAutomationCompositionElement";
-    private static final String PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT = "org.onap.policy.clamp.acm.Participant";
-    private static final StandardYamlCoder YAML_TRANSLATOR = new StandardYamlCoder();
 
     @Test
     void testFindStartPhase() {
@@ -54,30 +46,11 @@ class ParticipantUtilsTest {
 
     @Test
     void testGetFirstStartPhase() throws CoderException {
-        var serviceTemplate =
-            YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(TOSCA_TEMPLATE_YAML), ToscaServiceTemplate.class);
+        var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
         var automationCompositions =
             CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class);
         var result = ParticipantUtils.getFirstStartPhase(automationCompositions.getAutomationCompositionList().get(0),
             serviceTemplate);
         assertThat(result).isZero();
     }
-
-    @Test
-    void testCheckIfNodeTemplateIsAutomationCompositionElement() throws CoderException {
-        var serviceTemplate =
-            YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(TOSCA_TEMPLATE_YAML), ToscaServiceTemplate.class);
-        var nodeTemplate = new ToscaNodeTemplate();
-        nodeTemplate.setType(AUTOMATION_COMPOSITION_ELEMENT);
-        assertThat(ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate))
-            .isTrue();
-
-        nodeTemplate.setType(POLICY_AUTOMATION_COMPOSITION_ELEMENT);
-        assertThat(ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate))
-            .isTrue();
-
-        nodeTemplate.setType(PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT);
-        assertThat(ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate))
-            .isFalse();
-    }
 }
index a27a74b..784f1cf 100644 (file)
@@ -200,6 +200,7 @@ class AcDefinitionProviderTest {
         nodeTemplateState.setNodeTemplateStateId(UUID.randomUUID());
         nodeTemplateState.setNodeTemplateId(new ToscaConceptIdentifier("name", "1.0.0"));
         nodeTemplateState.setState(AcTypeState.COMMISSIONED);
+        nodeTemplateState.setParticipantId(UUID.randomUUID());
         acmDefinition.setElementStateMap(Map.of(nodeTemplateState.getNodeTemplateId().getName(), nodeTemplateState));
         return acmDefinition;
     }
index a40d1cc..0c51378 100644 (file)
@@ -104,6 +104,9 @@ class ParticipantProviderTest {
         when(participantRepository.findAll()).thenReturn(jpaParticipantList);
         assertThat(participantProvider.getParticipants()).hasSize(inputParticipants.size());
 
+        assertThatThrownBy(() -> participantProvider.getParticipantById(inputParticipants.get(0).getParticipantId()))
+                .hasMessageMatching("Participant Not Found with ID: " + inputParticipants.get(0).getParticipantId());
+
         when(participantRepository.findById(any())).thenReturn(
             Optional.ofNullable(jpaParticipantList.get(0)));
 
@@ -128,4 +131,14 @@ class ParticipantProviderTest {
         var deletedParticipant = participantProvider.deleteParticipant(participantId);
         assertThat(inputParticipants.get(0)).usingRecursiveComparison().isEqualTo(deletedParticipant);
     }
+
+    @Test
+    void testGetSupportedElementMap() {
+        var participantRepository = mock(ParticipantRepository.class);
+        when(participantRepository.findAll()).thenReturn(jpaParticipantList);
+        var participantProvider = new ParticipantProvider(participantRepository);
+
+        var result = participantProvider.getSupportedElementMap();
+        assertThat(result).hasSize(2);
+    }
 }
index c5acada..c23c38c 100644 (file)
 package org.onap.policy.clamp.models.acm.utils;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -38,7 +40,7 @@ import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantUpdates;
-import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
@@ -50,7 +52,10 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
 
 class AcmUtilsTest {
 
-    private static final ToscaConceptIdentifier TYPE = new ToscaConceptIdentifier("id", "1.0.0");
+    private static final String POLICY_AUTOMATION_COMPOSITION_ELEMENT =
+            "org.onap.policy.clamp.acm.PolicyAutomationCompositionElement";
+    private static final String PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT = "org.onap.policy.clamp.acm.Participant";
+    private static final String TOSCA_TEMPLATE_YAML = "clamp/acm/pmsh/funtional-pmsh-usecase.yaml";
 
     @Test
     void testCommonUtilsParticipantUpdate() {
@@ -71,6 +76,39 @@ class AcmUtilsTest {
         assertEquals(participantId, participantUpdates.get(1).getParticipantId());
     }
 
+    @Test
+    void testCheckIfNodeTemplateIsAutomationCompositionElement() {
+        var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
+        var nodeTemplate = new ToscaNodeTemplate();
+        nodeTemplate.setType(AcmUtils.AUTOMATION_COMPOSITION_ELEMENT);
+        assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isTrue();
+
+        nodeTemplate.setType(POLICY_AUTOMATION_COMPOSITION_ELEMENT);
+        assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isTrue();
+
+        nodeTemplate.setType(PARTICIPANT_AUTOMATION_COMPOSITION_ELEMENT);
+        assertThat(AcmUtils.checkIfNodeTemplateIsAutomationCompositionElement(nodeTemplate, serviceTemplate)).isFalse();
+    }
+
+    @Test
+    void testPrepareParticipantPriming() {
+        var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
+
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+        Map<ToscaConceptIdentifier, UUID> map = new HashMap<>();
+        var participantId = UUID.randomUUID();
+        assertThatThrownBy(() -> AcmUtils.prepareParticipantPriming(acElements, map)).hasMessageMatching(
+                "Element Type org.onap.policy.clamp.acm.PolicyAutomationCompositionElement 1.0.1 not supported");
+        map.put(new ToscaConceptIdentifier("org.onap.policy.clamp.acm.PolicyAutomationCompositionElement", "1.0.1"),
+                participantId);
+        map.put(new ToscaConceptIdentifier("org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement",
+                "1.0.1"), participantId);
+        map.put(new ToscaConceptIdentifier("org.onap.policy.clamp.acm.HttpAutomationCompositionElement", "1.0.1"),
+                participantId);
+        var result = AcmUtils.prepareParticipantPriming(acElements, map);
+        assertThat(result).isNotEmpty().hasSize(1);
+    }
+
     @Test
     void testCommonUtilsServiceTemplate() {
         var acElement = new AutomationCompositionElement();
@@ -90,7 +128,7 @@ class AcmUtilsTest {
     }
 
     @Test
-    void testValidateAutomationComposition() throws Exception {
+    void testValidateAutomationComposition() {
         var automationComposition = getDummyAutomationComposition();
         var toscaServiceTemplate = getDummyToscaServiceTemplate();
         var result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate);
@@ -102,19 +140,27 @@ class AcmUtilsTest {
         nodeTemplate.setType("org.onap.policy.clamp.acm.AutomationComposition");
         nodeTemplates.put("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", nodeTemplate);
         toscaServiceTemplate.getToscaTopologyTemplate().setNodeTemplates(nodeTemplates);
-        var result2 = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate);
-        toscaServiceTemplate.setToscaTopologyTemplate(null);
-        assertFalse(result2.isValid());
+        result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate);
+        assertFalse(result.isValid());
+
+        var doc = new DocToscaServiceTemplate(CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML));
+        result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative());
+        assertFalse(result.isValid());
     }
 
-    private AutomationComposition getDummyAutomationComposition() throws CoderException {
+    private AutomationComposition getDummyAutomationComposition() {
         var automationComposition = new AutomationComposition();
-        var element = new StandardCoder().decode(
-                new File("src/test/resources/json/AutomationCompositionElementNoOrderedState.json"),
-                AutomationCompositionElement.class);
         automationComposition.setCompositionId(UUID.randomUUID());
         Map<UUID, AutomationCompositionElement> map = new LinkedHashMap<>();
-        map.put(UUID.randomUUID(), element);
+        try {
+            var element = new StandardCoder().decode(
+                new File("src/test/resources/json/AutomationCompositionElementNoOrderedState.json"),
+                AutomationCompositionElement.class);
+            map.put(UUID.randomUUID(), element);
+        } catch (Exception e) {
+            fail("Cannot read or decode " + e.getMessage());
+            return null;
+        }
         automationComposition.setElements(map);
         return automationComposition;
     }
index f324cea..75f2d81 100644 (file)
@@ -209,15 +209,16 @@ public class ParticipantHandler {
             // This message is to decommission the automation composition
             acElementDefsMap.get(participantUpdateMsg.getCompositionId()).clear();
         }
-        sendParticipantUpdateAck(participantUpdateMsg.getMessageId());
+        sendParticipantUpdateAck(participantUpdateMsg.getMessageId(), participantUpdateMsg.getCompositionId());
     }
 
     /**
      * Method to send ParticipantUpdateAck message to automation composition runtime.
      */
-    public void sendParticipantUpdateAck(UUID messageId) {
+    public void sendParticipantUpdateAck(UUID messageId, UUID compositionId) {
         var participantUpdateAck = new ParticipantUpdateAck();
         participantUpdateAck.setResponseTo(messageId);
+        participantUpdateAck.setCompositionId(compositionId);
         participantUpdateAck.setMessage("Participant Update Ack message");
         participantUpdateAck.setResult(true);
         participantUpdateAck.setParticipantId(participantId);
index c538a02..dc04440 100644 (file)
@@ -25,6 +25,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 import java.time.Instant;
 import java.util.List;
@@ -36,14 +39,13 @@ import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantAckMessage;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessage;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.common.utils.coder.CoderException;
 
 class ParticipantHandlerTest {
 
     private final CommonTestData commonTestData = new CommonTestData();
-    private static final String ID_NAME = "org.onap.PM_CDS_Blueprint";
-    private static final String ID_VERSION = "1.0.1";
 
     @Test
     void handleUpdateTest() {
@@ -119,4 +121,14 @@ class ParticipantHandlerTest {
 
     }
 
+    @Test
+    void testHandleParticipantRegisterAck() {
+        var parameters = CommonTestData.getParticipantParameters();
+        var automationCompositionHandler = commonTestData.getMockAutomationCompositionHandler();
+        var publisher = mock(ParticipantMessagePublisher.class);
+        var participantHandler = new ParticipantHandler(parameters, publisher, automationCompositionHandler);
+
+        participantHandler.handleParticipantRegisterAck(new ParticipantRegisterAck());
+        verify(publisher).sendParticipantStatus(any());
+    }
 }
index 450c755..c273a62 100644 (file)
@@ -25,13 +25,14 @@ import java.util.UUID;
 import java.util.stream.Collectors;
 import javax.ws.rs.core.Response.Status;
 import lombok.RequiredArgsConstructor;
-import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.AcTypeStateUpdate;
 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcTypeStateResolver;
 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
-import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -51,8 +52,8 @@ public class CommissioningProvider {
 
     private final AcDefinitionProvider acDefinitionProvider;
     private final AutomationCompositionProvider acProvider;
-    private final SupervisionHandler supervisionHandler;
-    private final ParticipantProvider participantProvider;
+    private final AcTypeStateResolver acTypeStateResolver;
+    private final ParticipantUpdatePublisher participantUpdatePublisher;
 
     private CommissioningResponse createCommissioningResponse(UUID compositionId,
             ToscaServiceTemplate serviceTemplate) {
@@ -80,10 +81,6 @@ public class CommissioningProvider {
 
         var acmDefinition = acDefinitionProvider.createAutomationCompositionDefinition(serviceTemplate);
         serviceTemplate = acmDefinition.getServiceTemplate();
-        var participantList = participantProvider.getParticipants();
-        if (!participantList.isEmpty()) {
-            supervisionHandler.handleSendCommissionMessage(acmDefinition);
-        }
         return createCommissioningResponse(acmDefinition.getCompositionId(), serviceTemplate);
     }
 
@@ -100,7 +97,7 @@ public class CommissioningProvider {
                     "There are ACM instances, Update of ACM Definition not allowed");
         }
         var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
-        if (AcTypeState.COMMISSIONED.equals(acDefinition.getState())) {
+        if (!AcTypeState.COMMISSIONED.equals(acDefinition.getState())) {
             throw new PfModelRuntimeException(Status.BAD_REQUEST,
                     "ACM not in COMMISSIONED state, Update of ACM Definition not allowed");
         }
@@ -116,14 +113,14 @@ public class CommissioningProvider {
      * @return the result of the deletion
      */
     public CommissioningResponse deleteAutomationCompositionDefinition(UUID compositionId) {
-
         if (verifyIfInstanceExists(compositionId)) {
             throw new PfModelRuntimeException(Status.BAD_REQUEST,
                     "Delete instances, to commission automation composition definitions");
         }
-        var participantList = participantProvider.getParticipants();
-        if (!participantList.isEmpty()) {
-            supervisionHandler.handleSendDeCommissionMessage(compositionId);
+        var acDefinition = acDefinitionProvider.getAcDefinition(compositionId);
+        if (!AcTypeState.COMMISSIONED.equals(acDefinition.getState())) {
+            throw new PfModelRuntimeException(Status.BAD_REQUEST,
+                    "ACM not in COMMISSIONED state, Update of ACM Definition not allowed");
         }
         var serviceTemplate = acDefinitionProvider.deleteAcDefintion(compositionId);
         return createCommissioningResponse(compositionId, serviceTemplate);
@@ -165,4 +162,49 @@ public class CommissioningProvider {
     private boolean verifyIfInstanceExists(UUID compositionId) {
         return !acProvider.getAcInstancesByCompositionId(compositionId).isEmpty();
     }
+
+    /**
+     * Composition Definition Priming.
+     *
+     * @param compositionId the compositionId
+     * @param acTypeStateUpdate the ACMTypeStateUpdate
+     */
+    public void compositionDefinitionPriming(UUID compositionId, AcTypeStateUpdate acTypeStateUpdate) {
+        if (verifyIfInstanceExists(compositionId)) {
+            throw new PfModelRuntimeException(Status.BAD_REQUEST, "There are instances, Priming/Depriming not allowed");
+        }
+        var acmDefinition = acDefinitionProvider.getAcDefinition(compositionId);
+        var stateOrdered = acTypeStateResolver.resolve(acTypeStateUpdate.getPrimeOrder(), acmDefinition.getState());
+        switch (stateOrdered) {
+            case PRIME:
+                prime(acmDefinition);
+                break;
+
+            case DEPRIME:
+                deprime(acmDefinition);
+
+                break;
+
+            default:
+                throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acTypeStateUpdate.getPrimeOrder());
+        }
+    }
+
+    private void prime(AutomationCompositionDefinition acmDefinition) {
+        var prearation = participantUpdatePublisher.prepareParticipantPriming(acmDefinition);
+        acDefinitionProvider.updateAcDefinition(acmDefinition);
+        participantUpdatePublisher.sendPriming(prearation, acmDefinition.getCompositionId(), null);
+    }
+
+    private void deprime(AutomationCompositionDefinition acmDefinition) {
+        if (!AcTypeState.COMMISSIONED.equals(acmDefinition.getState())) {
+            for (var elementState : acmDefinition.getElementStateMap().values()) {
+                elementState.setState(AcTypeState.DEPRIMING);
+            }
+            acmDefinition.setState(AcTypeState.DEPRIMING);
+            acDefinitionProvider.updateAcDefinition(acmDefinition);
+        }
+        participantUpdatePublisher.sendDepriming(acmDefinition.getCompositionId());
+    }
+
 }
index b7e7644..4949c66 100644 (file)
@@ -138,12 +138,13 @@ public class AutomationCompositionInstantiationProvider {
     private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) {
 
         var result = new BeanValidationResult("AutomationComposition", automationComposition);
-        var serviceTemplate = acDefinitionProvider.findAcDefinition(automationComposition.getCompositionId());
-        if (serviceTemplate.isEmpty()) {
+        var acDefinitionOpt = acDefinitionProvider.findAcDefinition(automationComposition.getCompositionId());
+        if (acDefinitionOpt.isEmpty()) {
             result.addResult(new ObjectValidationResult("ServiceTemplate", "", ValidationStatus.INVALID,
                     "Commissioned automation composition definition not found"));
         } else {
-            result.addResult(AcmUtils.validateAutomationComposition(automationComposition, serviceTemplate.get()));
+            result.addResult(AcmUtils.validateAutomationComposition(automationComposition,
+                    acDefinitionOpt.get().getServiceTemplate()));
         }
         return result;
     }
index 6d7ae7d..4799880 100644 (file)
@@ -100,7 +100,7 @@ public class CommissioningController extends AbstractRestController implements A
     @Override
     public ResponseEntity<Void> compositionDefinitionPriming(UUID compositionId, UUID requestId,
         @Valid AcTypeStateUpdate body) {
-        // TODO Auto-generated method stub
-        return null;
+        provider.compositionDefinitionPriming(compositionId, body);
+        return ResponseEntity.accepted().build();
     }
 }
index 2c5d487..2542bdb 100644 (file)
@@ -29,10 +29,9 @@ import javax.ws.rs.core.Response;
 import lombok.AllArgsConstructor;
 import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
 import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionUpdatePublisher;
-import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
 import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 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.AutomationCompositionElementAck;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
@@ -69,27 +68,6 @@ public class SupervisionHandler {
     // Publishers for participant communication
     private final AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher;
     private final AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher;
-    private final ParticipantUpdatePublisher participantUpdatePublisher;
-
-    /**
-     * Send commissioning update message to dmaap.
-     *
-     * @param acmDefinition the AutomationComposition Definition
-     */
-    public void handleSendCommissionMessage(AutomationCompositionDefinition acmDefinition) {
-        LOGGER.debug("Participant update message with serviveTemplate {} being sent to all participants",
-            acmDefinition.getCompositionId());
-        participantUpdatePublisher.sendComissioningBroadcast(acmDefinition);
-    }
-
-    /**
-     * Send decommissioning update message to dmaap.
-     *
-     */
-    public void handleSendDeCommissionMessage(UUID compositionId) {
-        LOGGER.debug("Participant update message being sent {}", compositionId);
-        participantUpdatePublisher.sendDecomisioning(compositionId);
-    }
 
     /**
      * Handle a AutomationComposition update acknowledge message from a participant.
@@ -110,10 +88,34 @@ public class SupervisionHandler {
      *
      * @param participantUpdateAckMessage the ParticipantUpdateAck message received from a participant
      */
-    @MessageIntercept
     @Timed(value = "listener.participant_update_ack", description = "PARTICIPANT_UPDATE_ACK messages received")
     public void handleParticipantMessage(ParticipantUpdateAck participantUpdateAckMessage) {
         LOGGER.debug("Participant Update Ack message received {}", participantUpdateAckMessage);
+        var acDefinitionOpt = acDefinitionProvider.findAcDefinition(participantUpdateAckMessage.getCompositionId());
+        if (acDefinitionOpt.isEmpty()) {
+            LOGGER.warn("AC Definition not found in database {}", participantUpdateAckMessage.getCompositionId());
+            return;
+        }
+        var acDefinition = acDefinitionOpt.get();
+        if (!AcTypeState.PRIMING.equals(acDefinition.getState())
+                && !AcTypeState.DEPRIMING.equals(acDefinition.getState())) {
+            LOGGER.warn("AC Definition {} already primed/deprimed with participant {}",
+                    participantUpdateAckMessage.getCompositionId(), participantUpdateAckMessage.getParticipantId());
+            return;
+        }
+        var state = AcTypeState.PRIMING.equals(acDefinition.getState()) ? AcTypeState.PRIMED : AcTypeState.COMMISSIONED;
+        boolean completed = true;
+        for (var element : acDefinition.getElementStateMap().values()) {
+            if (participantUpdateAckMessage.getParticipantId().equals(element.getParticipantId())) {
+                element.setState(state);
+            } else if (!state.equals(element.getState())) {
+                completed = false;
+            }
+        }
+        if (completed) {
+            acDefinition.setState(state);
+        }
+        acDefinitionProvider.updateAcDefinition(acDefinition);
     }
 
     /**
index e4bfedd..1915f1b 100644 (file)
@@ -24,16 +24,18 @@ package org.onap.policy.clamp.acm.runtime.supervision.comm;
 
 import io.micrometer.core.annotation.Timed;
 import java.time.Instant;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import lombok.AllArgsConstructor;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
-import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdate;
-import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
 import org.onap.policy.clamp.models.acm.utils.AcmUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -47,72 +49,67 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantUpdatePublisher.class);
 
-    private final AcDefinitionProvider acDefinitionProvider;
-
-    /**
-     * Send ParticipantUpdate to all Participants.
-     *
-     * @param acmDefinition the AutomationComposition Definition
-     */
-    @Timed(value = "publisher.participant_update", description = "PARTICIPANT_UPDATE messages published")
-    public void sendComissioningBroadcast(AutomationCompositionDefinition acmDefinition) {
-        sendCommissioning(acmDefinition, null);
-    }
+    private final ParticipantProvider participantProvider;
 
     /**
      * Send ParticipantUpdate to Participant
      * if participantId is null then message is broadcast.
      *
+     * @param participantDefinitions the list of ParticipantDefinition to send
+     * @param compositionId the compositionId
      * @param participantId the ParticipantId
      */
     @Timed(value = "publisher.participant_update", description = "PARTICIPANT_UPDATE messages published")
-    public void sendCommissioning(UUID participantId) {
-        var list = acDefinitionProvider.getAllAcDefinitions();
-        if (list.isEmpty()) {
-            LOGGER.warn("No tosca service template found, cannot send participantupdate");
-        }
-        for (var acmDefinition : list) {
-            sendCommissioning(acmDefinition, participantId);
-        }
+    public void sendPriming(List<ParticipantDefinition> participantDefinitions, UUID compositionId,
+            UUID participantId) {
+        var message = new ParticipantUpdate();
+        message.setCompositionId(compositionId);
+        message.setParticipantId(participantId);
+        message.setTimestamp(Instant.now());
+        message.setParticipantDefinitionUpdates(participantDefinitions);
+        LOGGER.debug("Participant Update sent {}", message);
+        super.send(message);
     }
 
     /**
-     * Send ParticipantUpdate to Participant
-     * if participantId is null then message is broadcast.
+     * Pepare the Priming message creating the list of ParticipantDefinition to send
+     * and fill the ElementState map of the AC Definition.
      *
      * @param acmDefinition the AutomationComposition Definition
-     * @param participantId the ParticipantId
+     * @return list of ParticipantDefinition
      */
-    @Timed(value = "publisher.participant_update", description = "PARTICIPANT_UPDATE messages published")
-    public void sendCommissioning(AutomationCompositionDefinition acmDefinition,
-            UUID participantId) {
-        var message = new ParticipantUpdate();
-        message.setCompositionId(acmDefinition.getCompositionId());
-        message.setParticipantId(participantId);
-        message.setTimestamp(Instant.now());
-
-        var toscaServiceTemplate = acmDefinition.getServiceTemplate();
-        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
-        for (var toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
-            if (ParticipantUtils.checkIfNodeTemplateIsAutomationCompositionElement(toscaInputEntry.getValue(),
-                    toscaServiceTemplate)) {
-                AcmUtils.prepareParticipantDefinitionUpdate(
-                        participantId,
-                        toscaInputEntry.getKey(), toscaInputEntry.getValue(), participantDefinitionUpdates);
+    public List<ParticipantDefinition> prepareParticipantPriming(AutomationCompositionDefinition acmDefinition) {
+        acmDefinition.setState(AcTypeState.PRIMING);
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(acmDefinition.getServiceTemplate());
+        Map<ToscaConceptIdentifier, UUID> supportedElementMap = new HashMap<>();
+        if (AcTypeState.PRIMED.equals(acmDefinition.getState())) {
+            // scenario Prime again, participants already assigned
+            for (var elementEntry : acElements) {
+                var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey());
+                elementState.setState(AcTypeState.PRIMING);
+                var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(),
+                        elementEntry.getValue().getTypeVersion());
+                supportedElementMap.put(type, elementState.getParticipantId());
+            }
+        } else {
+            // scenario Prime participants not assigned yet
+            supportedElementMap = participantProvider.getSupportedElementMap();
+            for (var elementEntry : acElements) {
+                var elementState = acmDefinition.getElementStateMap().get(elementEntry.getKey());
+                elementState.setState(AcTypeState.PRIMING);
+                var type = new ToscaConceptIdentifier(elementEntry.getValue().getType(),
+                        elementEntry.getValue().getTypeVersion());
+                elementState.setParticipantId(supportedElementMap.get(type));
             }
         }
-
-        // Commission the automation composition but sending participantdefinitions to participants
-        message.setParticipantDefinitionUpdates(participantDefinitionUpdates);
-        LOGGER.debug("Participant Update sent {}", message);
-        super.send(message);
+        return AcmUtils.prepareParticipantPriming(acElements, supportedElementMap);
     }
 
     /**
      * Send ParticipantUpdate to Participant after that commissioning has been removed.
      */
     @Timed(value = "publisher.participant_update", description = "PARTICIPANT_UPDATE messages published")
-    public void sendDecomisioning(UUID compositionId) {
+    public void sendDepriming(UUID compositionId) {
         var message = new ParticipantUpdate();
         message.setCompositionId(compositionId);
         message.setTimestamp(Instant.now());
index 6ecb8e6..071fc26 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.policy.clamp.acm.runtime.commissioning;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -32,13 +33,16 @@ import java.util.List;
 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.SupervisionHandler;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 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.Participant;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.AcTypeStateUpdate;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcTypeStateResolver;
 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
-import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 class CommissioningProviderTest {
@@ -51,16 +55,14 @@ class CommissioningProviderTest {
     @Test
     void testGetAutomationCompositionDefinitions() {
         var acProvider = mock(AutomationCompositionProvider.class);
-        var participantProvider = mock(ParticipantProvider.class);
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
 
-        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, participantProvider);
+        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null);
 
         var serviceTemplates = provider.getAutomationCompositionDefinitions(null, null);
         assertThat(serviceTemplates.getServiceTemplates()).isEmpty();
 
-        when(acDefinitionProvider.getServiceTemplateList(null, null))
-                .thenReturn(List.of(new ToscaServiceTemplate()));
+        when(acDefinitionProvider.getServiceTemplateList(null, null)).thenReturn(List.of(new ToscaServiceTemplate()));
         serviceTemplates = provider.getAutomationCompositionDefinitions(null, null);
         assertThat(serviceTemplates.getServiceTemplates()).hasSize(1);
     }
@@ -81,16 +83,11 @@ class CommissioningProviderTest {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         when(acDefinitionProvider.createAutomationCompositionDefinition(serviceTemplate)).thenReturn(acmDefinition);
 
-        var participantProvider = mock(ParticipantProvider.class);
-        when(participantProvider.getParticipants()).thenReturn(List.of(new Participant()));
         var acProvider = mock(AutomationCompositionProvider.class);
-        var supervisionHandler = mock(SupervisionHandler.class);
-        var provider =
-                new CommissioningProvider(acDefinitionProvider, acProvider, supervisionHandler, participantProvider);
-        var affectedDefinitions = provider
-                .createAutomationCompositionDefinition(serviceTemplate).getAffectedAutomationCompositionDefinitions();
+        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null);
+        var affectedDefinitions = provider.createAutomationCompositionDefinition(serviceTemplate)
+                .getAffectedAutomationCompositionDefinitions();
         verify(acDefinitionProvider).createAutomationCompositionDefinition(serviceTemplate);
-        verify(supervisionHandler).handleSendCommissionMessage(acmDefinition);
         // Response should return the number of node templates present in the service template
         assertThat(affectedDefinitions).hasSize(7);
     }
@@ -104,10 +101,8 @@ class CommissioningProviderTest {
     void testGetToscaServiceTemplateList() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         var acProvider = mock(AutomationCompositionProvider.class);
-        var participantProvider = mock(ParticipantProvider.class);
 
-        var provider =
-                new CommissioningProvider(acDefinitionProvider, acProvider, null, participantProvider);
+        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null);
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         when(acDefinitionProvider.getServiceTemplateList(null, null)).thenReturn(List.of(serviceTemplate));
 
@@ -120,12 +115,11 @@ class CommissioningProviderTest {
     void testDeletecDefinitionDabRequest() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         var acProvider = mock(AutomationCompositionProvider.class);
-        var participantProvider = mock(ParticipantProvider.class);
 
         var compositionId = UUID.randomUUID();
         when(acProvider.getAcInstancesByCompositionId(compositionId)).thenReturn(List.of(new AutomationComposition()));
 
-        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, participantProvider);
+        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null);
 
         assertThatThrownBy(() -> provider.deleteAutomationCompositionDefinition(compositionId))
                 .hasMessageMatching("Delete instances, to commission automation composition definitions");
@@ -133,22 +127,59 @@ class CommissioningProviderTest {
 
     @Test
     void testDeleteAutomationCompositionDefinition() {
-        var participantProvider = mock(ParticipantProvider.class);
-        when(participantProvider.getParticipants()).thenReturn(List.of(new Participant()));
-
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         var compositionId = UUID.randomUUID();
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         when(acDefinitionProvider.deleteAcDefintion(compositionId)).thenReturn(serviceTemplate);
 
+        var acmDefinition = new AutomationCompositionDefinition();
+        acmDefinition.setCompositionId(compositionId);
+        acmDefinition.setServiceTemplate(serviceTemplate);
+        acmDefinition.setState(AcTypeState.COMMISSIONED);
+        when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition);
+
         var acProvider = mock(AutomationCompositionProvider.class);
-        var supervisionHandler = mock(SupervisionHandler.class);
-        var provider =
-                new CommissioningProvider(acDefinitionProvider, acProvider, supervisionHandler, participantProvider);
+        var provider = new CommissioningProvider(acDefinitionProvider, acProvider, null, null);
 
         provider.deleteAutomationCompositionDefinition(compositionId);
 
-        verify(supervisionHandler).handleSendDeCommissionMessage(compositionId);
         verify(acDefinitionProvider).deleteAcDefintion(compositionId);
     }
+
+    @Test
+    void testPriming() {
+        var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        var acmDefinition = CommonTestData.createAcDefinition(
+                InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.COMMISSIONED);
+        var compositionId = acmDefinition.getCompositionId();
+        when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition);
+
+        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+        var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class),
+                new AcTypeStateResolver(), participantUpdatePublisher);
+
+        var acTypeStateUpdate = new AcTypeStateUpdate();
+        acTypeStateUpdate.setPrimeOrder(PrimeOrder.PRIME);
+        provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate);
+        verify(acDefinitionProvider).updateAcDefinition(acmDefinition);
+        verify(participantUpdatePublisher).sendPriming(any(), any(), any());
+    }
+
+    @Test
+    void testDepriming() {
+        var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        var acmDefinition = CommonTestData.createAcDefinition(
+                InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED);
+        var compositionId = acmDefinition.getCompositionId();
+        when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acmDefinition);
+
+        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+        var provider = new CommissioningProvider(acDefinitionProvider, mock(AutomationCompositionProvider.class),
+                new AcTypeStateResolver(), participantUpdatePublisher);
+
+        var acTypeStateUpdate = new AcTypeStateUpdate();
+        acTypeStateUpdate.setPrimeOrder(PrimeOrder.DEPRIME);
+        provider.compositionDefinitionPriming(compositionId, acTypeStateUpdate);
+        verify(participantUpdatePublisher).sendDepriming(compositionId);
+    }
 }
index 53fa945..73f3a68 100644 (file)
@@ -40,7 +40,9 @@ import org.junit.jupiter.api.extension.ExtendWith;
 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.AcTypeStateUpdate;
 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
@@ -207,6 +209,16 @@ class CommissioningControllerTest extends CommonRestController {
         assertThat(templatesInDB).isEmpty();
     }
 
+    @Test
+    void testPrimeBadRequest() {
+        var compositionId = createEntryInDB("Prime");
+        var invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/" + compositionId);
+        var body = new AcTypeStateUpdate();
+        body.setPrimeOrder(PrimeOrder.PRIME);
+        var resp = invocationBuilder.put(Entity.json(body));
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+    }
+
     private UUID createEntryInDB(String name) {
         var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate);
         serviceTemplateCreate.setName(name);
index cd6e021..0a46bc6 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2022 Nordix Foundation.
+ *  Copyright (C) 2021-2023 Nordix Foundation.
  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,6 +37,7 @@ import org.mockito.Mockito;
 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler;
 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
 import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationCommand;
@@ -90,8 +91,9 @@ class AutomationCompositionInstantiationProviderTest {
         when(participantProvider.getParticipants()).thenReturn(participants);
 
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
-        var compositionId = UUID.randomUUID();
-        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(serviceTemplate));
+        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+        var compositionId = acDefinition.getCompositionId();
+        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
         var supervisionHandler = mock(SupervisionHandler.class);
         var acProvider = mock(AutomationCompositionProvider.class);
         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, supervisionHandler,
@@ -203,8 +205,9 @@ class AutomationCompositionInstantiationProviderTest {
     @Test
     void testCreateAutomationCompositions_NoDuplicates() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
-        var compositionId = UUID.randomUUID();
-        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(serviceTemplate));
+        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+        var compositionId = acDefinition.getCompositionId();
+        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
 
         var automationCompositionCreate =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "NoDuplicates");
@@ -236,8 +239,9 @@ class AutomationCompositionInstantiationProviderTest {
     @Test
     void testCreateAutomationCompositions_CommissionedAcElementNotFound() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
-        var compositionId = UUID.randomUUID();
-        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(serviceTemplate));
+        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+        var compositionId = acDefinition.getCompositionId();
+        when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(
                 AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "AcElementNotFound");
         automationComposition.setCompositionId(compositionId);
index aa89059..c653570 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.onap.policy.clamp.acm.runtime.supervision;
 
-import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -39,9 +38,9 @@ import org.mockito.Mockito;
 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
 import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionUpdatePublisher;
-import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
 import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 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.AutomationCompositionOrderedState;
@@ -52,7 +51,7 @@ import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMe
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck;
 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
 import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
-import org.onap.policy.models.base.PfModelException;
+
 
 class SupervisionHandlerTest {
     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
@@ -102,8 +101,7 @@ class SupervisionHandlerTest {
 
         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
         var handler = new SupervisionHandler(automationCompositionProvider, acDefinitionProvider,
-                mock(AutomationCompositionUpdatePublisher.class), automationCompositionStateChangePublisher,
-                mock(ParticipantUpdatePublisher.class));
+                mock(AutomationCompositionUpdatePublisher.class), automationCompositionStateChangePublisher);
 
         handler.triggerAutomationCompositionSupervision(automationComposition);
 
@@ -152,8 +150,7 @@ class SupervisionHandlerTest {
         var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
         var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class),
                 mock(AutomationCompositionUpdatePublisher.class), automationCompositionStateChangePublisher,
-                mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
+                AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.UNINITIALISED);
 
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
@@ -197,8 +194,7 @@ class SupervisionHandlerTest {
         var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
         var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class),
                 mock(AutomationCompositionUpdatePublisher.class), automationCompositionStateChangePublisher,
-                mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
+                AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.UNINITIALISED);
 
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
@@ -215,8 +211,7 @@ class SupervisionHandlerTest {
         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
         var handler = createSupervisionHandler(automationCompositionProvider,
                 mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
+                AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.UNINITIALISED);
         var automationCompositionAckMessage =
                 new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
         automationCompositionAckMessage.setAutomationCompositionResultMap(Map.of());
@@ -237,8 +232,7 @@ class SupervisionHandlerTest {
         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
         var handler = createSupervisionHandler(automationCompositionProvider,
                 mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
+                AutomationCompositionOrderedState.PASSIVE, AutomationCompositionState.UNINITIALISED);
 
         handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
 
@@ -246,48 +240,68 @@ class SupervisionHandlerTest {
     }
 
     @Test
-    void testParticipantUpdateAck() {
+    void testParticipantUpdateAckNotFound() {
         var participantUpdateAckMessage = new ParticipantUpdateAck();
         participantUpdateAckMessage.setParticipantId(CommonTestData.getParticipantId());
         participantUpdateAckMessage.setState(ParticipantState.ON_LINE);
-        var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class),
-                mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
+        var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        var handler = new SupervisionHandler(mock(AutomationCompositionProvider.class), acDefinitionProvider,
+                mock(AutomationCompositionUpdatePublisher.class),
+                mock(AutomationCompositionStateChangePublisher.class));
 
-        assertThatCode(() -> handler.handleParticipantMessage(participantUpdateAckMessage)).doesNotThrowAnyException();
+        handler.handleParticipantMessage(participantUpdateAckMessage);
+        verify(acDefinitionProvider).findAcDefinition(any());
     }
 
     @Test
-    void testHandleSendCommissionMessage() {
-        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
-        var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class),
-                mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                participantUpdatePublisher, AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
-        var acmDefinition = new AutomationCompositionDefinition();
-        handler.handleSendCommissionMessage(acmDefinition);
+    void testParticipantUpdateAckPrimed() {
+        var participantUpdateAckMessage = new ParticipantUpdateAck();
+        participantUpdateAckMessage.setParticipantId(CommonTestData.getParticipantId());
+        participantUpdateAckMessage.setState(ParticipantState.ON_LINE);
+
+        var acDefinition = CommonTestData.createAcDefinition(
+                InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMED);
+        participantUpdateAckMessage.setCompositionId(acDefinition.getCompositionId());
+
+        var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId()))
+                .thenReturn(Optional.of(acDefinition));
 
-        verify(participantUpdatePublisher).sendComissioningBroadcast(acmDefinition);
+        var handler = new SupervisionHandler(mock(AutomationCompositionProvider.class), acDefinitionProvider,
+                mock(AutomationCompositionUpdatePublisher.class),
+                mock(AutomationCompositionStateChangePublisher.class));
+
+        handler.handleParticipantMessage(participantUpdateAckMessage);
+        verify(acDefinitionProvider).findAcDefinition(any());
     }
 
     @Test
-    void testHandleSendDeCommissionMessage() throws PfModelException {
-        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
-        var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class),
-                mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                participantUpdatePublisher, AutomationCompositionOrderedState.PASSIVE,
-                AutomationCompositionState.UNINITIALISED);
-        handler.handleSendDeCommissionMessage(IDENTIFIER);
+    void testParticipantUpdateAck() {
+        var participantUpdateAckMessage = new ParticipantUpdateAck();
+        participantUpdateAckMessage.setParticipantId(CommonTestData.getParticipantId());
+        participantUpdateAckMessage.setState(ParticipantState.ON_LINE);
+
+        var acDefinition = CommonTestData.createAcDefinition(
+                InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML), AcTypeState.PRIMING);
+        participantUpdateAckMessage.setCompositionId(acDefinition.getCompositionId());
+
+        var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        when(acDefinitionProvider.findAcDefinition(acDefinition.getCompositionId()))
+                .thenReturn(Optional.of(acDefinition));
 
-        verify(participantUpdatePublisher).sendDecomisioning(IDENTIFIER);
+        var handler = new SupervisionHandler(mock(AutomationCompositionProvider.class), acDefinitionProvider,
+                mock(AutomationCompositionUpdatePublisher.class),
+                mock(AutomationCompositionStateChangePublisher.class));
+
+        handler.handleParticipantMessage(participantUpdateAckMessage);
+        verify(acDefinitionProvider).findAcDefinition(any());
+        verify(acDefinitionProvider).updateAcDefinition(any());
     }
 
     private SupervisionHandler createSupervisionHandler(AutomationCompositionProvider automationCompositionProvider,
             AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher,
             AutomationCompositionStateChangePublisher automationCompositionStateChangePublisher,
-            ParticipantUpdatePublisher participantUpdatePublisher, AutomationCompositionOrderedState orderedState,
-            AutomationCompositionState state) {
+            AutomationCompositionOrderedState orderedState, AutomationCompositionState state) {
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
 
@@ -306,21 +320,19 @@ class SupervisionHandlerTest {
         when(acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId())).thenReturn(acDefinition);
 
         return new SupervisionHandler(automationCompositionProvider, acDefinitionProvider,
-                automationCompositionUpdatePublisher, automationCompositionStateChangePublisher,
-                participantUpdatePublisher);
+                automationCompositionUpdatePublisher, automationCompositionStateChangePublisher);
     }
 
     private SupervisionHandler createSupervisionHandlerForTrigger() {
         return new SupervisionHandler(mock(AutomationCompositionProvider.class), mock(AcDefinitionProvider.class),
-                mock(AutomationCompositionUpdatePublisher.class), mock(AutomationCompositionStateChangePublisher.class),
-                mock(ParticipantUpdatePublisher.class));
+                mock(AutomationCompositionUpdatePublisher.class),
+                mock(AutomationCompositionStateChangePublisher.class));
     }
 
     private SupervisionHandler createSupervisionHandlerForTrigger(
             AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher) {
 
         return new SupervisionHandler(mock(AutomationCompositionProvider.class), mock(AcDefinitionProvider.class),
-                automationCompositionUpdatePublisher, mock(AutomationCompositionStateChangePublisher.class),
-                mock(ParticipantUpdatePublisher.class));
+                automationCompositionUpdatePublisher, mock(AutomationCompositionStateChangePublisher.class));
     }
 }
index 5ea3bea..d558dea 100644 (file)
@@ -25,16 +25,20 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 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.SupervisionHandler;
 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionParticipantHandler;
 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 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.AutomationCompositionState;
@@ -46,9 +50,11 @@ import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRe
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck;
-import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 class SupervisionMessagesTest {
 
@@ -133,16 +139,28 @@ class SupervisionMessagesTest {
 
     @Test
     void testParticipantUpdatePublisherDecomisioning() {
-        var publisher = new ParticipantUpdatePublisher(mock(AcDefinitionProvider.class));
+        var publisher = new ParticipantUpdatePublisher(mock(ParticipantProvider.class));
         var topicSink = mock(TopicSink.class);
         publisher.active(List.of(topicSink));
-        publisher.sendDecomisioning(UUID.randomUUID());
+        publisher.sendDepriming(UUID.randomUUID());
         verify(topicSink).send(anyString());
     }
 
     @Test
-    void testParticipantUpdatePublisherComissioning() {
-        var publisher = new ParticipantUpdatePublisher(mock(AcDefinitionProvider.class));
+    void testParticipantUpdatePublisherPriming() {
+        var participantId = UUID.randomUUID();
+        Map<ToscaConceptIdentifier, UUID> supportedElementMap = new HashMap<>();
+        supportedElementMap.put(
+                new ToscaConceptIdentifier("org.onap.policy.clamp.acm.PolicyAutomationCompositionElement", "1.0.1"),
+                participantId);
+        supportedElementMap.put(new ToscaConceptIdentifier(
+                "org.onap.policy.clamp.acm.K8SMicroserviceAutomationCompositionElement", "1.0.1"), participantId);
+        supportedElementMap.put(
+                new ToscaConceptIdentifier("org.onap.policy.clamp.acm.HttpAutomationCompositionElement", "1.0.1"),
+                participantId);
+        var participantProvider = mock(ParticipantProvider.class);
+        when(participantProvider.getSupportedElementMap()).thenReturn(supportedElementMap);
+        var publisher = new ParticipantUpdatePublisher(participantProvider);
         var topicSink = mock(TopicSink.class);
         publisher.active(List.of(topicSink));
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
@@ -151,7 +169,10 @@ class SupervisionMessagesTest {
         var acmDefinition = new AutomationCompositionDefinition();
         acmDefinition.setCompositionId(UUID.randomUUID());
         acmDefinition.setServiceTemplate(serviceTemplate);
-        publisher.sendComissioningBroadcast(acmDefinition);
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+        acmDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, AcTypeState.COMMISSIONED));
+        var preparation = publisher.prepareParticipantPriming(acmDefinition);
+        publisher.sendPriming(preparation, acmDefinition.getCompositionId(), null);
         verify(topicSink).send(anyString());
     }
 
index b991409..702a936 100644 (file)
@@ -25,11 +25,15 @@ import java.util.UUID;
 import javax.ws.rs.core.Response.Status;
 import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
 import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
 import org.onap.policy.clamp.models.acm.concepts.Participant;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 /**
  * Class to hold/create all parameters for test cases.
@@ -37,8 +41,7 @@ import org.onap.policy.common.utils.resources.ResourceUtils;
  */
 public class CommonTestData {
     private static final Coder CODER = new StandardCoder();
-    public static final String TOSCA_SERVICE_TEMPLATE_YAML =
-        "clamp/acm/pmsh/funtional-pmsh-usecase.yaml";
+    public static final String TOSCA_SERVICE_TEMPLATE_YAML = "clamp/acm/pmsh/funtional-pmsh-usecase.yaml";
 
     /**
      * Gets the standard automation composition parameters.
@@ -53,7 +56,7 @@ public class CommonTestData {
 
         } catch (CoderException e) {
             throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE,
-                "cannot read automation composition parameters", e);
+                    "cannot read automation composition parameters", e);
         }
     }
 
@@ -65,7 +68,7 @@ public class CommonTestData {
      */
     public static String getParameterGroupAsString(final String dbName) {
         return ResourceUtils.getResourceAsString("src/test/resources/parameters/TestParameters.json")
-            .replace("${dbName}", "jdbc:h2:mem:" + dbName);
+                .replace("${dbName}", "jdbc:h2:mem:" + dbName);
     }
 
     /**
@@ -95,4 +98,23 @@ public class CommonTestData {
     public static UUID getParticipantId() {
         return UUID.fromString("101c62b3-8918-41b9-a747-d21eb79c6c03");
     }
+
+    /**
+     * Create a new AutomationCompositionDefinition.
+     *
+     * @param serviceTemplate the serviceTemplate
+     * @param state the AcTypeState
+     * @return a new AutomationCompositionDefinition
+     */
+    public static AutomationCompositionDefinition createAcDefinition(ToscaServiceTemplate serviceTemplate,
+            AcTypeState state) {
+        var acDefinition = new AutomationCompositionDefinition();
+        acDefinition.setCompositionId(UUID.randomUUID());
+        acDefinition.setState(state);
+        acDefinition.setServiceTemplate(serviceTemplate);
+        var acElements = AcmUtils.extractAcElementsFromServiceTemplate(serviceTemplate);
+        acDefinition.setElementStateMap(AcmUtils.createElementStateMap(acElements, state));
+        return acDefinition;
+    }
+
 }