Add ACM interceptor for DME
[nonrtric/plt/rappmanager.git] / rapp-manager-acm / src / main / java / com / oransc / rappmanager / acm / service / AcmDeployer.java
index 287761a..dea83a4 100755 (executable)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START======================================================================
  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * Copyright (C) 2023 OpenInfra Foundation Europe. All rights reserved.
  * ===============================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 package com.oransc.rappmanager.acm.service;
 
+import com.google.gson.Gson;
 import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
 import com.oransc.rappmanager.acm.rest.AutomationCompositionDefinitionApiClient;
 import com.oransc.rappmanager.acm.rest.AutomationCompositionInstanceApiClient;
+import com.oransc.rappmanager.dme.service.DmeAcmInterceptor;
 import com.oransc.rappmanager.models.RappDeployer;
 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
 import com.oransc.rappmanager.models.rapp.Rapp;
 import com.oransc.rappmanager.models.rapp.RappEvent;
-import com.oransc.rappmanager.models.rapp.RappState;
 import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
 import com.oransc.rappmanager.models.rappinstance.RappInstance;
 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import lombok.RequiredArgsConstructor;
+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.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
@@ -41,6 +44,7 @@ import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -57,6 +61,8 @@ public class AcmDeployer implements RappDeployer {
     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
     private final RappInstanceStateMachine rappInstanceStateMachine;
     private final ACMConfiguration acmConfiguration;
+    private final Gson gson;
+    private final DmeAcmInterceptor dmeAcmInterceptor;
 
     void updateACMInstanceState(UUID compositionId, RappACMInstance rappACMInstance, DeployOrder deployOrder) {
         AcInstanceStateUpdate acInstanceStateUpdate = new AcInstanceStateUpdate();
@@ -75,9 +81,10 @@ public class AcmDeployer implements RappDeployer {
     public CommissioningResponse createComposition(String compositionPayload) {
         CommissioningResponse commissioningResponse = null;
         try {
-            commissioningResponse =
-                    automationCompositionDefinitionApiClient.createCompositionDefinitions(compositionPayload,
-                            UUID.randomUUID());
+            ToscaServiceTemplate toscaServiceTemplate = gson.fromJson(compositionPayload, ToscaServiceTemplate.class);
+            dmeAcmInterceptor.injectToscaServiceTemplate(toscaServiceTemplate);
+            commissioningResponse = automationCompositionDefinitionApiClient.createCompositionDefinitions(
+                    gson.toJson(toscaServiceTemplate), UUID.randomUUID());
         } catch (Exception e) {
             logger.warn("Error in creating composition", e);
         }
@@ -118,6 +125,7 @@ public class AcmDeployer implements RappDeployer {
             }
         } catch (Exception e) {
             logger.warn("Unable to get composition instance state for composition {}", compositionId, e);
+            Thread.currentThread().interrupt();
         }
         return targetInstanceStateTransition;
     }
@@ -128,9 +136,13 @@ public class AcmDeployer implements RappDeployer {
             String instantiationPayload =
                     rappCsarConfigurationHandler.getInstantiationPayload(rapp, rappInstance.getAcm(),
                             rapp.getCompositionId());
+            AutomationComposition automationComposition =
+                    gson.fromJson(instantiationPayload, AutomationComposition.class);
+            dmeAcmInterceptor.injectAutomationComposition(automationComposition, rapp, rappInstance);
+
             InstantiationResponse instantiationResponse =
                     automationCompositionInstanceApiClient.createCompositionInstance(rapp.getCompositionId(),
-                            instantiationPayload, UUID.randomUUID());
+                            gson.toJson(automationComposition), UUID.randomUUID());
             if (instantiationResponse.getInstanceId() != null) {
                 rappInstance.getAcm().setAcmInstanceId(instantiationResponse.getInstanceId());
                 updateACMInstanceState(rapp.getCompositionId(), rappInstance.getAcm(), DeployOrder.DEPLOY);
@@ -139,6 +151,8 @@ public class AcmDeployer implements RappDeployer {
         } catch (Exception e) {
             logger.warn("Error in deploying Rapp", e);
         }
+        rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMDEPLOYFAILED);
+        rappInstance.setReason("Unable to deploy ACM");
         return false;
     }
 
@@ -158,6 +172,8 @@ public class AcmDeployer implements RappDeployer {
                 return true;
             }
         }
+        rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMUNDEPLOYFAILED);
+        rappInstance.setReason("Unable to undeploy ACM");
         return false;
     }
 
@@ -171,14 +187,14 @@ public class AcmDeployer implements RappDeployer {
                 rapp.setCompositionId(commissioningResponse.getCompositionId());
                 logger.info("Priming automation Composition");
                 primeACMComposition(commissioningResponse.getCompositionId(), PrimeOrder.PRIME);
-                rapp.setState(RappState.PRIMED);
                 return true;
             } else {
-                logger.error("Failed to create automation composition");
+                logger.warn("Failed to create automation composition");
             }
         } catch (Exception e) {
-            logger.error("Failed to create automation composition", e);
+            logger.warn("Error in creating automation composition", e);
         }
+        rapp.setReason("Unable to create automation composition");
         return false;
     }
 
@@ -186,17 +202,45 @@ public class AcmDeployer implements RappDeployer {
     public boolean deprimeRapp(Rapp rapp) {
         try {
             primeACMComposition(rapp.getCompositionId(), PrimeOrder.DEPRIME);
-            CommissioningResponse commissioningResponse = deleteComposition(rapp.getCompositionId());
-            if (commissioningResponse != null) {
-                rapp.setState(RappState.COMMISSIONED);
-                return true;
+            if (waitForCompositionTargetState(rapp.getCompositionId(), AcTypeState.COMMISSIONED)) {
+                CommissioningResponse commissioningResponse = deleteComposition(rapp.getCompositionId());
+                if (commissioningResponse != null) {
+                    rapp.setCompositionId(null);
+                    return true;
+                }
             }
         } catch (Exception e) {
-            logger.error("Failed deprime automation composition", e);
+            logger.warn("Failed deprime automation composition", e);
         }
+        rapp.setReason("Unable to delete automation composition");
         return false;
     }
 
+    boolean waitForCompositionTargetState(UUID compositionId, AcTypeState acTypeState) {
+        boolean targetCompositionStateTransition = false;
+        try {
+            for (int i = 0; i < acmConfiguration.getMaxRetries(); i++) {
+                logger.debug("Composition state check {}", i + 1);
+                if (isCompositionStateEquals(compositionId, acTypeState)) {
+                    logger.debug("Composition {} state is {}", compositionId, acTypeState);
+                    targetCompositionStateTransition = true;
+                    break;
+                } else {
+                    TimeUnit.SECONDS.sleep(acmConfiguration.getRetryInterval());
+                }
+            }
+        } catch (Exception e) {
+            logger.warn("Unable to get composition state for composition {}", compositionId, e);
+            Thread.currentThread().interrupt();
+        }
+        return targetCompositionStateTransition;
+    }
+
+    boolean isCompositionStateEquals(UUID compositionId, AcTypeState acTypeState) {
+        return automationCompositionDefinitionApiClient.getCompositionDefinition(compositionId, UUID.randomUUID())
+                       .getState().equals(acTypeState);
+    }
+
     public void syncRappInstanceStatus(UUID compositionId, RappInstance rappInstance) {
         if (rappInstance.getAcm().getAcmInstanceId() != null) {
             try {
@@ -213,8 +257,10 @@ public class AcmDeployer implements RappDeployer {
     void sendRappInstanceStateEvent(RappInstance rappInstance, DeployState deployState) {
         if (deployState.equals(DeployState.DEPLOYED)) {
             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMDEPLOYED);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYED);
         } else if (deployState.equals(DeployState.UNDEPLOYED)) {
             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMUNDEPLOYED);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED);
         } else if (deployState.equals(DeployState.DEPLOYING)) {
             rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING);
         } else if (deployState.equals(DeployState.UNDEPLOYING)) {