Add validation in AC instance elements Id in update

Issue-ID: POLICY-4905
Change-Id: If49a7829fa8acfe375cf7bb1d7ed6859f8a3f190
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
index 9f12640..84920dd 100755
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2021-2023 Nordix Foundation.
+ * Copyright (C) 2021-2024 Nordix Foundation.
  * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -134,7 +134,7 @@
         } else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState())
                 || DeployState.UPDATING.equals(acToUpdate.getDeployState()))
                 && LockState.LOCKED.equals(acToUpdate.getLockState())) {
-            return updateDeployedAutomationComposition(compositionId, automationComposition, acToUpdate);
+            return updateDeployedAutomationComposition(automationComposition, acToUpdate);
         }
         throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
                 "Not allowed to update in the state " + acToUpdate.getDeployState());
@@ -143,12 +143,11 @@
     /**
      * Update deployed AC Element properties.
      *
-     * @param compositionId The UUID of the automation composition definition
      * @param automationComposition the automation composition
      * @param acToBeUpdated the composition to be updated
      * @return the result of the update
      */
-    public InstantiationResponse updateDeployedAutomationComposition(UUID compositionId,
+    public InstantiationResponse updateDeployedAutomationComposition(
             AutomationComposition automationComposition, AutomationComposition acToBeUpdated) {
 
         if (automationComposition.getCompositionTargetId() != null
@@ -158,12 +157,13 @@
         }
 
         // Iterate and update the element property values
-        for (var dbAcElement : acToBeUpdated.getElements().entrySet()) {
-            var elementId = dbAcElement.getKey();
-            if (automationComposition.getElements().containsKey(elementId)) {
-                dbAcElement.getValue().getProperties()
-                        .putAll(automationComposition.getElements().get(elementId).getProperties());
+        for (var element : automationComposition.getElements().entrySet()) {
+            var elementId = element.getKey();
+            var dbAcElement = acToBeUpdated.getElements().get(elementId);
+            if (dbAcElement == null) {
+                throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId);
             }
+            dbAcElement.getProperties().putAll(element.getValue().getProperties());
         }
         if (automationComposition.getRestarting() != null) {
             throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed");
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
index 8dca669..87bfe1b 100755
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021-2023 Nordix Foundation.
+ *  Copyright (C) 2021-2024 Nordix Foundation.
  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.when;
 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
@@ -39,7 +40,6 @@
 import org.onap.policy.clamp.acm.runtime.participants.AcmParticipantProvider;
 import org.onap.policy.clamp.acm.runtime.supervision.SupervisionAcHandler;
 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;
@@ -149,7 +149,7 @@
     }
 
     @Test
-    void testInstantiationUpdate() throws AutomationCompositionException {
+    void testInstantiationUpdate() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
         var compositionId = acDefinition.getCompositionId();
@@ -158,13 +158,13 @@
         var automationCompositionUpdate =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
         automationCompositionUpdate.setCompositionId(compositionId);
+        automationCompositionUpdate.setInstanceId(UUID.randomUUID());
         automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
         automationCompositionUpdate.setLockState(LockState.LOCKED);
         var acProvider = mock(AutomationCompositionProvider.class);
-        when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId()))
-                .thenReturn(automationCompositionUpdate);
-        when(acProvider.updateAutomationComposition(automationCompositionUpdate))
-                .thenReturn(automationCompositionUpdate);
+        var acmFromDb = new AutomationComposition(automationCompositionUpdate);
+        when(acProvider.getAutomationComposition(automationCompositionUpdate.getInstanceId())).thenReturn(acmFromDb);
+        when(acProvider.updateAutomationComposition(acmFromDb)).thenReturn(acmFromDb);
 
         var supervisionAcHandler = mock(SupervisionAcHandler.class);
         var acmParticipantProvider = mock(AcmParticipantProvider.class);
@@ -175,12 +175,22 @@
                 automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
 
         verify(supervisionAcHandler).update(any());
-        verify(acProvider).updateAutomationComposition(automationCompositionUpdate);
+        verify(acProvider).updateAutomationComposition(acmFromDb);
         InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionUpdate);
+
+        var elements = new ArrayList<>(automationCompositionUpdate.getElements().values());
+        automationCompositionUpdate.getElements().clear();
+        for (var element : elements) {
+            element.setId(UUID.randomUUID());
+            automationCompositionUpdate.getElements().put(element.getId(), element);
+        }
+        assertThatThrownBy(
+            () -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
+            .hasMessageStartingWith("Element id not present ");
     }
 
     @Test
-    void testUpdateBadRequest() throws AutomationCompositionException {
+    void testUpdateBadRequest() {
         var automationCompositionUpdate =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
         automationCompositionUpdate.setDeployState(DeployState.DEPLOYING);
@@ -210,7 +220,7 @@
     }
 
     @Test
-    void testUpdateRestartedBadRequest() throws AutomationCompositionException {
+    void testUpdateRestartedBadRequest() {
         var automationCompositionUpdate =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
         automationCompositionUpdate.setDeployState(DeployState.DEPLOYED);
@@ -239,7 +249,7 @@
     }
 
     @Test
-    void testUpdateCompositionRestartedBadRequest() throws AutomationCompositionException {
+    void testUpdateCompositionRestartedBadRequest() {
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
         acDefinition.setRestarting(true);