Add support for composition outProperties in ACM intermediary

Issue-ID: POLICY-4783
Change-Id: Ib0c89298a29a3524787e11ff7e25d3d22d01b534
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java
old mode 100644
new mode 100755
index 1111f20..5ea4092
--- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java
+++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/endtoend/ParticipantMessagesTest.java
@@ -142,14 +142,4 @@
                 .doesNotThrowAnyException();
         }
     }
-
-    @Test
-    void testParticipantStatusHeartbeat() {
-        final var heartbeat = participantHandler.makeHeartbeat(true);
-        synchronized (lockit) {
-            var publisher = new ParticipantMessagePublisher();
-            publisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
-            assertThatCode(() -> publisher.sendHeartbeat(heartbeat)).doesNotThrowAnyException();
-        }
-    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
old mode 100644
new mode 100755
index 8b800a8..bca5f48
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
@@ -26,9 +26,11 @@
 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.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 /**
  * This interface is used by participant implementations to use the participant intermediary.
@@ -56,6 +58,14 @@
     Map<UUID, AutomationComposition> getAutomationCompositions();
 
     /**
+     * Get a copy of the AutomationComposition by automationCompositionId.
+     *
+     * @param automationCompositionId the ID of the automation composition to update the state on
+     * @return get the AutomationComposition
+     */
+    AutomationComposition getAutomationComposition(UUID automationCompositionId);
+
+    /**
      * Get a copy of the AutomationCompositionElement by automationCompositionId and elementId.
      *
      * @param automationCompositionId the ID of the automation composition to update the state on
@@ -64,6 +74,13 @@
      */
     AutomationCompositionElement getAutomationCompositionElement(UUID automationCompositionId, UUID elementId);
 
+    Map<UUID, Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition>> getAcElementsDefinitions();
+
+    Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> getAcElementsDefinitions(UUID compositionId);
+
+    AutomationCompositionElementDefinition getAcElementDefinition(UUID compositionId,
+            ToscaConceptIdentifier elementId);
+
     /**
      * Send Automation Composition Element update Info to AC-runtime.
      *
@@ -76,6 +93,8 @@
     void sendAcElementInfo(UUID automationCompositionId, UUID id, String useState, String operationalState,
             Map<String, Object> outProperties);
 
+    void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId, Map<String, Object> outProperties);
+
     void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult,
             String message);
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
old mode 100644
new mode 100755
index ca5f087..5cdbaca
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
@@ -30,10 +30,12 @@
 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.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.springframework.stereotype.Component;
 
 /**
@@ -81,4 +83,43 @@
         var element = automationComposition.getElements().get(elementId);
         return element != null ? new AutomationCompositionElement(element) : null;
     }
+
+    @Override
+    public void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId,
+            Map<String, Object> outProperties) {
+        automationCompositionHandler.sendAcDefinitionInfo(compositionId, elementId, outProperties);
+    }
+
+    @Override
+    public AutomationComposition getAutomationComposition(UUID automationCompositionId) {
+        var automationComposition = cacheProvider.getAutomationCompositions().get(automationCompositionId);
+        return automationComposition != null ? new AutomationComposition(automationComposition) : null;
+    }
+
+    @Override
+    public Map<UUID, Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition>> getAcElementsDefinitions() {
+        return PfUtils.mapMap(cacheProvider.getAcElementsDefinitions(),
+                map -> PfUtils.mapMap(map, AutomationCompositionElementDefinition::new));
+    }
+
+    @Override
+    public Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> getAcElementsDefinitions(
+            UUID compositionId) {
+        var acElementDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId);
+        if (acElementDefinitions == null) {
+            return null;
+        }
+        return PfUtils.mapMap(acElementDefinitions, AutomationCompositionElementDefinition::new);
+    }
+
+    @Override
+    public AutomationCompositionElementDefinition getAcElementDefinition(UUID compositionId,
+            ToscaConceptIdentifier elementId) {
+        var acElementDefinitions = cacheProvider.getAcElementsDefinitions().get(compositionId);
+        if (acElementDefinitions == null) {
+            return null;
+        }
+        var acElementDefinition = acElementDefinitions.get(elementId);
+        return acElementDefinition != null ? new AutomationCompositionElementDefinition(acElementDefinition) : null;
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
index bd5f142..3023cdd 100755
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
@@ -29,16 +29,19 @@
 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.AutomationCompositionElementInfo;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeployAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -159,29 +162,27 @@
         var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
         if (automationComposition == null) {
             LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
-                    automationComposition);
+                    automationCompositionId);
             return;
         }
 
         var element = automationComposition.getElements().get(elementId);
         if (element == null) {
             var msg = "Cannot update Automation composition element state, AC Element id {} not present";
-            LOGGER.error(msg, automationComposition);
+            LOGGER.error(msg, elementId);
             return;
         }
         element.setOperationalState(operationalState);
         element.setUseState(useState);
         element.setOutProperties(outProperties);
 
-        var statusMsg = new ParticipantStatus();
-        statusMsg.setParticipantId(cacheProvider.getParticipantId());
-        statusMsg.setState(ParticipantState.ON_LINE);
-        statusMsg.setParticipantSupportedElementType(cacheProvider.getSupportedAcElementTypes());
         var acInfo = new AutomationCompositionInfo();
         acInfo.setAutomationCompositionId(automationCompositionId);
         acInfo.setDeployState(automationComposition.getDeployState());
         acInfo.setLockState(automationComposition.getLockState());
         acInfo.setElements(List.of(getAutomationCompositionElementInfo(element)));
+        var statusMsg = createParticipantStatus();
+        statusMsg.setCompositionId(automationComposition.getCompositionId());
         statusMsg.setAutomationCompositionInfoList(List.of(acInfo));
         publisher.sendParticipantStatus(statusMsg);
     }
@@ -225,4 +226,59 @@
         publisher.sendParticipantPrimeAck(participantPrimeAck);
         cacheProvider.getMsgIdentification().remove(compositionId);
     }
+
+    /**
+     * Send Composition Definition Info.
+     *
+     * @param compositionId the composition id
+     * @param elementId the Composition Definition Element id
+     * @param outProperties the output Properties Map
+     */
+    public void sendAcDefinitionInfo(UUID compositionId, ToscaConceptIdentifier elementId,
+            Map<String, Object> outProperties) {
+        if (compositionId == null) {
+            LOGGER.error("Cannot send Composition outProperties, id is null");
+            return;
+        }
+        var statusMsg = createParticipantStatus();
+        statusMsg.setCompositionId(compositionId);
+        var acElementDefsMap = cacheProvider.getAcElementsDefinitions();
+        var acElementsDefinitions = acElementDefsMap.get(compositionId);
+        if (acElementsDefinitions == null) {
+            LOGGER.error("Cannot send Composition outProperties, id {} is null", compositionId);
+            return;
+        }
+        var acElementDefinition = getAutomationCompositionElementDefinition(acElementsDefinitions, elementId);
+        if (acElementDefinition == null) {
+            LOGGER.error("Cannot send Composition outProperties, elementId {} not present", elementId);
+            return;
+        }
+        acElementDefinition.setOutProperties(outProperties);
+        var participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(cacheProvider.getParticipantId());
+        participantDefinition.setAutomationCompositionElementDefinitionList(List.of(acElementDefinition));
+        statusMsg.setParticipantDefinitionUpdates(List.of(participantDefinition));
+        publisher.sendHeartbeat(statusMsg);
+    }
+
+    private AutomationCompositionElementDefinition getAutomationCompositionElementDefinition(
+            Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> acElementsDefinition,
+            ToscaConceptIdentifier elementId) {
+
+        if (elementId == null) {
+            if (acElementsDefinition.size() == 1) {
+                return acElementsDefinition.values().iterator().next();
+            }
+            return null;
+        }
+        return acElementsDefinition.get(elementId);
+    }
+
+    private ParticipantStatus createParticipantStatus() {
+        var statusMsg = new ParticipantStatus();
+        statusMsg.setParticipantId(cacheProvider.getParticipantId());
+        statusMsg.setState(ParticipantState.ON_LINE);
+        statusMsg.setParticipantSupportedElementType(cacheProvider.getSupportedAcElementTypes());
+        return statusMsg;
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
index 5f07518..6d7ff2c 100755
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
@@ -30,7 +30,6 @@
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionInfo;
-import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange;
@@ -69,8 +68,7 @@
      */
     @Timed(value = "listener.participant_status_req", description = "PARTICIPANT_STATUS_REQ messages received")
     public void handleParticipantStatusReq(final ParticipantStatusReq participantStatusReqMsg) {
-        var participantStatus = makeHeartbeat(true);
-        publisher.sendParticipantStatus(participantStatus);
+        publisher.sendParticipantStatus(makeHeartbeat());
     }
 
     /**
@@ -147,7 +145,7 @@
     public void handleParticipantRegisterAck(ParticipantRegisterAck participantRegisterAckMsg) {
         LOGGER.debug("ParticipantRegisterAck message received as responseTo {}",
                 participantRegisterAckMsg.getResponseTo());
-        publisher.sendParticipantStatus(makeHeartbeat(false));
+        publisher.sendParticipantStatus(makeHeartbeat());
     }
 
     /**
@@ -224,33 +222,19 @@
      */
     public void sendHeartbeat() {
         if (publisher.isActive()) {
-            publisher.sendHeartbeat(makeHeartbeat(false));
+            publisher.sendHeartbeat(makeHeartbeat());
         }
     }
 
     /**
      * Method to send heartbeat to automation composition runtime.
      */
-    public ParticipantStatus makeHeartbeat(boolean responseToParticipantStatusReq) {
+    private ParticipantStatus makeHeartbeat() {
         var heartbeat = new ParticipantStatus();
         heartbeat.setParticipantId(cacheProvider.getParticipantId());
         heartbeat.setState(ParticipantState.ON_LINE);
-        heartbeat.setAutomationCompositionInfoList(getAutomationCompositionInfoList());
         heartbeat.setParticipantSupportedElementType(cacheProvider.getSupportedAcElementTypes());
 
-        if (responseToParticipantStatusReq) {
-            var acElementDefsMap = cacheProvider.getAcElementsDefinitions();
-            List<ParticipantDefinition> participantDefinitionList = new ArrayList<>(acElementDefsMap.size());
-            for (var acElementDefs : acElementDefsMap.values()) {
-                var participantDefinition = new ParticipantDefinition();
-                participantDefinition.setParticipantId(cacheProvider.getParticipantId());
-                participantDefinition
-                        .setAutomationCompositionElementDefinitionList(new ArrayList<>(acElementDefs.values()));
-                participantDefinitionList.add(participantDefinition);
-            }
-            heartbeat.setParticipantDefinitionUpdates(participantDefinitionList);
-        }
-
         return heartbeat;
     }
 
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
old mode 100644
new mode 100755
index acf86f2..22929a2
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
@@ -34,59 +34,118 @@
 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.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
-import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
 class ParticipantIntermediaryApiImplTest {
 
     private static final String USE_STATE = "useState";
     private static final String OPERATIONAL_STATE = "operationState";
     private static final Map<String, Object> MAP = Map.of("key", 1);
+    private static final UUID AUTOMATION_COMPOSITION_ID = UUID.randomUUID();
+    private static final UUID ELEMENT_ID = UUID.randomUUID();
+    private static final UUID COMPOSITION_ID = UUID.randomUUID();
+    private static final ToscaConceptIdentifier DEFINITION_ELEMENT_ID = new ToscaConceptIdentifier("code", "0.0.1");
 
     @Test
-    void mockParticipantIntermediaryApiImplTest() throws CoderException {
+    void testUpdateAutomationCompositionElementState() {
         var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
-        var cacheProvider = mock(CacheProvider.class);
-        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, cacheProvider);
-
-        var uuid = UUID.randomUUID();
-        var automationCompositionId = UUID.randomUUID();
-        apiImpl.updateAutomationCompositionElementState(automationCompositionId, uuid, DeployState.UNDEPLOYED,
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, mock(CacheProvider.class));
+        apiImpl.updateAutomationCompositionElementState(AUTOMATION_COMPOSITION_ID, ELEMENT_ID, DeployState.UNDEPLOYED,
                 LockState.NONE, StateChangeResult.NO_ERROR, null);
-        verify(automationComposiitonHandler).updateAutomationCompositionElementState(automationCompositionId, uuid,
-                DeployState.UNDEPLOYED, LockState.NONE, StateChangeResult.NO_ERROR, null);
+        verify(automationComposiitonHandler).updateAutomationCompositionElementState(AUTOMATION_COMPOSITION_ID,
+                ELEMENT_ID, DeployState.UNDEPLOYED, LockState.NONE, StateChangeResult.NO_ERROR, null);
+    }
 
-        apiImpl.sendAcElementInfo(automationCompositionId, uuid, USE_STATE, OPERATIONAL_STATE, MAP);
-        verify(automationComposiitonHandler).sendAcElementInfo(automationCompositionId, uuid, USE_STATE,
-                OPERATIONAL_STATE, MAP);
-
-        apiImpl.updateAutomationCompositionElementState(automationCompositionId, uuid, DeployState.DEPLOYED, null,
+    @Test
+    void testUpdateCompositionState() {
+        var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, mock(CacheProvider.class));
+        apiImpl.updateCompositionState(COMPOSITION_ID, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "");
+        verify(automationComposiitonHandler).updateCompositionState(COMPOSITION_ID, AcTypeState.PRIMED,
                 StateChangeResult.NO_ERROR, "");
-        verify(automationComposiitonHandler).updateAutomationCompositionElementState(automationCompositionId, uuid,
-                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "");
+    }
 
-        var map = Map.of(automationCompositionId, new AutomationComposition());
+    @Test
+    void testSendAcElementInfo() {
+        var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, mock(CacheProvider.class));
+        apiImpl.sendAcElementInfo(AUTOMATION_COMPOSITION_ID, ELEMENT_ID, USE_STATE, OPERATIONAL_STATE, MAP);
+        verify(automationComposiitonHandler).sendAcElementInfo(AUTOMATION_COMPOSITION_ID, ELEMENT_ID, USE_STATE,
+                OPERATIONAL_STATE, MAP);
+    }
+
+    @Test
+    void testSendAcDefinitionInfo() {
+        var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, mock(CacheProvider.class));
+        apiImpl.sendAcDefinitionInfo(COMPOSITION_ID, DEFINITION_ELEMENT_ID, MAP);
+        verify(automationComposiitonHandler).sendAcDefinitionInfo(COMPOSITION_ID, DEFINITION_ELEMENT_ID, MAP);;
+    }
+
+    @Test
+    void testGetAutomationCompositionElement() {
+        var automationComposition = new AutomationComposition();
+        automationComposition.setInstanceId(AUTOMATION_COMPOSITION_ID);
+        var map = Map.of(AUTOMATION_COMPOSITION_ID, automationComposition);
+        var cacheProvider = mock(CacheProvider.class);
         when(cacheProvider.getAutomationCompositions()).thenReturn(map);
         var acElement = new AutomationCompositionElement();
-        acElement.setId(uuid);
-        map.get(automationCompositionId).setElements(Map.of(uuid, acElement));
+        acElement.setId(ELEMENT_ID);
+        automationComposition.setElements(Map.of(ELEMENT_ID, acElement));
 
-        var result = apiImpl.getAutomationCompositions();
-        assertEquals(map, result);
+        var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, cacheProvider);
+        var mapResult = apiImpl.getAutomationCompositions();
+        assertEquals(map, mapResult);
+
+        var result = apiImpl.getAutomationComposition(UUID.randomUUID());
+        assertThat(result).isNull();
+
+        result = apiImpl.getAutomationComposition(AUTOMATION_COMPOSITION_ID);
+        assertEquals(automationComposition, result);
 
         var element = apiImpl.getAutomationCompositionElement(UUID.randomUUID(), UUID.randomUUID());
         assertThat(element).isNull();
 
-        element = apiImpl.getAutomationCompositionElement(automationCompositionId, UUID.randomUUID());
+        element = apiImpl.getAutomationCompositionElement(AUTOMATION_COMPOSITION_ID, UUID.randomUUID());
         assertThat(element).isNull();
 
-        element = apiImpl.getAutomationCompositionElement(automationCompositionId, uuid);
+        element = apiImpl.getAutomationCompositionElement(AUTOMATION_COMPOSITION_ID, ELEMENT_ID);
         assertEquals(acElement, element);
+    }
 
-        apiImpl.updateCompositionState(uuid, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "");
-        verify(automationComposiitonHandler).updateCompositionState(uuid, AcTypeState.PRIMED,
-                StateChangeResult.NO_ERROR, "");
+    @Test
+    void testGetAcElementsDefinitions() {
+        var cacheProvider = mock(CacheProvider.class);
+        var acElementDefinition = new AutomationCompositionElementDefinition();
+        acElementDefinition.setAcElementDefinitionId(DEFINITION_ELEMENT_ID);
+        acElementDefinition.setAutomationCompositionElementToscaNodeTemplate(new ToscaNodeTemplate());
+        var elementsDefinitions = Map.of(DEFINITION_ELEMENT_ID, acElementDefinition);
+        var map = Map.of(COMPOSITION_ID, elementsDefinitions);
+        when(cacheProvider.getAcElementsDefinitions()).thenReturn(map);
+        var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, cacheProvider);
+        var mapResult = apiImpl.getAcElementsDefinitions();
+        assertEquals(map, mapResult);
+
+        var result = apiImpl.getAcElementsDefinitions(UUID.randomUUID());
+        assertThat(result).isNull();
+
+        result = apiImpl.getAcElementsDefinitions(COMPOSITION_ID);
+        assertEquals(elementsDefinitions, result);
+
+        var element = apiImpl.getAcElementDefinition(UUID.randomUUID(), new ToscaConceptIdentifier("wrong", "0.0.1"));
+        assertThat(element).isNull();
+
+        element = apiImpl.getAcElementDefinition(COMPOSITION_ID, new ToscaConceptIdentifier("wrong", "0.0.1"));
+        assertThat(element).isNull();
+
+        element = apiImpl.getAcElementDefinition(COMPOSITION_ID, DEFINITION_ELEMENT_ID);
+        assertEquals(acElementDefinition, element);
     }
 }
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
index 36c0c4b..e1b0b08 100755
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java
@@ -34,12 +34,14 @@
 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
 import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData;
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeployAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 class AutomationCompositionOutHandlerTest {
 
@@ -175,4 +177,29 @@
                 "Primed");
         verify(publisher).sendParticipantPrimeAck(any(ParticipantPrimeAck.class));
     }
+
+    @Test
+    void sendAcDefinitionInfoTest() {
+        var cacheProvider = mock(CacheProvider.class);
+        when(cacheProvider.getParticipantId()).thenReturn(UUID.randomUUID());
+        var compositionId = UUID.randomUUID();
+        var elementId = new ToscaConceptIdentifier("code", "1.0.0");
+        var mapAcElementsDefinitions =
+                Map.of(compositionId, Map.of(elementId, new AutomationCompositionElementDefinition()));
+        when(cacheProvider.getAcElementsDefinitions()).thenReturn(mapAcElementsDefinitions);
+        var publisher = mock(ParticipantMessagePublisher.class);
+        var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider);
+
+        acOutHandler.sendAcDefinitionInfo(null, null, Map.of());
+        verify(publisher, times(0)).sendHeartbeat(any(ParticipantStatus.class));
+
+        acOutHandler.sendAcDefinitionInfo(UUID.randomUUID(), null, Map.of());
+        verify(publisher, times(0)).sendHeartbeat(any(ParticipantStatus.class));
+
+        acOutHandler.sendAcDefinitionInfo(compositionId, new ToscaConceptIdentifier("wrong", "1.0.0"), Map.of());
+        verify(publisher, times(0)).sendHeartbeat(any(ParticipantStatus.class));
+
+        acOutHandler.sendAcDefinitionInfo(compositionId, elementId, Map.of());
+        verify(publisher).sendHeartbeat(any(ParticipantStatus.class));
+    }
 }