Add Rapp Instances 25/11525/2
authoraravind.est <aravindhan.a@est.tech>
Wed, 26 Jul 2023 11:24:30 +0000 (12:24 +0100)
committeraravind.est <aravindhan.a@est.tech>
Wed, 26 Jul 2023 11:57:40 +0000 (12:57 +0100)
Add rapp instances.
Move deployment lifecycle to rapp instance.

Issue-ID: NONRTRIC-897
Signed-off-by: aravind.est <aravindhan.a@est.tech>
Change-Id: I36cb3c204b5a2aa4fdfd2d3361c4abc7cf38f236

68 files changed:
rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/configuration/ACMConfiguration.java
rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AcmDeployer.java
rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AutomationCompositionLifeCycleManager.java [deleted file]
rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java [new file with mode: 0755]
rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java [new file with mode: 0755]
rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java [new file with mode: 0755]
rapp-manager-acm/src/test/resources/application.yaml [new file with mode: 0755]
rapp-manager-acm/src/test/resources/valid-rapp-package.csar [new file with mode: 0755]
rapp-manager-application/src/main/java/com/oransc/rappmanager/RappManagerApplication.java
rapp-manager-application/src/main/java/com/oransc/rappmanager/rest/RappController.java [moved from rapp-manager-application/src/main/java/com/oransc/rappmanager/rest/OnboardingController.java with 55% similarity]
rapp-manager-application/src/main/java/com/oransc/rappmanager/rest/RappInstanceController.java [new file with mode: 0755]
rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java [new file with mode: 0755]
rapp-manager-application/src/main/resources/application.yaml
rapp-manager-application/src/main/resources/resource-csar/Files/Acm/definition/compositions.json [moved from rapp-manager-application/src/main/resources/compositiondefinition.json with 100% similarity]
rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/a1pms-instance.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/k8s-instance.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/kserve-instance.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instantiation.json [deleted file]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/invokers/invoker-app1.json [moved from rapp-manager-application/src/main/resources/resource-csar/Files/Sme/invoker.json with 65% similarity]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/invokers/invoker-app2.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/aef-provider-function.json [moved from rapp-manager-application/src/main/resources/resource-csar/Files/Sme/provider-domain.json with 100% similarity]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/amf-provider-function.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/apf-provider-function.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/gateway-provider-function.json [new file with mode: 0755]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/serviceapis/api-set-1.json [moved from rapp-manager-application/src/main/resources/resource-csar/Files/Sme/provider-api.json with 96% similarity]
rapp-manager-application/src/main/resources/resource-csar/Files/Sme/serviceapis/api-set-2.json [new file with mode: 0755]
rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/OnboardingControllerTest.java [deleted file]
rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappControllerTest.java [new file with mode: 0755]
rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappInstanceControllerTest.java [new file with mode: 0755]
rapp-manager-application/src/test/java/com/oransc/rappmanager/service/AcmDeployerTest.java [deleted file]
rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappCsarConfigurationHandlerTest.java [deleted file]
rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java [new file with mode: 0755]
rapp-manager-application/src/test/java/com/oransc/rappmanager/statemachine/RappStateMachineTest.java [deleted file]
rapp-manager-application/src/test/resources/valid-rapp-package.csar
rapp-manager-models/pom.xml
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappCsarConfigurationHandler.java [deleted file]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappDeployer.java
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappEvent.java [deleted file]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/cache/RappCacheService.java
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandler.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/PrimeOrder.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/Rapp.java [moved from rapp-manager-models/src/main/java/com/oransc/rappmanager/models/Rapp.java with 76% similarity]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappEvent.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappPrimeOrder.java [moved from rapp-manager-application/src/main/java/com/oransc/rappmanager/exception/ACMInvalidStateTransitionException.java with 75% similarity]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappResources.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappState.java [moved from rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappState.java with 89% similarity]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/DeployOrder.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappACMInstance.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstance.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceDeployOrder.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceState.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappSMEInstance.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachine.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfig.java [new file with mode: 0755]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachine.java [deleted file]
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachineConfig.java [deleted file]
rapp-manager-models/src/test/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandlerTest.java [new file with mode: 0755]
rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfigTest.java [new file with mode: 0755]
rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineTest.java [new file with mode: 0755]
rapp-manager-models/src/test/resources/invalid-rapp-package.csar [new file with mode: 0755]
rapp-manager-models/src/test/resources/valid-rapp-package.csar [new file with mode: 0755]
rapp-manager-sme/pom.xml
rapp-manager-sme/src/main/java/com/oransc/rappmanager/sme/service/SmeDeployer.java
rapp-manager-sme/src/main/java/com/oransc/rappmanager/sme/service/SmeLifecycleManager.java
rapp-manager-sme/src/test/java/com/oransc/rappmanager/sme/service/BeanTestConfiguration.java [new file with mode: 0755]
rapp-manager-sme/src/test/java/com/oransc/rappmanager/sme/service/SmeDeployerTest.java [moved from rapp-manager-application/src/test/java/com/oransc/rappmanager/sme/service/SmeDeployerTest.java with 78% similarity]
rapp-manager-sme/src/test/resources/application.yaml [new file with mode: 0755]
rapp-manager-sme/src/test/resources/valid-rapp-package.csar [new file with mode: 0755]

index 6582775..956f928 100755 (executable)
@@ -30,7 +30,6 @@ public class ACMConfiguration {
     String baseUrl;
     String username;
     String password;
-    String compositionDefinitionLocation;
     int maxRetries;
     int retryInterval;
 }
index def268b..287761a 100755 (executable)
@@ -21,24 +21,20 @@ package com.oransc.rappmanager.acm.service;
 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.acm.rest.ParticipantMonitoringApiClient;
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
 import com.oransc.rappmanager.models.RappDeployer;
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
-import com.oransc.rappmanager.models.cache.RappCacheService;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
-import java.util.List;
+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.Getter;
 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;
-import org.onap.policy.clamp.models.acm.concepts.ParticipantInformation;
 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;
@@ -56,26 +52,17 @@ public class AcmDeployer implements RappDeployer {
 
     Logger logger = LoggerFactory.getLogger(AcmDeployer.class);
 
-    private final ParticipantMonitoringApiClient participantMonitoringApiClient;
     private final AutomationCompositionDefinitionApiClient automationCompositionDefinitionApiClient;
     private final AutomationCompositionInstanceApiClient automationCompositionInstanceApiClient;
     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
-    private final RappCacheService rappCacheService;
-    private final RappStateMachine rappStateMachine;
+    private final RappInstanceStateMachine rappInstanceStateMachine;
     private final ACMConfiguration acmConfiguration;
-    @Getter
-    private UUID compositionId;
 
-    public List<ParticipantInformation> getAllParticipants() {
-        return participantMonitoringApiClient.queryParticipants(null, null, UUID.randomUUID());
-    }
-
-
-    void updateACMInstanceState(Rapp rapp, DeployOrder deployOrder) {
+    void updateACMInstanceState(UUID compositionId, RappACMInstance rappACMInstance, DeployOrder deployOrder) {
         AcInstanceStateUpdate acInstanceStateUpdate = new AcInstanceStateUpdate();
         acInstanceStateUpdate.setDeployOrder(deployOrder);
-        automationCompositionInstanceApiClient.compositionInstanceState(rapp.getCompositionId(),
-                rapp.getCompositionInstanceId(), acInstanceStateUpdate, UUID.randomUUID());
+        automationCompositionInstanceApiClient.compositionInstanceState(compositionId,
+                rappACMInstance.getAcmInstanceId(), acInstanceStateUpdate, UUID.randomUUID());
     }
 
     public void primeACMComposition(UUID compositionId, PrimeOrder primeOrder) {
@@ -91,7 +78,6 @@ public class AcmDeployer implements RappDeployer {
             commissioningResponse =
                     automationCompositionDefinitionApiClient.createCompositionDefinitions(compositionPayload,
                             UUID.randomUUID());
-            compositionId = commissioningResponse.getCompositionId();
         } catch (Exception e) {
             logger.warn("Error in creating composition", e);
         }
@@ -99,13 +85,13 @@ public class AcmDeployer implements RappDeployer {
     }
 
     public CommissioningResponse deleteComposition(UUID compositionId) {
-        return automationCompositionDefinitionApiClient.deleteCompositionDefinition(compositionId, UUID.randomUUID());
-    }
-
-    public boolean isCompositionStateEquals(UUID compositionId, AcTypeState acTypeState) {
-        //automationCompositionDefinitionApiClient.getCompositionDefinition(compositionId, UUID.randomUUID()).getState().equals(acTypeState);
-        //TODO httpmessage converter doesn't map AutomationCompositionDefinition properly, Fix that and check the response
-        return true;
+        try {
+            return automationCompositionDefinitionApiClient.deleteCompositionDefinition(compositionId,
+                    UUID.randomUUID());
+        } catch (Exception e) {
+            logger.warn("Error in deleting composition {}", compositionId, e);
+        }
+        return null;
     }
 
     boolean isCompositionInstanceStateEquals(UUID compositionId, UUID compositionIntanceId, DeployState deployState) {
@@ -113,15 +99,17 @@ public class AcmDeployer implements RappDeployer {
                 UUID.randomUUID()).getDeployState().equals(deployState);
     }
 
-    boolean waitForCompositionInstanceTargetState(Rapp rapp, DeployState deployState) {
+    boolean waitForCompositionInstanceTargetState(UUID compositionId, RappInstance rappInstance,
+            DeployState deployState) {
         boolean targetInstanceStateTransition = false;
         try {
             for (int i = 0; i < acmConfiguration.getMaxRetries(); i++) {
                 logger.debug("Composition instance state check {}", i + 1);
-                if (isCompositionInstanceStateEquals(rapp.getCompositionId(), rapp.getCompositionInstanceId(),
+                if (isCompositionInstanceStateEquals(compositionId, rappInstance.getAcm().getAcmInstanceId(),
                         deployState)) {
-                    sendRappStateEvent(rapp, deployState);
-                    logger.info("Composition instance {} state is {}", rapp.getCompositionInstanceId(), deployState);
+                    sendRappInstanceStateEvent(rappInstance, deployState);
+                    logger.info("Composition instance {} state is {}", rappInstance.getAcm().getAcmInstanceId(),
+                            deployState);
                     targetInstanceStateTransition = true;
                     break;
                 } else {
@@ -129,23 +117,23 @@ public class AcmDeployer implements RappDeployer {
                 }
             }
         } catch (Exception e) {
-            logger.warn("Unable to get composition instance state for composition {}", rapp.getCompositionId());
+            logger.warn("Unable to get composition instance state for composition {}", compositionId, e);
         }
         return targetInstanceStateTransition;
     }
 
     @Override
-    public boolean deployRapp(Rapp rapp) {
+    public boolean deployRappInstance(Rapp rapp, RappInstance rappInstance) {
         try {
-            rapp.setCompositionId(getCompositionId());
             String instantiationPayload =
-                    rappCsarConfigurationHandler.getInstantiationPayload(rapp, getCompositionId());
+                    rappCsarConfigurationHandler.getInstantiationPayload(rapp, rappInstance.getAcm(),
+                            rapp.getCompositionId());
             InstantiationResponse instantiationResponse =
-                    automationCompositionInstanceApiClient.createCompositionInstance(getCompositionId(),
+                    automationCompositionInstanceApiClient.createCompositionInstance(rapp.getCompositionId(),
                             instantiationPayload, UUID.randomUUID());
             if (instantiationResponse.getInstanceId() != null) {
-                rapp.setCompositionInstanceId(instantiationResponse.getInstanceId());
-                updateACMInstanceState(rapp, DeployOrder.DEPLOY);
+                rappInstance.getAcm().setAcmInstanceId(instantiationResponse.getInstanceId());
+                updateACMInstanceState(rapp.getCompositionId(), rappInstance.getAcm(), DeployOrder.DEPLOY);
                 return true;
             }
         } catch (Exception e) {
@@ -155,47 +143,82 @@ public class AcmDeployer implements RappDeployer {
     }
 
     @Override
-    public boolean undeployRapp(Rapp rapp) {
+    public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
         AutomationComposition automationComposition =
                 automationCompositionInstanceApiClient.getCompositionInstance(rapp.getCompositionId(),
-                        rapp.getCompositionInstanceId(), UUID.randomUUID());
+                        rappInstance.getAcm().getAcmInstanceId(), UUID.randomUUID());
         if (automationComposition.getDeployState().equals(DeployState.DEPLOYED) && automationComposition.getLockState()
                                                                                            .equals(LockState.LOCKED)) {
-            updateACMInstanceState(rapp, DeployOrder.UNDEPLOY);
-            if (waitForCompositionInstanceTargetState(rapp, DeployState.UNDEPLOYED)) {
+            updateACMInstanceState(rapp.getCompositionId(), rappInstance.getAcm(), DeployOrder.UNDEPLOY);
+            if (waitForCompositionInstanceTargetState(rapp.getCompositionId(), rappInstance, DeployState.UNDEPLOYED)) {
                 automationCompositionInstanceApiClient.deleteCompositionInstance(
                         automationComposition.getCompositionId(), automationComposition.getInstanceId(),
                         UUID.randomUUID());
-                rappStateMachine.sendRappEvent(rapp, RappEvent.ACMUNDEPLOYED);
+                rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMUNDEPLOYED);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean primeRapp(Rapp rapp) {
+        logger.info("Priming rapp {}", rapp.getName());
+        try {
+            String compositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
+            CommissioningResponse commissioningResponse = createComposition(compositionPayload);
+            if (commissioningResponse != null && commissioningResponse.getCompositionId() != null) {
+                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");
             }
+        } catch (Exception e) {
+            logger.error("Failed to create automation composition", e);
+        }
+        return false;
+    }
+
+    @Override
+    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;
+            }
+        } catch (Exception e) {
+            logger.error("Failed deprime automation composition", e);
         }
         return false;
     }
 
-    public void syncRappStatus(Rapp rapp) {
-        if (rapp.getCompositionId() != null && rapp.getCompositionInstanceId() != null) {
+    public void syncRappInstanceStatus(UUID compositionId, RappInstance rappInstance) {
+        if (rappInstance.getAcm().getAcmInstanceId() != null) {
             try {
                 AutomationComposition compositionInstance =
-                        automationCompositionInstanceApiClient.getCompositionInstance(rapp.getCompositionId(),
-                                rapp.getCompositionInstanceId(), UUID.randomUUID());
-                logger.info("ACM details are " + compositionInstance.toString());
-                sendRappStateEvent(rapp, compositionInstance.getDeployState());
+                        automationCompositionInstanceApiClient.getCompositionInstance(compositionId,
+                                rappInstance.getAcm().getAcmInstanceId(), UUID.randomUUID());
+                sendRappInstanceStateEvent(rappInstance, compositionInstance.getDeployState());
             } catch (RestClientException exception) {
-                logger.warn("Unable to get the ACM details for rapp {}", rapp.getName());
+                logger.warn("Unable to get the ACM details for rapp instance {}", rappInstance.getRappInstanceId());
             }
         }
     }
 
-    void sendRappStateEvent(Rapp rapp, DeployState deployState) {
+    void sendRappInstanceStateEvent(RappInstance rappInstance, DeployState deployState) {
         if (deployState.equals(DeployState.DEPLOYED)) {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.ACMDEPLOYED);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMDEPLOYED);
         } else if (deployState.equals(DeployState.UNDEPLOYED)) {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.ACMUNDEPLOYED);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMUNDEPLOYED);
         } else if (deployState.equals(DeployState.DEPLOYING)) {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.DEPLOYING);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING);
         } else if (deployState.equals(DeployState.UNDEPLOYING)) {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.UNDEPLOYING);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.UNDEPLOYING);
         }
     }
 }
diff --git a/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AutomationCompositionLifeCycleManager.java b/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AutomationCompositionLifeCycleManager.java
deleted file mode 100755 (executable)
index 8498bdf..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.acm.service;
-
-
-import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.concurrent.TimeUnit;
-import lombok.RequiredArgsConstructor;
-import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
-import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
-import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.SmartLifecycle;
-import org.springframework.stereotype.Service;
-
-@Service
-@RequiredArgsConstructor
-public class AutomationCompositionLifeCycleManager implements SmartLifecycle {
-
-    Logger logger = LoggerFactory.getLogger(AutomationCompositionLifeCycleManager.class);
-    private final ACMConfiguration acmConfiguration;
-    private final AcmDeployer acmDeployer;
-    private boolean running;
-
-    @Override
-    public void start() {
-        logger.info("Initializing automation Composition");
-        try {
-            String compositionPayload = Files.readString(Path.of(acmConfiguration.getCompositionDefinitionLocation()));
-            CommissioningResponse commissioningResponse =
-                    acmDeployer.createComposition(compositionPayload);
-            if (commissioningResponse != null && commissioningResponse.getCompositionId() != null) {
-                logger.info("Priming automation Composition");
-                acmDeployer.primeACMComposition(commissioningResponse.getCompositionId(),
-                        PrimeOrder.PRIME);
-                for (int i = 0; i < acmConfiguration.getMaxRetries(); i++) {
-                    logger.debug("Composition priming check {}", i + 1);
-                    if (acmDeployer.isCompositionStateEquals(commissioningResponse.getCompositionId(),
-                            AcTypeState.PRIMED)) {
-                        logger.info("Composition {} is primed", commissioningResponse.getCompositionId());
-                        running = true;
-                        break;
-                    } else {
-                        TimeUnit.SECONDS.sleep(acmConfiguration.getRetryInterval());
-                    }
-                }
-            } else {
-                logger.error("Failed to create automation composition");
-            }
-        } catch (Exception e) {
-            logger.error("Failed to create automation composition", e);
-        }
-    }
-
-    @Override
-    public void stop() {
-        logger.info("Depriming automation Composition");
-        if (running) {
-            try {
-                acmDeployer.primeACMComposition(acmDeployer.getCompositionId(),
-                        PrimeOrder.DEPRIME);
-                for (int i = 0; i < acmConfiguration.getMaxRetries(); i++) {
-                    logger.debug("Composition depriming check {}", i + 1);
-                    if (acmDeployer.isCompositionStateEquals(
-                            acmDeployer.getCompositionId(), AcTypeState.COMMISSIONED)) {
-                        logger.info("Composition {} is deprimed", acmDeployer.getCompositionId());
-                        logger.info("Deleting automation Composition");
-                        acmDeployer.deleteComposition(acmDeployer.getCompositionId());
-                        running = false;
-                        break;
-                    } else {
-                        TimeUnit.SECONDS.sleep(acmConfiguration.getRetryInterval());
-                    }
-                }
-            } catch (Exception e) {
-                logger.error("Failed to cleanup automation composition");
-            }
-        }
-    }
-
-    @Override
-    public boolean isRunning() {
-        return running;
-    }
-}
diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java
new file mode 100755 (executable)
index 0000000..928f4bc
--- /dev/null
@@ -0,0 +1,394 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.acm.service;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rapp.RappResourceBuilder;
+import com.oransc.rappmanager.models.rapp.RappResources;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.models.cache.RappCacheService;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachineConfig;
+import java.io.IOException;
+import java.util.UUID;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+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;
+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.messages.rest.instantiation.InstantiationResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.client.ExpectedCount;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootTest(classes = {BeanTestConfiguration.class, ACMConfiguration.class, AcmDeployer.class,
+        RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
+        RappInstanceStateMachine.class})
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@AutoConfigureMockMvc
+public class AcmDeployerTest {
+
+    MockRestServiceServer mockServer;
+    @SpyBean
+    AcmDeployer acmDeployer;
+    @Autowired
+    RestTemplate restTemplate;
+    @Autowired
+    ACMConfiguration acmConfiguration;
+    @SpyBean
+    RappInstanceStateMachine rappInstanceStateMachine;
+    @Autowired
+    RappCsarConfigurationHandler rappCsarConfigurationHandler;
+
+    RappResourceBuilder rappResourceBuilder = new RappResourceBuilder();
+    private final String validRappFile = "valid-rapp-package.csar";
+    String validCsarFileLocation = "src/test/resources/";
+    ObjectMapper objectMapper = new ObjectMapper();
+    String URI_ACM_COMPOSITIONS, URI_ACM_COMPOSITION, URI_ACM_INSTANCES, URI_ACM_INSTANCE;
+
+    @BeforeAll
+    void initACMURI() {
+        URI_ACM_COMPOSITIONS = acmConfiguration.getBaseUrl() + "compositions";
+        URI_ACM_COMPOSITION = acmConfiguration.getBaseUrl() + "compositions/%s";
+        URI_ACM_INSTANCES = acmConfiguration.getBaseUrl() + "compositions/%s/instances";
+        URI_ACM_INSTANCE = acmConfiguration.getBaseUrl() + "compositions/%s/instances/%s";
+    }
+
+    @BeforeEach
+    public void init() {
+        mockServer = MockRestServiceServer.createServer(restTemplate);
+    }
+
+    @Test
+    void testCreateComposition() throws IOException {
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .rappResources(rappResources).build();
+
+        String compositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
+
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(UUID.randomUUID());
+        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
+                .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                    .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+        CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
+        mockServer.verify();
+        assertEquals(commissioningResponseActual.getCompositionId(), commissioningResponseExpected.getCompositionId());
+    }
+
+    @Test
+    void testCreateCompositionFailure() {
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .rappResources(rappResources).build();
+        String compositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
+        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
+                .andRespond(withStatus(HttpStatus.BAD_GATEWAY));
+        CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
+        mockServer.verify();
+        assertNull(commissioningResponseActual);
+    }
+
+    @Test
+    void testCompositionPriming() {
+        UUID compositionId = UUID.randomUUID();
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+
+        acmDeployer.primeACMComposition(compositionId, PrimeOrder.PRIME);
+        mockServer.verify();
+    }
+
+    @Test
+    void testDeployRappInstance() throws Exception {
+
+        UUID compositionId = UUID.randomUUID();
+        UUID rappId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        InstantiationResponse instantiationResponse = new InstantiationResponse();
+        instantiationResponse.setInstanceId(instanceId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
+                .andExpect(method(HttpMethod.POST)).andRespond(
+                        withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(instantiationResponse)));
+        mockServer.expect(ExpectedCount.once(),
+                        requestTo(acmConfiguration.getBaseUrl() + "compositions/" + compositionId + "/instances/" + instanceId))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+        boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappResourceBuilder.getRappInstance());
+        assertTrue(rappDeployStateActual);
+        mockServer.verify();
+    }
+
+    @Test
+    void testDeployRappInstanceFailure() throws Exception {
+        UUID compositionId = UUID.randomUUID();
+        UUID rappId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        InstantiationResponse instantiationResponse = new InstantiationResponse();
+        instantiationResponse.setInstanceId(instanceId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
+                .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
+
+        boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappResourceBuilder.getRappInstance());
+        mockServer.verify();
+        assertFalse(rappDeployStateActual);
+    }
+
+    @Test
+    void testUndeployRappInstance() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        UUID rappId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name("").packageName(validRappFile).compositionId(compositionId)
+                            .state(RappState.PRIMED).build();
+
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
+                ExpectedCount.once());
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYED, LockState.UNLOCKED,
+                ExpectedCount.once());
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
+
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.getAcm().setAcmInstanceId(instanceId);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
+        mockServer.verify();
+        assertTrue(rappUndeployStateActual);
+    }
+
+    @Test
+    void testUndeployRappInstanceFailure() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        UUID rappId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+                            .state(RappState.PRIMED).build();
+
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
+                ExpectedCount.once());
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYING, LockState.UNLOCKING,
+                ExpectedCount.manyTimes());
+
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.getAcm().setAcmInstanceId(instanceId);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
+        mockServer.verify();
+        assertFalse(rappUndeployStateActual);
+    }
+
+    @Test
+    void testSyncRappInstanceStatus() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYING, LockState.UNLOCKING,
+                ExpectedCount.once());
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.getAcm().setAcmInstanceId(instanceId);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        acmDeployer.syncRappInstanceStatus(compositionId, rappInstance);
+        mockServer.verify();
+        verify(rappInstanceStateMachine, times(1)).sendRappInstanceEvent(rappInstance, RappEvent.UNDEPLOYING);
+    }
+
+    @Test
+    void testSyncRappStatusFailure() {
+        UUID compositionId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
+
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.getAcm().setAcmInstanceId(instanceId);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        acmDeployer.syncRappInstanceStatus(compositionId, rappInstance);
+        mockServer.verify();
+        verify(rappInstanceStateMachine, never()).sendRappInstanceEvent(any(), any());
+    }
+
+    @Test
+    void testPrimeRapp() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
+                .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                    .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+        boolean primeRapp = acmDeployer.primeRapp(rapp);
+        mockServer.verify();
+        assertTrue(primeRapp);
+        assertEquals(RappState.PRIMED, rapp.getState());
+
+    }
+
+    @Test
+    void testPrimeRappFailure() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
+                .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                    .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
+        boolean primeRapp = acmDeployer.primeRapp(rapp);
+        mockServer.verify();
+        assertFalse(primeRapp);
+        assertEquals(RappState.COMMISSIONED, rapp.getState());
+    }
+
+    @Test
+    void testDeprimeRapp() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+
+        boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
+        mockServer.verify();
+        assertTrue(deprimeRapp);
+    }
+
+    @Test
+    void testDeprimeFailureRapp() {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
+
+        boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
+        mockServer.verify();
+        assertFalse(deprimeRapp);
+    }
+
+    @Test
+    void testDeleteComposition() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+        CommissioningResponse commissioningResponse = acmDeployer.deleteComposition(compositionId);
+        mockServer.verify();
+        assertEquals(commissioningResponse.getCompositionId(), compositionId);
+    }
+
+    @Test
+    void testDeleteCompositionFailure() {
+        UUID compositionId = UUID.randomUUID();
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
+        CommissioningResponse commissioningResponse = acmDeployer.deleteComposition(compositionId);
+        mockServer.verify();
+        assertNull(commissioningResponse);
+    }
+
+    void expectAcmGetInstanceToReturnState(UUID compositionId, UUID instanceId, DeployState deployState,
+            LockState lockState, ExpectedCount expectedCount) throws JsonProcessingException {
+        AutomationComposition automationCompositionDeployed = new AutomationComposition();
+        automationCompositionDeployed.setCompositionId(compositionId);
+        automationCompositionDeployed.setInstanceId(instanceId);
+        automationCompositionDeployed.setDeployState(deployState);
+        automationCompositionDeployed.setLockState(lockState);
+
+        mockServer.expect(expectedCount, requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDeployed)));
+    }
+}
diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java
new file mode 100755 (executable)
index 0000000..f59f8fb
--- /dev/null
@@ -0,0 +1,74 @@
+package com.oransc.rappmanager.acm.service;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.acm.ApiClient;
+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.acm.rest.ParticipantMonitoringApiClient;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+@TestConfiguration
+@RequiredArgsConstructor
+public class BeanTestConfiguration {
+
+    private final ACMConfiguration acmConfiguration;
+
+    @Bean
+    public ObjectMapper objectMapper() {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        return objectMapper;
+    }
+
+    @Bean
+    public RestTemplateBuilder restTemplateBuilder() {
+        return new RestTemplateBuilder();
+    }
+
+    @Bean
+    public CacheManager cacheManager() {
+        return new ConcurrentMapCacheManager(); // or any other CacheManager implementation you want to use in the test
+    }
+
+    @Bean
+    public RestTemplate restTemplate(RestTemplateBuilder builder) {
+        return builder.build();
+    }
+
+    @Bean("acmApiClient")
+    public ApiClient acmApiClient(RestTemplate restTemplate) {
+        ApiClient apiClient = new ApiClient(restTemplate);
+        apiClient.setUsername(acmConfiguration.getUsername());
+        apiClient.setPassword(acmConfiguration.getPassword());
+        return apiClient.setBasePath(acmConfiguration.getBaseUrl());
+    }
+
+    @Bean
+    public ParticipantMonitoringApiClient participantMonitoringApiClient(
+            @Qualifier("acmApiClient") ApiClient apiClient) {
+        return new ParticipantMonitoringApiClient(apiClient);
+    }
+
+    @Bean
+    public AutomationCompositionDefinitionApiClient automationCompositionDefinitionApiClient(
+            @Qualifier("acmApiClient") ApiClient apiClient) {
+        return new AutomationCompositionDefinitionApiClient(apiClient);
+    }
+
+    @Bean
+    public AutomationCompositionInstanceApiClient automationCompositionInstanceApiClient(
+            @Qualifier("acmApiClient") ApiClient apiClient) {
+        return new AutomationCompositionInstanceApiClient(apiClient);
+    }
+
+
+}
diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java
new file mode 100755 (executable)
index 0000000..f939ccc
--- /dev/null
@@ -0,0 +1,24 @@
+package com.oransc.rappmanager.models.rapp;
+
+import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import java.util.List;
+
+public class RappResourceBuilder {
+
+    public RappResources getResources() {
+        RappResources rappResources = new RappResources();
+        RappResources.ACMResources acmResources = new RappResources.ACMResources("compositions", List.of());
+        acmResources.setCompositionInstances(List.of("kserve-instance"));
+        rappResources.setAcm(acmResources);
+        return rappResources;
+    }
+
+    public RappInstance getRappInstance() {
+        RappInstance rappInstance = new RappInstance();
+        RappACMInstance rappACMInstance = new RappACMInstance();
+        rappACMInstance.setInstance("kserve-instance");
+        rappInstance.setAcm(rappACMInstance);
+        return rappInstance;
+    }
+}
diff --git a/rapp-manager-acm/src/test/resources/application.yaml b/rapp-manager-acm/src/test/resources/application.yaml
new file mode 100755 (executable)
index 0000000..2fdadf4
--- /dev/null
@@ -0,0 +1,7 @@
+rappmanager:
+  acm:
+    baseurl: http://10.101.3.22:30442/onap/policy/clamp/acm/v2/
+    username: runtimeUser
+    password: zb!XztG34
+    maxRetries: 3
+    retryInterval: 2 #seconds
\ No newline at end of file
diff --git a/rapp-manager-acm/src/test/resources/valid-rapp-package.csar b/rapp-manager-acm/src/test/resources/valid-rapp-package.csar
new file mode 100755 (executable)
index 0000000..b8b36e3
Binary files /dev/null and b/rapp-manager-acm/src/test/resources/valid-rapp-package.csar differ
index 94f865a..31fbd28 100755 (executable)
@@ -22,12 +22,10 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.retry.annotation.EnableRetry;
 
 @SpringBootApplication
 @EnableConfigurationProperties
 @EnableCaching
-@EnableRetry
 public class RappManagerApplication {
 
     public static void main(String[] args) {
 
 package com.oransc.rappmanager.rest;
 
-import com.oransc.rappmanager.acm.service.AcmDeployer;
 import com.oransc.rappmanager.configuration.RappManagerConfiguration;
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
 import com.oransc.rappmanager.models.cache.RappCacheService;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
-import com.oransc.rappmanager.sme.service.SmeDeployer;
+import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
+import com.oransc.rappmanager.models.rapp.PrimeOrder;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rapp.RappPrimeOrder;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.service.RappService;
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -37,9 +36,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.cache.Cache;
 import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestPart;
 import org.springframework.web.bind.annotation.RestController;
@@ -48,16 +50,13 @@ import org.springframework.web.multipart.MultipartFile;
 @RestController
 @RequestMapping(path = "rapps")
 @RequiredArgsConstructor
-public class OnboardingController {
+public class RappController {
 
-    Logger logger = LoggerFactory.getLogger(OnboardingController.class);
+    Logger logger = LoggerFactory.getLogger(RappController.class);
     private final RappCsarConfigurationHandler rappCsarConfigurationHandler;
-    private final AcmDeployer acmDeployer;
-    private final SmeDeployer smeDeployer;
     private final RappManagerConfiguration rappManagerConfiguration;
-    private final RappStateMachine rappStateMachine;
     private final RappCacheService rappCacheService;
-
+    private final RappService rappService;
 
     @GetMapping
     public ResponseEntity<Cache> getRapps() {
@@ -65,17 +64,12 @@ public class OnboardingController {
     }
 
     @GetMapping("{rapp_id}")
-    public ResponseEntity<Rapp> getRapps(@PathVariable("rapp_id") String rappId) {
-        Optional<Rapp> rappOptional = rappCacheService.getRapp(rappId);
-        if (rappOptional.isPresent()) {
-            acmDeployer.syncRappStatus(rappOptional.get());
-            return ResponseEntity.ok(rappCacheService.getRapp(rappId).get());
-        }
-        return ResponseEntity.badRequest().build();
+    public ResponseEntity<Rapp> getRapp(@PathVariable("rapp_id") String rappId) {
+        return rappCacheService.getRapp(rappId).map(ResponseEntity::ok).orElse(ResponseEntity.badRequest().build());
     }
 
-    @PostMapping("{rapp_id}/onboard")
-    public ResponseEntity<Object> uploadRappCsarFile(@PathVariable("rapp_id") String rappId,
+    @PostMapping("{rapp_id}")
+    public ResponseEntity<Rapp> createRapp(@PathVariable("rapp_id") String rappId,
             @RequestPart("file") MultipartFile csarFilePart) throws IOException {
         if (rappCsarConfigurationHandler.isValidRappPackage(csarFilePart)) {
             File csarFile = new File(
@@ -85,9 +79,9 @@ public class OnboardingController {
             Files.copy(csarFilePart.getInputStream(), csarFile.getAbsoluteFile().toPath(),
                     StandardCopyOption.REPLACE_EXISTING);
             Rapp rapp = Rapp.builder().name(rappId).packageLocation(rappManagerConfiguration.getCsarLocation())
-                                .packageName(csarFile.getName()).state(RappState.ONBOARDED).build();
+                                .packageName(csarFile.getName()).state(RappState.COMMISSIONED).build();
+            rapp.setRappResources(rappCsarConfigurationHandler.getRappResource(rapp));
             rappCacheService.putRapp(rapp);
-            rappStateMachine.onboardRapp(rapp.getRappId());
             return ResponseEntity.accepted().build();
         } else {
             logger.info("Invalid Rapp package for {}", rappId);
@@ -95,37 +89,29 @@ public class OnboardingController {
         }
     }
 
-    @PostMapping("{rapp_id}/deploy")
-    public ResponseEntity<?> deployRapp(@PathVariable("rapp_id") String rappId) {
-        Optional<Rapp> rappOptional = rappCacheService.getRapp(rappId);
-        rappOptional.ifPresent(rapp -> {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.DEPLOYING);
-        });
-        if (rappOptional.isPresent() && acmDeployer.deployRapp(rappOptional.get()) && smeDeployer.deployRapp(
-                rappOptional.get())) {
-            return ResponseEntity.accepted().build();
-        }
-        return ResponseEntity.internalServerError().build();
+    @PutMapping("{rapp_id}")
+    public ResponseEntity<String> primeRapp(@PathVariable("rapp_id") String rappId,
+            @RequestBody RappPrimeOrder rappPrimeOrder) {
+        // @formatter:off
+        return rappCacheService.getRapp(rappId)
+                       .map(rapp -> Optional.ofNullable(rappPrimeOrder.getPrimeOrder())
+                            .filter(primeOrder -> primeOrder.equals(PrimeOrder.PRIME))
+                            .map(primeOrder -> rappService.primeRapp(rapp))
+                            .orElseGet(() -> rappService.deprimeRapp(rapp)))
+                       .orElse(ResponseEntity.notFound().build());
+        // @formatter:on
     }
 
-    @PostMapping("{rapp_id}/undeploy")
-    public ResponseEntity<?> undeployRapp(@PathVariable("rapp_id") String rappId) {
-        Optional<Rapp> rappOptional = rappCacheService.getRapp(rappId);
-        rappOptional.ifPresent(rapp -> {
-            rappStateMachine.sendRappEvent(rapp, RappEvent.UNDEPLOYING);
-        });
-        if (rappOptional.isPresent() && acmDeployer.undeployRapp(rappOptional.get()) && smeDeployer.undeployRapp(
-                rappOptional.get())) {
-            rappCacheService.deleteRapp(rappOptional.get());
-            rappStateMachine.deleteRapp(rappOptional.get());
-            return ResponseEntity.accepted().build();
-        }
-        return ResponseEntity.internalServerError().build();
-    }
-
-    @GetMapping("info")
-    public ResponseEntity<Object> getInfo() {
-        return ResponseEntity.ok(acmDeployer.getAllParticipants());
+    @DeleteMapping("{rapp_id}")
+    public ResponseEntity<Object> deleteRapp(@PathVariable("rapp_id") String rappId) {
+        // @formatter:off
+        return rappCacheService.getRapp(rappId)
+               .filter(rapp -> rapp.getRappInstances().isEmpty() && rapp.getState().equals(RappState.COMMISSIONED))
+               .map(rapp -> {
+                   rappCacheService.deleteRapp(rapp);
+                   return ResponseEntity.ok().build();
+               })
+               .orElse(ResponseEntity.notFound().build());
+        // @formatter:on
     }
-
 }
diff --git a/rapp-manager-application/src/main/java/com/oransc/rappmanager/rest/RappInstanceController.java b/rapp-manager-application/src/main/java/com/oransc/rappmanager/rest/RappInstanceController.java
new file mode 100755 (executable)
index 0000000..20fbdb0
--- /dev/null
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.rest;
+
+import com.oransc.rappmanager.models.rappinstance.DeployOrder;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceDeployOrder;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import com.oransc.rappmanager.models.cache.RappCacheService;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.service.RappService;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(path = "rapps/{rapp_id}/instance")
+@RequiredArgsConstructor
+public class RappInstanceController {
+
+    private final RappCacheService rappCacheService;
+    private final RappInstanceStateMachine rappInstanceStateMachine;
+    private final RappService rappService;
+
+    @GetMapping
+    public ResponseEntity<Map<UUID, RappInstance>> getAllRappInstances(@PathVariable("rapp_id") String rappId) {
+        return rappCacheService.getRapp(rappId).map(Rapp::getRappInstances).map(ResponseEntity::ok)
+                       .orElse(ResponseEntity.notFound().build());
+    }
+
+    @PostMapping
+    public ResponseEntity<RappInstance> createRappInstance(@PathVariable("rapp_id") String rappId,
+            @RequestBody RappInstance rappInstance) {
+        return rappCacheService.getRapp(rappId).map(rapp -> {
+            rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+            rapp.getRappInstances().put(rappInstance.getRappInstanceId(), rappInstance);
+            return ResponseEntity.ok(rappInstance);
+        }).orElse(ResponseEntity.notFound().build());
+    }
+
+    @GetMapping("{rapp_instance_id}")
+    public ResponseEntity<RappInstance> getRappInstance(@PathVariable("rapp_id") String rappId,
+            @PathVariable("rapp_instance_id") UUID rappInstanceId) {
+        return rappCacheService.getRapp(rappId).map(rapp -> Pair.of(rapp, rapp.getRappInstances().get(rappInstanceId)))
+                       .filter(rappPair -> rappPair.getLeft().getRappInstances().containsKey(rappInstanceId))
+                       .map(rappPair -> {
+                           rappService.updateRappInstanceState(rappPair.getLeft(), rappPair.getRight());
+                           RappInstance rappInstance = rappPair.getLeft().getRappInstances().get(rappInstanceId);
+                           rappInstance.setState(rappInstanceStateMachine.getRappInstanceState(rappInstanceId));
+                           return rappInstance;
+                       }).map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());
+    }
+
+    @PutMapping("{rapp_instance_id}")
+    public ResponseEntity<String> deployRappInstance(@PathVariable("rapp_id") String rappId,
+            @PathVariable("rapp_instance_id") UUID rappInstanceId,
+            @RequestBody RappInstanceDeployOrder rappInstanceDeployOrder) {
+        //@formatter:off
+        return rappCacheService.getRapp(rappId)
+                   .filter(rapp -> rapp.getRappInstances().containsKey(rappInstanceId))
+                   .map(rapp -> Pair.of(rapp, rapp.getRappInstances().get(rappInstanceId)))
+                   .map(rappPair -> Optional.ofNullable(rappInstanceDeployOrder.getDeployOrder())
+                        .filter(deployOrder -> deployOrder.equals(DeployOrder.DEPLOY))
+                        .map(primeOrder -> rappService.deployRappInstance(rappPair.getLeft(), rappPair.getRight()))
+                        .orElseGet(() -> rappService.undeployRappInstance(rappPair.getLeft(), rappPair.getRight())))
+                   .orElse(ResponseEntity.notFound().build());
+        //@formatter:on
+    }
+
+    @DeleteMapping("{rapp_instance_id}")
+    public ResponseEntity<Object> deleteRappInstance(@PathVariable("rapp_id") String rappId,
+            @PathVariable("rapp_instance_id") UUID rappInstanceId) {
+        return rappCacheService.getRapp(rappId).map(rapp -> Pair.of(rapp, rapp.getRappInstances()))
+                       .filter(rappPair -> rappPair.getRight().containsKey(rappInstanceId) && rappPair.getRight()
+                                                                                                      .get(rappInstanceId)
+                                                                                                      .getState()
+                                                                                                      .equals(RappInstanceState.UNDEPLOYED))
+                       .map(rappPair -> {
+                           rappInstanceStateMachine.deleteRappInstance(
+                                   rappPair.getLeft().getRappInstances().get(rappInstanceId));
+                           rappPair.getLeft().getRappInstances().remove(rappInstanceId);
+                           return ResponseEntity.noContent().build();
+                       }).orElse(ResponseEntity.notFound().build());
+    }
+
+}
diff --git a/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java b/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java
new file mode 100755 (executable)
index 0000000..82054f5
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.service;
+
+import com.oransc.rappmanager.acm.service.AcmDeployer;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.sme.service.SmeDeployer;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class RappService {
+
+    private final AcmDeployer acmDeployer;
+    private final SmeDeployer smeDeployer;
+    private final RappInstanceStateMachine rappInstanceStateMachine;
+
+    public ResponseEntity<String> primeRapp(Rapp rapp) {
+        if (rapp.getState().equals(RappState.COMMISSIONED)) {
+            rapp.setState(RappState.PRIMING);
+            if (!acmDeployer.primeRapp(rapp)) {
+                rapp.setState(RappState.COMMISSIONED);
+            }
+            return ResponseEntity.ok().build();
+        } else {
+            return ResponseEntity.badRequest()
+                           .body("State transition from " + RappState.PRIMED.name() + " to " + rapp.getState().name()
+                                         + " is not permitted.");
+        }
+    }
+
+    public ResponseEntity<String> deprimeRapp(Rapp rapp) {
+        if (rapp.getState().equals(RappState.PRIMED) && rapp.getRappInstances().isEmpty()) {
+            rapp.setState(RappState.DEPRIMING);
+            if (!acmDeployer.deprimeRapp(rapp)) {
+                rapp.setState(RappState.PRIMED);
+            }
+            return ResponseEntity.ok().build();
+        } else {
+            if (!rapp.getRappInstances().isEmpty()) {
+                return ResponseEntity.badRequest().body("Unable to deprime as there are active rapp instances,");
+            } else {
+                return ResponseEntity.badRequest()
+                               .body("State transition from " + RappState.COMMISSIONED.name() + " to " + rapp.getState()
+                                                                                                                 .name()
+                                             + " is not permitted.");
+            }
+        }
+    }
+
+    public ResponseEntity<String> deployRappInstance(Rapp rapp, RappInstance rappInstance) {
+        if (rappInstance.getState().equals(RappInstanceState.UNDEPLOYED)) {
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING);
+            if (acmDeployer.deployRappInstance(rapp, rappInstance) && smeDeployer.deployRappInstance(rapp,
+                    rappInstance)) {
+                return ResponseEntity.accepted().build();
+            }
+            return ResponseEntity.status(HttpStatus.BAD_GATEWAY).build();
+        } else {
+            return ResponseEntity.badRequest().body("State transition from " + rappInstance.getState().name() + " to "
+                                                            + RappInstanceState.DEPLOYED.name() + " is not permitted.");
+        }
+    }
+
+    public ResponseEntity<String> undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
+        if (rappInstance.getState().equals(RappInstanceState.DEPLOYED)) {
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.UNDEPLOYING);
+            if (acmDeployer.undeployRappInstance(rapp, rappInstance) && smeDeployer.undeployRappInstance(rapp,
+                    rappInstance)) {
+                return ResponseEntity.accepted().build();
+            }
+            return ResponseEntity.status(HttpStatus.BAD_GATEWAY).build();
+        } else {
+            return ResponseEntity.badRequest().body("State transition from " + rappInstance.getState().name() + " to "
+                                                            + RappInstanceState.UNDEPLOYED.name()
+                                                            + " is not permitted.");
+        }
+    }
+
+    public void updateRappInstanceState(Rapp rapp, RappInstance rappInstance) {
+        acmDeployer.syncRappInstanceStatus(rapp.getCompositionId(), rappInstance);
+    }
+}
index 445297a..987214f 100755 (executable)
@@ -1,14 +1,13 @@
 rappmanager:
   csarlocation: src/main/resources/csar
   acm:
-    baseurl: http://10.101.2.254:30442/onap/policy/clamp/acm/v2/
+    baseurl: http://10.101.3.22:30442/onap/policy/clamp/acm/v2/
     username: runtimeUser
     password: zb!XztG34
-    compositionDefinitionLocation: src/main/resources/compositiondefinition.json
     maxRetries: 3
     retryInterval: 2 #seconds
   sme:
-    baseurl: http://10.101.2.254:30232
+    baseurl: http://localhost:60821 #http://10.101.3.22:61761
     providerBasePath: /api-provider-management/v1/
     invokerBasePath: /api-invoker-management/v1/
     publishApiBasePath: /published-apis/v1/
@@ -27,4 +26,4 @@ management:
   endpoints:
     web:
       exposure:
-        include: "*"
\ No newline at end of file
+        include: "*"
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/a1pms-instance.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/a1pms-instance.json
new file mode 100755 (executable)
index 0000000..fa5d207
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "name": "A1PMSInstance0",
+  "version": "1.0.1",
+  "compositionId": "COMPOSITIONID",
+  "description": "Demo automation composition instance 0",
+  "elements": {
+    "709c62b3-8918-41b9-a747-d21eb79c6c12": {
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c12",
+      "definition": {
+        "name": "onap.policy.clamp.ac.element.A1PMSAutomationCompositionElement",
+        "version": "1.2.3"
+      },
+      "description": "Starter Automation Composition Element for the Demo",
+      "properties": {
+        "policyServiceEntities": [
+          {
+            "a1PolicyServiceEntityId": {
+              "name": "entity1",
+              "version": "1.0.1"
+            },
+            "clientId": "firstService",
+            "callbackUrl": "http:\\localhost"
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/k8s-instance.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/k8s-instance.json
new file mode 100755 (executable)
index 0000000..286a943
--- /dev/null
@@ -0,0 +1,31 @@
+{
+  "name": "DemoInstance0",
+  "version": "1.0.1",
+  "compositionId": "COMPOSITIONID",
+  "description": "Demo automation composition instance 0",
+  "elements": {
+    "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+      "definition": {
+        "name": "onap.policy.clamp.ac.element.K8S_StarterAutomationCompositionElement",
+        "version": "1.2.3"
+      },
+      "description": "Starter Automation Composition Element for the Demo",
+      "properties": {
+        "chart": {
+          "chartId": {
+            "name": "ransliceassurance",
+            "version": "1.0.0"
+          },
+          "namespace": "nonrtric",
+          "releaseName": "ransliceassurance",
+          "podName": "ransliceassurance",
+          "repository": {
+            "repoName": "local",
+            "address": "http://10.101.3.22:8879/charts"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/kserve-instance.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instances/kserve-instance.json
new file mode 100755 (executable)
index 0000000..aaf63a1
--- /dev/null
@@ -0,0 +1,29 @@
+{
+  "name": "KserveInstance0",
+  "version": "1.0.1",
+  "compositionId": "COMPOSITIONID",
+  "description": "Demo automation composition instance 0",
+  "elements": {
+    "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+      "definition": {
+        "name": "onap.policy.clamp.ac.element.KserveAutomationCompositionElement",
+        "version": "1.2.3"
+      },
+      "description": "Starter Automation Composition Element for the Demo",
+      "properties": {
+        "kserveInferenceEntities": [
+          {
+            "kserveInferenceEntityId": {
+              "name": "entity1",
+              "version": "1.0.1"
+            },
+            "name": "sklearn-iris",
+            "namespace": "kserve-test",
+            "payload": "{\"apiVersion\": \"serving.kserve.io/v1beta1\",\"kind\": \"InferenceService\",\"metadata\": {\"name\": \"sklearn-iris\"},\"spec\": {\"predictor\": {\"model\":{\"modelFormat\": {\"name\": \"sklearn\"},\"storageUri\": \"gs://kfserving-examples/models/sklearn/1.0/model\"}}}}"
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instantiation.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Acm/instantiation.json
deleted file mode 100755 (executable)
index c17f49b..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-{
-  "name": "RappInstance0",
-  "version": "1.0.1",
-  "compositionId": "COMPOSITIONID",
-  "description": "Demo automation composition instance 0",
-  "elements": {
-    "709c62b3-8918-41b9-a747-d21eb79c6c20": {
-      "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
-      "definition": {
-        "name": "onap.policy.clamp.ac.element.KserveAutomationCompositionElement",
-        "version": "1.2.3"
-      },
-      "description": "Starter Automation Composition Element for the Demo",
-      "properties": {
-        "kserveInferenceEntities": [
-          {
-            "kserveInferenceEntityId": {
-              "name": "entity1",
-              "version": "1.0.1"
-            },
-            "name": "sklearn-iris",
-            "namespace": "rapps",
-            "payload": "{\"apiVersion\": \"serving.kserve.io/v1beta1\",\"kind\": \"InferenceService\",\"metadata\": {\"name\": \"sklearn-iris\"},\"spec\": {\"predictor\": {\"model\":{\"modelFormat\": {\"name\": \"sklearn\"},\"storageUri\": \"gs://kfserving-examples/models/sklearn/1.0/model\"}}}}"
-          }
-        ]
-      }
-    },
-    "709c62b3-8918-41b9-a747-d21eb79c6c12": {
-      "id": "709c62b3-8918-41b9-a747-d21eb79c6c12",
-      "definition": {
-        "name": "onap.policy.clamp.ac.element.A1PMSAutomationCompositionElement",
-        "version": "1.2.3"
-      },
-      "description": "Starter Automation Composition Element for the Demo",
-      "properties": {
-        "policyServiceEntities": [
-          {
-            "a1PolicyServiceEntityId": {
-              "name": "entity1",
-              "version": "1.0.1"
-            },
-            "clientId": "firstService",
-            "callbackUrl": "http:\\localhost"
-          }
-        ]
-      }
-    },
-    "709c62b3-8918-41b9-a747-d21eb79c6c21": {
-      "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
-      "definition": {
-        "name": "onap.policy.clamp.ac.element.K8S_StarterAutomationCompositionElement",
-        "version": "1.2.3"
-      },
-      "description": "Starter Automation Composition Element for the Demo",
-      "properties": {
-        "chart": {
-          "chartId": {
-            "name": "ransliceassurance",
-            "version": "1.0.0"
-          },
-          "namespace": "nonrtric",
-          "releaseName": "ransliceassurance",
-          "podName": "ransliceassurance",
-          "repository": {
-            "repoName": "local",
-            "address": "http://10.101.2.254:8879/charts"
-          }
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
@@ -1,10 +1,10 @@
 [
   {
-    "apiInvokerInformation": "rApp as invoker 1",
+    "apiInvokerInformation": "Invoker App 1",
     "apiList": [
       {}
     ],
-    "notificationDestination": "http://invoker-app:8086/callback",
+    "notificationDestination": "http://invoker-app1:8086/callback",
     "onboardingInformation": {
       "apiInvokerPublicKey": "{PUBLIC_KEY_INVOKER_1}",
       "apiInvokerCertificate": "apiInvokerCertificate"
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/invokers/invoker-app2.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/invokers/invoker-app2.json
new file mode 100755 (executable)
index 0000000..27e1063
--- /dev/null
@@ -0,0 +1,14 @@
+[
+  {
+    "apiInvokerInformation": "Invoker App 2",
+    "apiList": [
+      {}
+    ],
+    "notificationDestination": "http://invoker-app2:8086/callback",
+    "onboardingInformation": {
+      "apiInvokerPublicKey": "{PUBLIC_KEY_INVOKER_1}",
+      "apiInvokerCertificate": "apiInvokerCertificate"
+    },
+    "requestTestNotification": true
+  }
+]
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/amf-provider-function.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/amf-provider-function.json
new file mode 100755 (executable)
index 0000000..7bb2984
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "apiProvDomInfo": "provider domain rApp as AMF",
+  "apiProvFuncs": [
+    {
+      "apiProvFuncInfo": "rApp as AMF",
+      "apiProvFuncRole": "AMF",
+      "regInfo": {
+        "apiProvPubKey": "AMF-PublicKey"
+      }
+    }
+  ],
+  "regSec": "PSK"
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/apf-provider-function.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/apf-provider-function.json
new file mode 100755 (executable)
index 0000000..8a9383a
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "apiProvDomInfo": "provider domain rApp as APF",
+  "apiProvFuncs": [
+    {
+      "apiProvFuncInfo": "rApp as APF",
+      "apiProvFuncRole": "APF",
+      "regInfo": {
+        "apiProvPubKey": "APF-PublicKey"
+      }
+    }
+  ],
+  "regSec": "PSK"
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/gateway-provider-function.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/providers/gateway-provider-function.json
new file mode 100755 (executable)
index 0000000..fae856a
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "apiProvDomInfo": "provider domain Gateway as entrypoint AEF",
+  "apiProvFuncs": [
+    {
+      "apiProvFuncInfo": "Gateway as entrypoint AEF",
+      "apiProvFuncRole": "AEF",
+      "regInfo": {
+        "apiProvPubKey": "AEF-Gateway-PublicKey"
+      }
+    }
+  ],
+  "regSec": "PSK"
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/serviceapis/api-set-2.json b/rapp-manager-application/src/main/resources/resource-csar/Files/Sme/serviceapis/api-set-2.json
new file mode 100755 (executable)
index 0000000..8b377fe
--- /dev/null
@@ -0,0 +1,45 @@
+{
+  "apiName": "Rapp API Set B",
+  "description": "Example B API of rApp",
+  "aefProfiles": [
+    {
+      "aefId": "rApp as AEF",
+      "description": "Example B rApp as AEF",
+      "versions": [
+        {
+          "apiVersion": "v1",
+          "resources": [
+            {
+              "resourceName": "exampleA",
+              "commType": "REQUEST_RESPONSE",
+              "uri": "/exampleA/subscription/subscription_id_1",
+              "operations": [
+                "GET"
+              ]
+            }
+          ]
+        }
+      ],
+      "protocol": "HTTP_1_1",
+      "securityMethods": [
+        "PSK"
+      ],
+      "interfaceDescriptions": [
+        {
+          "ipv4Addr": "string",
+          "port": 65535,
+          "securityMethods": [
+            "PKI"
+          ]
+        },
+        {
+          "ipv4Addr": "string",
+          "port": 65535,
+          "securityMethods": [
+            "PKI"
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/OnboardingControllerTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/OnboardingControllerTest.java
deleted file mode 100755 (executable)
index c64e999..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.rest;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import com.oransc.rappmanager.acm.service.AcmDeployer;
-import com.oransc.rappmanager.configuration.RappManagerConfiguration;
-import com.oransc.rappmanager.models.RappState;
-import com.oransc.rappmanager.sme.service.SmeDeployer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.UUID;
-import org.apache.http.entity.ContentType;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-@TestPropertySource(properties = "rappmanager.csarlocation=src/test/resources")
-@AutoConfigureMockMvc
-public class OnboardingControllerTest {
-
-    @Autowired
-    private MockMvc mockMvc;
-
-    @Autowired
-    RappManagerConfiguration rappManagerConfiguration;
-
-    @MockBean
-    AcmDeployer acmDeployer;
-
-    @MockBean
-    SmeDeployer smeDeployer;
-
-    private final String validRappFile = "valid-rapp-package.csar";
-
-    private final String invalidRappFile = "invalid-rapp-package.csar";
-
-    @Test
-    void testOnboardCsarPackage() throws Exception {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + validRappFile;
-        MockMultipartFile multipartFile =
-                new MockMultipartFile("file", validRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        mockMvc.perform(
-                        MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/onboard", UUID.randomUUID()).file(multipartFile))
-                .andExpect(status().isAccepted());
-    }
-
-    @Test
-    void testOnboardCsarPackageFailure() throws Exception {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + invalidRappFile;
-        MockMultipartFile multipartFile =
-                new MockMultipartFile("file", invalidRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        mockMvc.perform(
-                        MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/onboard", UUID.randomUUID()).file(multipartFile))
-                .andExpect(status().isBadRequest());
-    }
-
-    @Test
-    void testGetRapp() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        this.onBoardRappCsar(rappId);
-        this.mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}", rappId)).andExpect(status().isOk())
-                .andExpect(jsonPath("$.name").value(rappId.toString()))
-                .andExpect(jsonPath("$.state").value(RappState.ONBOARDED.name()));
-    }
-
-    @Test
-    void testGetInvalidRapp() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        this.mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}", rappId)).andDo(print())
-                .andExpect(status().isBadRequest());
-    }
-
-    @Test
-    void testRappDeploy() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        this.onBoardRappCsar(rappId);
-        when(acmDeployer.deployRapp(any())).thenReturn(true);
-        when(smeDeployer.deployRapp(any())).thenReturn(true);
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/deploy", rappId))
-                .andExpect(status().isAccepted());
-    }
-
-    @Test
-    void testInvalidRappDeploy() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        when(acmDeployer.deployRapp(any())).thenReturn(false);
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/deploy", rappId))
-                .andExpect(status().isInternalServerError());
-    }
-
-    @Test
-    void testRappUndeploy() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        this.onBoardRappCsar(rappId);
-        when(acmDeployer.undeployRapp(any())).thenReturn(true);
-        when(smeDeployer.undeployRapp(any())).thenReturn(true);
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/undeploy", rappId))
-                .andExpect(status().isAccepted());
-    }
-
-    @Test
-    void testInvalidRappUndeploy() throws Exception {
-        UUID rappId = UUID.randomUUID();
-        when(acmDeployer.undeployRapp(any())).thenReturn(false);
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/undeploy", rappId))
-                .andExpect(status().isInternalServerError());
-    }
-
-    void onBoardRappCsar(UUID rappId) throws Exception {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + validRappFile;
-        MockMultipartFile multipartFile =
-                new MockMultipartFile("file", validRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/onboard", rappId).file(multipartFile))
-                .andExpect(status().isAccepted());
-    }
-
-}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappControllerTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappControllerTest.java
new file mode 100755 (executable)
index 0000000..896eef3
--- /dev/null
@@ -0,0 +1,144 @@
+package com.oransc.rappmanager.rest;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.acm.service.AcmDeployer;
+import com.oransc.rappmanager.models.rapp.PrimeOrder;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rapp.RappPrimeOrder;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.models.cache.RappCacheService;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.UUID;
+import org.apache.http.entity.ContentType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+public class RappControllerTest {
+
+    @Autowired
+    private MockMvc mockMvc;
+
+    @Autowired
+    private RappCacheService rappCacheService;
+
+    @MockBean
+    AcmDeployer acmDeployer;
+
+    private final String validRappFile = "valid-rapp-package.csar";
+
+    private final String invalidRappFile = "invalid-rapp-package.csar";
+    private final String validCsarFileLocation = "src/test/resources/";
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    @Test
+    void testGetRapps() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps")).andExpect(status().isOk());
+    }
+
+    @Test
+    void testGetRapp() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        rappCacheService.putRapp(rapp);
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}", rappId)).andExpect(status().isOk())
+                .andExpect(jsonPath("$.rappId").value(rappId.toString()))
+                .andExpect(jsonPath("$.state").value(RappState.COMMISSIONED.name()));
+    }
+
+    @Test
+    void testGetInvalidRapp() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}", UUID.randomUUID()))
+                .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    void testCreateRapp() throws Exception {
+        String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
+        MockMultipartFile multipartFile =
+                new MockMultipartFile("file", validRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}", UUID.randomUUID()).file(multipartFile))
+                .andExpect(status().isAccepted());
+    }
+
+    @Test
+    void testCreateInvalidRapp() throws Exception {
+        String rappCsarPath = validCsarFileLocation + File.separator + invalidRappFile;
+        MockMultipartFile multipartFile =
+                new MockMultipartFile("file", invalidRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}", UUID.randomUUID()).file(multipartFile))
+                .andExpect(status().isBadRequest());
+    }
+
+    @Test
+    void testPrimeRapp() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        rappCacheService.putRapp(rapp);
+        when(acmDeployer.primeRapp(any())).thenReturn(true);
+        RappPrimeOrder rappPrimeOrder = new RappPrimeOrder();
+        rappPrimeOrder.setPrimeOrder(PrimeOrder.PRIME);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}", rappId).contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappPrimeOrder))).andExpect(status().isOk());
+    }
+
+    @ParameterizedTest
+    @EnumSource(value = PrimeOrder.class, names = {"PRIME", "DEPRIME"})
+    void testPrimeRappFailure(PrimeOrder primeOrder) throws Exception {
+        RappPrimeOrder rappPrimeOrder = new RappPrimeOrder();
+        rappPrimeOrder.setPrimeOrder(primeOrder);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}", UUID.randomUUID())
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappPrimeOrder)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testDeprimeRapp() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        rappCacheService.putRapp(rapp);
+        when(acmDeployer.deprimeRapp(any())).thenReturn(true);
+        RappPrimeOrder rappPrimeOrder = new RappPrimeOrder();
+        rappPrimeOrder.setPrimeOrder(PrimeOrder.DEPRIME);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}", rappId).contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappPrimeOrder))).andExpect(status().isOk());
+    }
+
+    @Test
+    void testDeleteRapp() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        rappCacheService.putRapp(rapp);
+        mockMvc.perform(MockMvcRequestBuilders.delete("/rapps/{rapp_id}", rappId)).andExpect(status().isOk());
+    }
+
+    @Test
+    void testDeleteRappFailure() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.delete("/rapps/{rapp_id}", UUID.randomUUID()))
+                .andExpect(status().isNotFound());
+    }
+}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappInstanceControllerTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/rest/RappInstanceControllerTest.java
new file mode 100755 (executable)
index 0000000..3ad2059
--- /dev/null
@@ -0,0 +1,277 @@
+package com.oransc.rappmanager.rest;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.acm.service.AcmDeployer;
+import com.oransc.rappmanager.models.rappinstance.DeployOrder;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceDeployOrder;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.models.cache.RappCacheService;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.sme.service.SmeDeployer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+public class RappInstanceControllerTest {
+
+    @Autowired
+    private MockMvc mockMvc;
+
+    @Autowired
+    private RappCacheService rappCacheService;
+
+    @Autowired
+    private RappInstanceStateMachine rappInstanceStateMachine;
+
+    @MockBean
+    AcmDeployer acmDeployer;
+
+    @MockBean
+    SmeDeployer smeDeployer;
+
+    private final String validRappFile = "valid-rapp-package.csar";
+
+    private final String invalidRappFile = "invalid-rapp-package.csar";
+    private final String validCsarFileLocation = "src/test/resources/";
+
+    private final ObjectMapper objectMapper = new ObjectMapper();
+
+    @Test
+    void testGetAllRappInstances() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rappCacheService.putRapp(rapp);
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}/instance", rappId)).andExpect(status().isOk())
+                .andExpect(
+                        jsonPath("$." + rappInstanceId.toString() + ".rappInstanceId").value(rappInstanceId.toString()))
+                .andExpect(jsonPath("$." + rappInstanceId.toString() + ".state").value(
+                        RappInstanceState.UNDEPLOYED.name()));
+    }
+
+    @Test
+    void testGetAllRappInstancesFailure() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}/instance", UUID.randomUUID()))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testCreateRappInstance() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setRappInstanceId(rappInstanceId);
+        rappInstance.setState(RappInstanceState.UNDEPLOYED);
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        rappCacheService.putRapp(rapp);
+        mockMvc.perform(
+                MockMvcRequestBuilders.post("/rapps/{rapp_id}/instance", rappId).contentType(MediaType.APPLICATION_JSON)
+                        .content(objectMapper.writeValueAsString(rappInstance))).andExpect(status().isOk());
+        Rapp rappResult = rappCacheService.getRapp(String.valueOf(rappId)).get();
+        assertNotNull(rappResult.getRappInstances().get(rappInstanceId));
+    }
+
+    @Test
+    void testCreateRappInstanceFailure() throws Exception {
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setRappInstanceId(UUID.randomUUID());
+        rappInstance.setState(RappInstanceState.UNDEPLOYED);
+        mockMvc.perform(MockMvcRequestBuilders.post("/rapps/{rapp_id}/instance", UUID.randomUUID())
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstance)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testGetRappInstance() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId))
+                .andExpect(status().isOk()).andExpect(jsonPath("$.rappInstanceId").value(rappInstanceId.toString()))
+                .andExpect(jsonPath("$.state").value(RappInstanceState.UNDEPLOYED.name()));
+    }
+
+    @Test
+    void testGetRappInstanceNoRappFailure() throws Exception {
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}/instance/{instance_id}", UUID.randomUUID(),
+                UUID.randomUUID())).andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testGetRappInstanceNoRappInstanceFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        rappCacheService.putRapp(rapp);
+        mockMvc.perform(MockMvcRequestBuilders.get("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testDeployRappInstance() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.DEPLOY);
+        when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId)
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isAccepted());
+    }
+
+
+    @Test
+    void testDeployNoRappInstanceFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rapp.setRappInstances(Map.of());
+        rappCacheService.putRapp(rapp);
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.DEPLOY);
+        when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId)
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testDeployNoRappFailure() throws Exception {
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.DEPLOY);
+        when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", UUID.randomUUID(),
+                                UUID.randomUUID()).contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testUndeployRappInstance() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rapp.getRappInstances().forEach((uuid, rappInstance) -> rappInstance.setState(RappInstanceState.DEPLOYED));
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.UNDEPLOY);
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId)
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isAccepted());
+    }
+
+    @Test
+    void testUndeployNoRappInstanceFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rapp.setRappInstances(Map.of());
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.UNDEPLOY);
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId)
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testUndeployNoRappFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        RappInstanceDeployOrder rappInstanceDeployOrder = new RappInstanceDeployOrder();
+        rappInstanceDeployOrder.setDeployOrder(DeployOrder.UNDEPLOY);
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        mockMvc.perform(MockMvcRequestBuilders.put("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId)
+                                .contentType(MediaType.APPLICATION_JSON)
+                                .content(objectMapper.writeValueAsString(rappInstanceDeployOrder)))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testDeleteRappInstance() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        mockMvc.perform(
+                        MockMvcRequestBuilders.delete("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId))
+                .andExpect(status().isNoContent());
+    }
+
+    @Test
+    void testDeleteRappNoRappFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        mockMvc.perform(
+                        MockMvcRequestBuilders.delete("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId))
+                .andExpect(status().isNotFound());
+    }
+
+    @Test
+    void testDeleteRappNoInstanceFailure() throws Exception {
+        UUID rappId = UUID.randomUUID();
+        UUID rappInstanceId = UUID.randomUUID();
+        Rapp rapp = getRapp(rappId, rappInstanceId);
+        rapp.setRappInstances(Map.of());
+        rappCacheService.putRapp(rapp);
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        mockMvc.perform(
+                        MockMvcRequestBuilders.delete("/rapps/{rapp_id}/instance/{instance_id}", rappId, rappInstanceId))
+                .andExpect(status().isNotFound());
+    }
+
+    Rapp getRapp(UUID rappId, UUID rappInstanceId) {
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setRappInstanceId(rappInstanceId);
+        rappInstance.setState(RappInstanceState.UNDEPLOYED);
+        Map<UUID, RappInstance> instances = new HashMap();
+        instances.put(rappInstanceId, rappInstance);
+        Rapp rapp = Rapp.builder().rappId(rappId).name(String.valueOf(rappId)).packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).rappInstances(instances)
+                            .build();
+        return rapp;
+    }
+
+}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/AcmDeployerTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/AcmDeployerTest.java
deleted file mode 100755 (executable)
index 5682ca0..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.service;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
-import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
-import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
-import com.oransc.rappmanager.acm.service.AcmDeployer;
-import com.oransc.rappmanager.configuration.RappManagerConfiguration;
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
-import com.oransc.rappmanager.models.cache.RappCacheService;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.UUID;
-import org.apache.http.entity.ContentType;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-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;
-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.messages.rest.instantiation.InstantiationResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.SpyBean;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.web.client.ExpectedCount;
-import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-import org.springframework.web.client.RestTemplate;
-
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-@TestPropertySource(properties = "rappmanager.csarlocation=src/test/resources")
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@AutoConfigureMockMvc
-public class AcmDeployerTest {
-
-    MockRestServiceServer mockServer;
-    @SpyBean
-    AcmDeployer acmDeployer;
-    @Autowired
-    RestTemplate restTemplate;
-    @Autowired
-    ACMConfiguration acmConfiguration;
-    @Autowired
-    RappManagerConfiguration rappManagerConfiguration;
-    @Autowired
-    private MockMvc mockMvc;
-    @Autowired
-    RappCacheService rappCacheService;
-    @SpyBean
-    RappStateMachine rappStateMachine;
-    private final String validRappFile = "valid-rapp-package.csar";
-    ObjectMapper objectMapper = new ObjectMapper();
-    String URI_ACM_COMPOSITIONS, URI_ACM_COMPOSITION, URI_ACM_INSTANCES, URI_ACM_INSTANCE;
-
-    @BeforeAll
-    void initACMURI() {
-        URI_ACM_COMPOSITIONS = acmConfiguration.getBaseUrl() + "compositions";
-        URI_ACM_COMPOSITION = acmConfiguration.getBaseUrl() + "compositions/%s";
-        URI_ACM_INSTANCES = acmConfiguration.getBaseUrl() + "compositions/%s/instances";
-        URI_ACM_INSTANCE = acmConfiguration.getBaseUrl() + "compositions/%s/instances/%s";
-    }
-
-
-    @BeforeEach
-    public void init() {
-        mockServer = MockRestServiceServer.createServer(restTemplate);
-    }
-
-    @Test
-    void testCreateComposition() throws IOException {
-        String compositionPayload = Files.readString(Path.of(acmConfiguration.getCompositionDefinitionLocation()));
-        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
-        commissioningResponseExpected.setCompositionId(UUID.randomUUID());
-        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
-                .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
-                                    .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
-        CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
-        mockServer.verify();
-        assertEquals(commissioningResponseActual.getCompositionId(), commissioningResponseExpected.getCompositionId());
-    }
-
-    @Test
-    void testCreateCompositionFailure() throws IOException {
-        String compositionPayload = Files.readString(Path.of(acmConfiguration.getCompositionDefinitionLocation()));
-        mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST))
-                .andRespond(withStatus(HttpStatus.BAD_GATEWAY));
-        CommissioningResponse commissioningResponseActual = acmDeployer.createComposition(compositionPayload);
-        mockServer.verify();
-        assertNull(commissioningResponseActual);
-    }
-
-    @Test
-    void testCompositionPriming() {
-        UUID compositionId = UUID.randomUUID();
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
-                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
-
-        acmDeployer.primeACMComposition(compositionId, PrimeOrder.PRIME);
-        mockServer.verify();
-    }
-
-    @Test
-    void testDeployRapp() throws Exception {
-
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .build();
-        onBoardRappCsar(rappId);
-        InstantiationResponse instantiationResponse = new InstantiationResponse();
-        instantiationResponse.setInstanceId(instanceId);
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
-                .andExpect(method(HttpMethod.POST)).andRespond(
-                        withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
-                                .body(objectMapper.writeValueAsString(instantiationResponse)));
-
-        mockServer.expect(ExpectedCount.once(),
-                        requestTo(acmConfiguration.getBaseUrl() + "compositions/" + compositionId + "/instances/" + instanceId))
-                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
-
-
-        boolean rappDeployStateActual = acmDeployer.deployRapp(rapp);
-        assertTrue(rappDeployStateActual);
-        mockServer.verify();
-    }
-
-    @Test
-    void testDeployRappFailure() throws Exception {
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .build();
-        onBoardRappCsar(rappId);
-        InstantiationResponse instantiationResponse = new InstantiationResponse();
-        instantiationResponse.setInstanceId(instanceId);
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
-                .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
-
-        boolean rappDeployStateActual = acmDeployer.deployRapp(rapp);
-        mockServer.verify();
-        assertFalse(rappDeployStateActual);
-    }
-
-    @Test
-    void testUndeployRapp() throws JsonProcessingException {
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .compositionId(compositionId).compositionInstanceId(instanceId).state(RappState.DEPLOYED)
-                            .build();
-        rappCacheService.putRapp(rapp);
-        rappStateMachine.onboardRapp(rappId);
-
-        expectAcmGetInstanceToReturnDeployedState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
-                ExpectedCount.once());
-
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
-                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
-
-        expectAcmGetInstanceToReturnDeployedState(compositionId, instanceId, DeployState.UNDEPLOYED, LockState.UNLOCKED,
-                ExpectedCount.once());
-
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
-                .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
-
-
-        boolean rappUndeployStateActual = acmDeployer.undeployRapp(rapp);
-        mockServer.verify();
-        assertTrue(rappUndeployStateActual);
-    }
-
-    @Test
-    void testUndeployRappFailure() throws JsonProcessingException {
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
-                            .compositionInstanceId(instanceId).state(RappState.DEPLOYED).build();
-        rappCacheService.putRapp(rapp);
-
-        expectAcmGetInstanceToReturnDeployedState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
-                ExpectedCount.once());
-
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
-                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
-
-        expectAcmGetInstanceToReturnDeployedState(compositionId, instanceId, DeployState.UNDEPLOYING,
-                LockState.UNLOCKING, ExpectedCount.manyTimes());
-
-        boolean rappUndeployStateActual = acmDeployer.undeployRapp(rapp);
-        mockServer.verify();
-        assertFalse(rappUndeployStateActual);
-    }
-
-    @Test
-    void testSyncRappStatus() throws JsonProcessingException {
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .compositionId(compositionId).compositionInstanceId(instanceId).state(RappState.DEPLOYED)
-                            .build();
-        rappCacheService.putRapp(rapp);
-        rappStateMachine.onboardRapp(rappId);
-
-        expectAcmGetInstanceToReturnDeployedState(compositionId, instanceId, DeployState.UNDEPLOYING,
-                LockState.UNLOCKING, ExpectedCount.once());
-
-        acmDeployer.syncRappStatus(rapp);
-        mockServer.verify();
-        verify(rappStateMachine, times(1)).sendRappEvent(rapp, RappEvent.UNDEPLOYING);
-    }
-
-    @Test
-    void testSyncRappStatusFailure() {
-        UUID compositionId = UUID.randomUUID();
-        when(acmDeployer.getCompositionId()).thenReturn(compositionId);
-        UUID rappId = UUID.randomUUID();
-        UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
-                            .compositionInstanceId(instanceId).state(RappState.DEPLOYED).build();
-        rappCacheService.putRapp(rapp);
-
-        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
-                .andExpect(method(HttpMethod.GET)).andRespond(withStatus(HttpStatus.BAD_GATEWAY));
-
-        acmDeployer.syncRappStatus(rapp);
-        mockServer.verify();
-        verify(rappStateMachine, never()).sendRappEvent(any(), any());
-    }
-
-    void expectAcmGetInstanceToReturnDeployedState(UUID compositionId, UUID instanceId, DeployState deployState,
-            LockState lockState, ExpectedCount expectedCount) throws JsonProcessingException {
-        AutomationComposition automationCompositionDeployed = new AutomationComposition();
-        automationCompositionDeployed.setCompositionId(compositionId);
-        automationCompositionDeployed.setInstanceId(instanceId);
-        automationCompositionDeployed.setDeployState(deployState);
-        automationCompositionDeployed.setLockState(lockState);
-
-        mockServer.expect(expectedCount, requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
-                .andExpect(method(HttpMethod.GET)).andRespond(
-                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
-                                .body(objectMapper.writeValueAsString(automationCompositionDeployed)));
-    }
-
-    void onBoardRappCsar(UUID rappId) throws Exception {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + validRappFile;
-        MockMultipartFile multipartFile =
-                new MockMultipartFile("file", validRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/onboard", rappId).file(multipartFile))
-                .andExpect(status().isAccepted());
-    }
-
-
-}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappCsarConfigurationHandlerTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappCsarConfigurationHandlerTest.java
deleted file mode 100755 (executable)
index f92becb..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.service;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.oransc.rappmanager.configuration.RappManagerConfiguration;
-
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.UUID;
-import org.apache.http.entity.ContentType;
-import org.junit.jupiter.api.Test;
-import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.web.multipart.MultipartFile;
-
-@SpringBootTest
-@TestPropertySource(properties = "rappmanager.csarlocation=src/test/resources")
-public class RappCsarConfigurationHandlerTest {
-
-    @Autowired
-    RappCsarConfigurationHandler rappCsarConfigurationHandler;
-
-    @Autowired
-    RappManagerConfiguration rappManagerConfiguration;
-
-    ObjectMapper objectMapper = new ObjectMapper();
-
-
-    private final String validRappFile = "valid-rapp-package.csar";
-
-    private final String invalidRappFile = "invalid-rapp-package.csar";
-
-    @Test
-    void testCsarPackageValidationSuccess() throws IOException {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + validRappFile;
-        MultipartFile multipartFile =
-                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        assertEquals(Boolean.TRUE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
-    }
-
-    @Test
-    void testCsarPackageValidationFailure() throws IOException {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + invalidRappFile;
-        MultipartFile multipartFile =
-                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
-    }
-
-    @Test
-    void testCsarInstantiationPayload() throws JsonProcessingException {
-        Rapp rapp = Rapp.builder().name("").packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).build();
-        UUID compositionId = UUID.randomUUID();
-        AutomationComposition automationComposition =
-                objectMapper.readValue(rappCsarConfigurationHandler.getInstantiationPayload(rapp, compositionId),
-                        AutomationComposition.class);
-        assertEquals(automationComposition.getCompositionId(), compositionId);
-    }
-}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java
new file mode 100755 (executable)
index 0000000..803504b
--- /dev/null
@@ -0,0 +1,157 @@
+package com.oransc.rappmanager.service;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import com.oransc.rappmanager.acm.service.AcmDeployer;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import com.oransc.rappmanager.models.rapp.RappState;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.sme.service.SmeDeployer;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.HttpStatus;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+public class RappServiceTest {
+
+    @Autowired
+    RappService rappService;
+
+    @MockBean
+    AcmDeployer acmDeployer;
+
+    @MockBean
+    SmeDeployer smeDeployer;
+
+    @Autowired
+    RappInstanceStateMachine rappInstanceStateMachine;
+
+    String validCsarFileLocation = "src/test/resources/";
+
+    private final String validRappFile = "valid-rapp-package.csar";
+
+    private final String invalidRappFile = "invalid-rapp-package.csar";
+
+
+    @Test
+    void testPrimeRapp() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        when(acmDeployer.primeRapp(any())).thenReturn(true);
+        assertEquals(HttpStatus.OK, rappService.primeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testPrimeRappInvalidState() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMING).build();
+        assertEquals(HttpStatus.BAD_REQUEST, rappService.primeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testPrimeRappAcmFailure() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        when(acmDeployer.primeRapp(any())).thenReturn(false);
+        assertEquals(HttpStatus.OK, rappService.primeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testDeprimeRapp() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        when(acmDeployer.deprimeRapp(any())).thenReturn(true);
+        assertEquals(HttpStatus.OK, rappService.deprimeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testDeprimeRappFailure() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        when(acmDeployer.deprimeRapp(any())).thenReturn(false);
+        assertEquals(HttpStatus.OK, rappService.deprimeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testDeprimeRappInvalidState() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        assertEquals(HttpStatus.BAD_REQUEST, rappService.deprimeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testDeprimeRappActiveInstances() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .rappInstances(Map.of(UUID.randomUUID(), new RappInstance())).build();
+        assertEquals(HttpStatus.BAD_REQUEST, rappService.deprimeRapp(rapp).getStatusCode());
+    }
+
+    @Test
+    void testDeployRappInstance() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        RappInstance rappInstance = new RappInstance();
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        assertEquals(HttpStatus.ACCEPTED, rappService.deployRappInstance(rapp, rappInstance).getStatusCode());
+    }
+
+    @Test
+    void testDeployRappInstanceFailure() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        RappInstance rappInstance = new RappInstance();
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.deployRappInstance(any(), any())).thenReturn(false);
+        assertEquals(HttpStatus.BAD_GATEWAY, rappService.deployRappInstance(rapp, rappInstance).getStatusCode());
+    }
+
+    @Test
+    void testUndeployRappInstance() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setState(RappInstanceState.DEPLOYED);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        assertEquals(HttpStatus.ACCEPTED, rappService.undeployRappInstance(rapp, rappInstance).getStatusCode());
+    }
+
+    @Test
+    void testUndeployRappInstanceFailure() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setState(RappInstanceState.DEPLOYED);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(false);
+        assertEquals(HttpStatus.BAD_GATEWAY, rappService.undeployRappInstance(rapp, rappInstance).getStatusCode());
+    }
+
+    @Test
+    void testUndeployRappInstanceInvalidStateFailure() {
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build();
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setState(RappInstanceState.DEPLOYING);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true);
+        when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(false);
+        assertEquals(HttpStatus.BAD_REQUEST, rappService.undeployRappInstance(rapp, rappInstance).getStatusCode());
+    }
+}
diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/statemachine/RappStateMachineTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/statemachine/RappStateMachineTest.java
deleted file mode 100755 (executable)
index 6deb839..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.statemachine;
-
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
-import java.util.UUID;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.statemachine.StateMachine;
-import org.springframework.statemachine.config.StateMachineFactory;
-import org.springframework.statemachine.test.StateMachineTestPlan;
-import org.springframework.statemachine.test.StateMachineTestPlanBuilder;
-
-@SpringBootTest
-public class RappStateMachineTest {
-
-    @Autowired
-    StateMachineFactory<RappState, RappEvent> stateMachineFactory;
-
-    StateMachine<RappState, RappEvent> stateMachine;
-
-    @BeforeEach
-    void getStateMachine() {
-        stateMachine = stateMachineFactory.getStateMachine(UUID.randomUUID());
-        stateMachine.startReactively().subscribe();
-    }
-
-    @AfterEach
-    void stopStateMachine() {
-        stateMachine.stopReactively().subscribe();
-    }
-
-    @Test
-    void testOnboardedState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().build();
-        plan.test();
-    }
-
-    @Test
-    void testDeployingState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().build();
-        plan.test();
-    }
-
-    @ParameterizedTest
-    @EnumSource(value = RappEvent.class, names = {"ACMDEPLOYED", "SMEDEPLOYED"})
-    void testIndividualDeployedState(RappEvent rappEvent) throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step().sendEvent(rappEvent)
-                        .expectState(RappState.DEPLOYING).and().build();
-        plan.test();
-    }
-
-    @Test
-    void testDeployedState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappState.DEPLOYED).expectStateChanged(1).and()
-                        .build();
-        plan.test();
-    }
-
-    @Test
-    void testDeployFailedState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYFAILED).expectState(RappState.FAILED).expectStateChanged(1).and()
-                        .build();
-        plan.test();
-    }
-
-    @Test
-    void testUndeployingState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappState.DEPLOYED).expectStateChanged(1).and()
-                        .step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappState.UNDEPLOYING)
-                        .expectStateChanged(1).and().build();
-        plan.test();
-    }
-
-    @ParameterizedTest
-    @EnumSource(value = RappEvent.class, names = {"ACMUNDEPLOYED", "SMEUNDEPLOYED"})
-    void testIndividualUndeployedState(RappEvent rappEvent) throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappState.DEPLOYED).expectStateChanged(1).and()
-                        .step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappState.UNDEPLOYING)
-                        .expectStateChanged(1).and().step().sendEvent(rappEvent).expectState(RappState.UNDEPLOYING)
-                        .and().build();
-        plan.test();
-    }
-
-    @Test
-    void testUndeployedState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappState.DEPLOYED).expectStateChanged(1).and()
-                        .step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappState.UNDEPLOYING)
-                        .expectStateChanged(1).and().step().sendEvent(RappEvent.ACMUNDEPLOYED)
-                        .expectState(RappState.UNDEPLOYING).and().step().sendEvent(RappEvent.SMEUNDEPLOYED)
-                        .expectState(RappState.UNDEPLOYED).expectStateChanged(1).and().build();
-        plan.test();
-    }
-
-    @Test
-    void testUndeployFailedState() throws Exception {
-        StateMachineTestPlan plan =
-                StateMachineTestPlanBuilder.<RappState, RappEvent>builder().stateMachine(stateMachine).step()
-                        .expectState(RappState.ONBOARDED).and().step().sendEvent(RappEvent.DEPLOYING)
-                        .expectState(RappState.DEPLOYING).expectStateChanged(1).and().step()
-                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappState.DEPLOYING).and().step()
-                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappState.DEPLOYED).expectStateChanged(1).and()
-                        .step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappState.UNDEPLOYING)
-                        .expectStateChanged(1).and().step().sendEvent(RappEvent.ACMUNDEPLOYED)
-                        .expectState(RappState.UNDEPLOYING).and().step().sendEvent(RappEvent.SMEUNDEPLOYFAILED)
-                        .expectState(RappState.FAILED).expectStateChanged(1).and().build();
-        plan.test();
-    }
-
-
-}
index 205094e..b8b36e3 100755 (executable)
Binary files a/rapp-manager-application/src/test/resources/valid-rapp-package.csar and b/rapp-manager-application/src/test/resources/valid-rapp-package.csar differ
index 918d936..4d1414d 100755 (executable)
             <artifactId>spring-statemachine-core</artifactId>
             <version>3.2.1</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.statemachine</groupId>
+            <artifactId>spring-statemachine-test</artifactId>
+            <version>3.2.1</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.3.2</version>
+            <scope>test</scope>
+        </dependency>
+
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappCsarConfigurationHandler.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappCsarConfigurationHandler.java
deleted file mode 100755 (executable)
index 5574f38..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-
- * ============LICENSE_START======================================================================
- * Copyright (C) 2023 Nordix Foundation. All rights reserved.
- * ===============================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END========================================================================
- */
-
-package com.oransc.rappmanager.models;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.UUID;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-@Service
-public class RappCsarConfigurationHandler {
-
-    Logger logger = LoggerFactory.getLogger(RappCsarConfigurationHandler.class);
-    private final String acmInstantiationJsonLocation = "Files/Acm/instantiation.json";
-
-    private final String smeProviderDomainLocation = "Files/Sme/provider-domain.json";
-
-    private final String smeProviderApiLocation = "Files/Sme/provider-api.json";
-
-    private final String smeInvokerLocation = "Files/Sme/invoker.json";
-
-
-    public boolean isValidRappPackage(MultipartFile multipartFile) {
-        return multipartFile.getOriginalFilename() != null && multipartFile.getOriginalFilename().endsWith(".csar")
-                       && isFileExistsInCsar(multipartFile, acmInstantiationJsonLocation);
-    }
-
-    boolean isFileExistsInCsar(MultipartFile multipartFile, String fileLocation) {
-        try (ZipInputStream zipInputStream = new ZipInputStream(multipartFile.getInputStream())) {
-            ZipEntry zipEntry;
-            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
-                if (zipEntry.getName().matches(fileLocation)) {
-                    return Boolean.TRUE;
-                }
-            }
-            return Boolean.FALSE;
-        } catch (IOException e) {
-            logger.error("Unable to find the CSAR file", e);
-            return Boolean.FALSE;
-        }
-    }
-
-    public Path getRappPackageLocation(String csarLocation, String rappId, String fileName) {
-        return Path.of(csarLocation, rappId, fileName);
-    }
-
-    public String getInstantiationPayload(Rapp rapp, UUID compositionId) {
-        return getPayload(rapp, acmInstantiationJsonLocation).replaceAll("COMPOSITIONID",
-                String.valueOf(compositionId));
-    }
-
-    String getPayload(Rapp rapp, String location) {
-        File csarFile = new File(
-                getRappPackageLocation(rapp.getPackageLocation(), rapp.getName(), rapp.getPackageName()).toUri());
-        return getFileFromCsar(csarFile, location).toString();
-    }
-
-    ByteArrayOutputStream getFileFromCsar(File csarFile, String fileLocation) {
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-        try (FileInputStream fileInputStream = new FileInputStream(csarFile);
-             ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
-            ZipEntry entry;
-            while ((entry = zipInputStream.getNextEntry()) != null) {
-                if (!entry.isDirectory() && entry.getName().equals(fileLocation)) {
-                    byte[] buffer = new byte[1024];
-                    int bytesRead;
-                    while ((bytesRead = zipInputStream.read(buffer)) != -1) {
-                        byteArrayOutputStream.write(buffer, 0, bytesRead);
-                    }
-                }
-            }
-        } catch (IOException e) {
-            logger.error("Unable to find the CSAR file", e);
-        }
-        return byteArrayOutputStream;
-    }
-
-
-    public String getSmeProviderDomainPayload(Rapp rapp) {
-        return getPayload(rapp, smeProviderDomainLocation);
-    }
-
-    public String getSmeProviderApiPayload(Rapp rapp) {
-        return getPayload(rapp, smeProviderApiLocation);
-    }
-
-    public String getSmeInvokerPayload(Rapp rapp) {
-        return getPayload(rapp, smeInvokerLocation);
-    }
-
-}
index 9c6a410..9aa3fca 100755 (executable)
@@ -1,6 +1,33 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
 package com.oransc.rappmanager.models;
 
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+
 public interface RappDeployer {
-    boolean deployRapp(Rapp rapp);
-    boolean undeployRapp(Rapp rapp);
+
+    boolean deployRappInstance(Rapp rapp, RappInstance rappInstance);
+
+    boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance);
+
+    boolean primeRapp(Rapp rapp);
+
+    boolean deprimeRapp(Rapp rapp);
 }
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappEvent.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/RappEvent.java
deleted file mode 100755 (executable)
index 0f64e55..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.oransc.rappmanager.models;
-
-public enum RappEvent {
-    ONBOARDED, DEPLOYING, ACMDEPLOYED, SMEDEPLOYED, ACMDEPLOYFAILED, SMEDEPLOYFAILED, DEPLOYED, UNDEPLOYING, UNDEPLOYED,
-    ACMUNDEPLOYED, SMEUNDEPLOYED, ACMUNDEPLOYFAILED, SMEUNDEPLOYFAILED
-}
index d2b273c..ec7d7b2 100755 (executable)
@@ -18,8 +18,7 @@
 
 package com.oransc.rappmanager.models.cache;
 
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
+import com.oransc.rappmanager.models.rapp.Rapp;
 import java.util.Optional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.cache.Cache;
@@ -32,7 +31,6 @@ public class RappCacheService {
 
     private final String RAPP_CACHE = "rapp-cache";
     private final CacheManager cacheManager;
-    private final RappStateMachine rappStateMachine;
 
     public Cache getAllRapp() {
         return cacheManager.getCache(RAPP_CACHE);
@@ -40,9 +38,7 @@ public class RappCacheService {
 
     public Optional<Rapp> getRapp(String rappId) {
         final Cache cache = cacheManager.getCache(RAPP_CACHE);
-        Optional<Rapp> rappOptional = Optional.ofNullable(cache.get(rappId, Rapp.class));
-        rappOptional.ifPresent(rapp -> rapp.setState(rappStateMachine.getRappState(rapp.getRappId())));
-        return rappOptional;
+        return Optional.ofNullable(cache.get(rappId, Rapp.class));
     }
 
     public void putRapp(Rapp rapp) {
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandler.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandler.java
new file mode 100755 (executable)
index 0000000..f7cdece
--- /dev/null
@@ -0,0 +1,168 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.csar;
+
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
+import com.oransc.rappmanager.models.rapp.RappResources;
+import com.oransc.rappmanager.models.rappinstance.RappSMEInstance;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Predicate;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+@Service
+public class RappCsarConfigurationHandler {
+
+    Logger logger = LoggerFactory.getLogger(RappCsarConfigurationHandler.class);
+    private final String acmCompositionJsonLocation = "Files/Acm/definition/compositions.json";
+    private final String acmDefinitionLocation = "Files/Acm/definition";
+    private final String acmInstancesLocation = "Files/Acm/instances";
+
+    private final String smeProviderFuncsLocation = "Files/Sme/providers";
+    private final String smeServiceApisLocation = "Files/Sme/serviceapis";
+
+    private final String smeInvokersLocation = "Files/Sme/invokers";
+
+
+    public boolean isValidRappPackage(MultipartFile multipartFile) {
+        return multipartFile.getOriginalFilename() != null && multipartFile.getOriginalFilename().endsWith(".csar")
+                       && isFileExistsInCsar(multipartFile, acmCompositionJsonLocation);
+        //TODO Additional file checks needs to be added
+    }
+
+    boolean isFileExistsInCsar(MultipartFile multipartFile, String fileLocation) {
+        try (ZipInputStream zipInputStream = new ZipInputStream(multipartFile.getInputStream())) {
+            ZipEntry zipEntry;
+            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+                if (zipEntry.getName().matches(fileLocation)) {
+                    return Boolean.TRUE;
+                }
+            }
+            return Boolean.FALSE;
+        } catch (IOException e) {
+            logger.error("Unable to find the CSAR file", e);
+            return Boolean.FALSE;
+        }
+    }
+
+    public Path getRappPackageLocation(String csarLocation, String rappId, String fileName) {
+        return Path.of(csarLocation, rappId, fileName);
+    }
+
+    public String getInstantiationPayload(Rapp rapp, RappACMInstance rappACMInstance, UUID compositionId) {
+        return getPayload(rapp, getResourceUri(acmInstancesLocation, rappACMInstance.getInstance())).replaceAll(
+                "COMPOSITIONID", String.valueOf(compositionId));
+    }
+
+    String getPayload(Rapp rapp, String location) {
+        logger.info("Getting payload for {} from {}", rapp.getRappId(), location);
+        File csarFile = getCsarFile(rapp);
+        return getFileFromCsar(csarFile, location).toString();
+    }
+
+    File getCsarFile(Rapp rapp) {
+        return new File(
+                getRappPackageLocation(rapp.getPackageLocation(), rapp.getName(), rapp.getPackageName()).toUri());
+    }
+
+    ByteArrayOutputStream getFileFromCsar(File csarFile, String fileLocation) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        try (FileInputStream fileInputStream = new FileInputStream(csarFile);
+             ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
+            ZipEntry entry;
+            while ((entry = zipInputStream.getNextEntry()) != null) {
+                if (!entry.isDirectory() && entry.getName().equals(fileLocation)) {
+                    byte[] buffer = new byte[1024];
+                    int bytesRead;
+                    while ((bytesRead = zipInputStream.read(buffer)) != -1) {
+                        byteArrayOutputStream.write(buffer, 0, bytesRead);
+                    }
+                }
+            }
+        } catch (IOException e) {
+            logger.error("Unable to find the CSAR file", e);
+        }
+        return byteArrayOutputStream;
+    }
+
+
+    public String getSmeProviderDomainPayload(Rapp rapp, RappSMEInstance rappSMEInstance) {
+        return getPayload(rapp, getResourceUri(smeProviderFuncsLocation, rappSMEInstance.getProviderFunction()));
+    }
+
+    public String getSmeProviderApiPayload(Rapp rapp, RappSMEInstance rappSMEInstance) {
+        return getPayload(rapp, getResourceUri(smeServiceApisLocation, rappSMEInstance.getServiceApis()));
+    }
+
+    public String getSmeInvokerPayload(Rapp rapp, RappSMEInstance rappSMEInstance) {
+        return getPayload(rapp, getResourceUri(smeInvokersLocation, rappSMEInstance.getInvokers()));
+    }
+
+    public String getAcmCompositionPayload(Rapp rapp) {
+        return getPayload(rapp,
+                getResourceUri(acmDefinitionLocation, rapp.getRappResources().getAcm().getCompositionDefinitions()));
+    }
+
+    String getResourceUri(String resourceLocation, String resource) {
+        return resourceLocation + "/" + resource + ".json";
+    }
+
+    public RappResources getRappResource(Rapp rapp) {
+        RappResources rappResources = new RappResources();
+        try {
+            File csarFile = getCsarFile(rapp);
+            if (csarFile.exists()) {
+                rappResources.setAcm(RappResources.ACMResources.builder().compositionDefinitions(
+                                getFileListFromCsar(csarFile, acmDefinitionLocation).get(0))
+                                             .compositionInstances(getFileListFromCsar(csarFile, acmInstancesLocation))
+                                             .build());
+                rappResources.setSme(RappResources.SMEResources.builder()
+                                             .providerFunctions(getFileListFromCsar(csarFile, smeProviderFuncsLocation))
+                                             .serviceApis(getFileListFromCsar(csarFile, smeServiceApisLocation))
+                                             .invokers(getFileListFromCsar(csarFile, smeInvokersLocation)).build());
+            }
+        } catch (Exception e) {
+            logger.warn("Error in getting the rapp resources", e);
+        }
+        return rappResources;
+    }
+
+    List<String> getFileListFromCsar(File csarFile, String dirLocation) {
+        try (ZipFile zipFile = new ZipFile(csarFile)) {
+            return zipFile.stream().filter(Predicate.not(ZipEntry::isDirectory)).map(ZipEntry::getName)
+                           .filter(name -> name.startsWith(dirLocation))
+                           .map(name -> name.substring(name.lastIndexOf("/") + 1, name.lastIndexOf("."))).toList();
+        } catch (IOException e) {
+            logger.warn("Error in listing the files from csar", e);
+        }
+        return List.of();
+    }
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/PrimeOrder.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/PrimeOrder.java
new file mode 100755 (executable)
index 0000000..9ad0d36
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rapp;
+
+public enum PrimeOrder {
+    PRIME, DEPRIME;
+}
\ No newline at end of file
  * ============LICENSE_END========================================================================
  */
 
-package com.oransc.rappmanager.models;
+package com.oransc.rappmanager.models.rapp;
 
 
-import java.util.ArrayList;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import lombok.Builder;
 import lombok.Data;
-import lombok.Getter;
 
 @Data
 @Builder(toBuilder = true)
@@ -38,14 +36,9 @@ public class Rapp {
     RappState state;
     String packageLocation;
     String packageName;
-    UUID compositionId;
-    UUID compositionInstanceId;
-    String smeApfId;
-    String smeAefId;
-    @Builder.Default
-    Map<String, String> smeProviderFunctions = new HashMap<>();
-    @Builder.Default
-    List<String> smeServiceApis = new ArrayList<>();
+    RappResources rappResources;
     @Builder.Default
-    List<String> smeInvokers = new ArrayList<>();
+    Map<UUID, RappInstance> rappInstances = new HashMap<>();
+
+    UUID compositionId;
 }
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappEvent.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappEvent.java
new file mode 100755 (executable)
index 0000000..1bdc67d
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rapp;
+
+public enum RappEvent {
+    DEPLOYING,
+    ACMDEPLOYED,
+    SMEDEPLOYED,
+    ACMDEPLOYFAILED,
+    SMEDEPLOYFAILED,
+    UNDEPLOYING,
+    ACMUNDEPLOYED,
+    SMEUNDEPLOYED,
+    ACMUNDEPLOYFAILED,
+    SMEUNDEPLOYFAILED
+}
  * ============LICENSE_END========================================================================
  */
 
-package com.oransc.rappmanager.exception;
+package com.oransc.rappmanager.models.rapp;
 
-public class ACMInvalidStateTransitionException extends RuntimeException {
-    public ACMInvalidStateTransitionException() {
-        super();
-    }
+import com.oransc.rappmanager.models.rapp.PrimeOrder;
+import lombok.Data;
+
+@Data
+public class RappPrimeOrder {
+
+    PrimeOrder primeOrder;
 
-    public ACMInvalidStateTransitionException(String targetState, String actualState) {
-        super();
-    }
 }
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappResources.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rapp/RappResources.java
new file mode 100755 (executable)
index 0000000..4dd5e3a
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rapp;
+
+import java.util.List;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+public class RappResources {
+
+    public ACMResources acm;
+    public SMEResources sme;
+
+    @Data
+    @Builder
+    public static class ACMResources {
+
+        String compositionDefinitions;
+        List<String> compositionInstances;
+    }
+
+    @Data
+    @Builder
+    public static class SMEResources {
+
+        List<String> providerFunctions;
+        List<String> serviceApis;
+        List<String> invokers;
+    }
+}
@@ -16,8 +16,8 @@
  * ============LICENSE_END========================================================================
  */
 
-package com.oransc.rappmanager.models;
+package com.oransc.rappmanager.models.rapp;
 
 public enum RappState {
-    ONBOARDED, DEPLOYING, DEPLOYED, UNDEPLOYING, UNDEPLOYED, FAILED
+    COMMISSIONED, PRIMING, PRIMED, DEPRIMING,
 }
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/DeployOrder.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/DeployOrder.java
new file mode 100755 (executable)
index 0000000..5e838a1
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+public enum DeployOrder {
+    DEPLOY, UNDEPLOY;
+}
\ No newline at end of file
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappACMInstance.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappACMInstance.java
new file mode 100755 (executable)
index 0000000..e50bb86
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+import java.util.UUID;
+import lombok.Data;
+
+@Data
+public class RappACMInstance {
+
+    String instance;
+    UUID acmInstanceId;
+
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstance.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstance.java
new file mode 100755 (executable)
index 0000000..b5e54a7
--- /dev/null
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+import java.util.UUID;
+import lombok.Data;
+
+@Data
+public class RappInstance {
+
+    UUID rappInstanceId = UUID.randomUUID();
+    RappInstanceState state = RappInstanceState.UNDEPLOYED;
+    RappACMInstance acm;
+    RappSMEInstance sme;
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceDeployOrder.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceDeployOrder.java
new file mode 100755 (executable)
index 0000000..1dc9754
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+import lombok.Data;
+
+@Data
+public class RappInstanceDeployOrder {
+
+    DeployOrder deployOrder;
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceState.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappInstanceState.java
new file mode 100755 (executable)
index 0000000..cb5e6b1
--- /dev/null
@@ -0,0 +1,23 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+public enum RappInstanceState {
+    DEPLOYED, DEPLOYING, UNDEPLOYED, UNDEPLOYING;
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappSMEInstance.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/rappinstance/RappSMEInstance.java
new file mode 100755 (executable)
index 0000000..1ec24b3
--- /dev/null
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.rappinstance;
+
+import java.util.List;
+import lombok.Data;
+
+@Data
+public class RappSMEInstance {
+
+    String providerFunction;
+    List<String> providerFunctionIds;
+    String serviceApis;
+    List<String> serviceApiIds;
+    String invokers;
+    List<String> invokerIds;
+
+    String aefId;
+    String apfId;
+
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachine.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachine.java
new file mode 100755 (executable)
index 0000000..4e10ac0
--- /dev/null
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.statemachine;
+
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.statemachine.StateMachine;
+import org.springframework.statemachine.config.StateMachineFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class RappInstanceStateMachine {
+
+    Logger logger = LoggerFactory.getLogger(RappInstanceStateMachine.class);
+
+    private final StateMachineFactory<RappInstanceState, RappEvent> stateMachineFactory;
+    Map<UUID, StateMachine<RappInstanceState, RappEvent>> stateMachineMap = new HashMap<>();
+
+    public void onboardRappInstance(UUID rappInstanceId) {
+        StateMachine<RappInstanceState, RappEvent> stateMachine = stateMachineFactory.getStateMachine(rappInstanceId);
+        stateMachineMap.put(rappInstanceId, stateMachine);
+        stateMachine.start();
+    }
+
+    public void sendRappInstanceEvent(RappInstance rappInstance, RappEvent rappEvent) {
+        logger.info("Sending rapp instance event {} for {}", rappEvent.name(), rappInstance.getRappInstanceId());
+        logger.debug("State machine map is {}", stateMachineMap);
+        stateMachineMap.get(rappInstance.getRappInstanceId()).sendEvent(rappEvent);
+    }
+
+    public RappInstanceState getRappInstanceState(UUID rappInstanceId) {
+        return stateMachineMap.get(rappInstanceId).getState().getId();
+    }
+
+    public void deleteRappInstance(RappInstance rappInstance) {
+        stateMachineMap.get(rappInstance.getRappInstanceId()).stop();
+        stateMachineMap.remove(rappInstance.getRappInstanceId());
+    }
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfig.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfig.java
new file mode 100755 (executable)
index 0000000..e1bc784
--- /dev/null
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.statemachine;
+
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import java.util.EnumSet;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.statemachine.config.EnableStateMachineFactory;
+import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
+import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
+import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
+import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
+import org.springframework.statemachine.guard.Guard;
+
+@Configuration
+@EnableStateMachineFactory
+public class RappInstanceStateMachineConfig extends EnumStateMachineConfigurerAdapter<RappInstanceState, RappEvent> {
+
+    @Override
+    public void configure(StateMachineStateConfigurer<RappInstanceState, RappEvent> states) throws Exception {
+        states.withStates().initial(RappInstanceState.UNDEPLOYED).states(EnumSet.allOf(RappInstanceState.class));
+    }
+
+    @Override
+    public void configure(StateMachineConfigurationConfigurer<RappInstanceState, RappEvent> config) throws Exception {
+        config.withConfiguration();
+    }
+
+    // @formatter:off
+    @Override
+    public void configure(StateMachineTransitionConfigurer<RappInstanceState, RappEvent> transitions) throws Exception {
+        transitions
+                .withExternal()
+                    .source(RappInstanceState.UNDEPLOYED).target(RappInstanceState.DEPLOYING).event(RappEvent.DEPLOYING)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.DEPLOYING).target(RappInstanceState.UNDEPLOYED).event(RappEvent.ACMDEPLOYFAILED)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.DEPLOYING).target(RappInstanceState.UNDEPLOYED).event(RappEvent.SMEDEPLOYFAILED)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.UNDEPLOYING).target(RappInstanceState.DEPLOYED).event(RappEvent.ACMUNDEPLOYFAILED)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.UNDEPLOYING).target(RappInstanceState.DEPLOYED).event(RappEvent.SMEUNDEPLOYFAILED)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.DEPLOYED).target(RappInstanceState.UNDEPLOYING).event(RappEvent.UNDEPLOYING)
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.DEPLOYING).target(RappInstanceState.DEPLOYED).event(RappEvent.ACMDEPLOYED)
+                    .guard(deployedGuard())
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.DEPLOYING).target(RappInstanceState.DEPLOYED).event(RappEvent.SMEDEPLOYED)
+                    .guard(deployedGuard())
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.UNDEPLOYING).target(RappInstanceState.UNDEPLOYED).event(RappEvent.ACMUNDEPLOYED)
+                    .guard(undeployedGuard())
+                    .and()
+                .withExternal()
+                    .source(RappInstanceState.UNDEPLOYING).target(RappInstanceState.UNDEPLOYED).event(RappEvent.SMEUNDEPLOYED)
+                    .guard(undeployedGuard());
+
+    }
+    // @formatter:on
+
+    @Bean
+    public Guard<RappInstanceState, RappEvent> deployedGuard() {
+        return stateContext -> {
+            stateContext.getExtendedState().getVariables().put(stateContext.getEvent(), true);
+            return stateContext.getExtendedState().getVariables().get(RappEvent.ACMDEPLOYED) != null
+                           && stateContext.getExtendedState().getVariables().get(RappEvent.SMEDEPLOYED) != null;
+        };
+    }
+
+    @Bean
+    public Guard<RappInstanceState, RappEvent> undeployedGuard() {
+        return stateContext -> {
+            stateContext.getExtendedState().getVariables().put(stateContext.getEvent(), true);
+            return stateContext.getExtendedState().getVariables().get(RappEvent.ACMUNDEPLOYED) != null
+                           && stateContext.getExtendedState().getVariables().get(RappEvent.SMEUNDEPLOYED) != null;
+        };
+    }
+}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachine.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachine.java
deleted file mode 100755 (executable)
index fcd6ed3..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.oransc.rappmanager.models.statemachine;
-
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import lombok.RequiredArgsConstructor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.statemachine.StateMachine;
-import org.springframework.statemachine.config.StateMachineFactory;
-import org.springframework.stereotype.Service;
-
-@Service
-@RequiredArgsConstructor
-public class RappStateMachine {
-
-    Logger logger = LoggerFactory.getLogger(RappStateMachine.class);
-
-    private final StateMachineFactory<RappState, RappEvent> stateMachineFactory;
-    private Map<UUID, StateMachine<RappState, RappEvent>> stateMachineMap = new HashMap<>();
-
-    public void onboardRapp(UUID rappId) {
-        StateMachine<RappState, RappEvent> stateMachine = stateMachineFactory.getStateMachine(rappId);
-        stateMachineMap.put(rappId, stateMachine);
-        stateMachine.start();
-    }
-
-    public void sendRappEvent(Rapp rapp, RappEvent rappEvent) {
-        logger.info("Sending rapp event {} for {}", rappEvent.name(), rapp.getRappId());
-        logger.info("State machine map is {}", stateMachineMap);
-        stateMachineMap.get(rapp.getRappId()).sendEvent(rappEvent);
-    }
-
-    public RappState getRappState(UUID rappId) {
-        return stateMachineMap.get(rappId).getState().getId();
-    }
-
-    public void deleteRapp(Rapp rapp) {
-        stateMachineMap.get(rapp.getRappId()).stop();
-    }
-}
diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachineConfig.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/statemachine/RappStateMachineConfig.java
deleted file mode 100755 (executable)
index 4d7e486..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.oransc.rappmanager.models.statemachine;
-
-import com.oransc.rappmanager.models.RappEvent;
-import com.oransc.rappmanager.models.RappState;
-import java.util.EnumSet;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.statemachine.config.EnableStateMachineFactory;
-import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
-import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
-import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
-import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
-import org.springframework.statemachine.guard.Guard;
-
-@Configuration
-@EnableStateMachineFactory
-public class RappStateMachineConfig extends EnumStateMachineConfigurerAdapter<RappState, RappEvent> {
-
-    @Override
-    public void configure(StateMachineStateConfigurer<RappState, RappEvent> states) throws Exception {
-        states.withStates().initial(RappState.ONBOARDED).states(EnumSet.allOf(RappState.class));
-    }
-
-    @Override
-    public void configure(StateMachineConfigurationConfigurer<RappState, RappEvent> config) throws Exception {
-        config.withConfiguration();
-    }
-
-    // @formatter:off
-    @Override
-    public void configure(StateMachineTransitionConfigurer<RappState, RappEvent> transitions) throws Exception {
-        transitions
-                .withExternal()
-                    .source(RappState.ONBOARDED).target(RappState.DEPLOYING).event(RappEvent.DEPLOYING)
-                    .and()
-                .withExternal()
-                    .source(RappState.DEPLOYING).target(RappState.FAILED).event(RappEvent.ACMDEPLOYFAILED)
-                    .and()
-                .withExternal()
-                    .source(RappState.DEPLOYING).target(RappState.FAILED).event(RappEvent.SMEDEPLOYFAILED)
-                    .and()
-                .withExternal()
-                    .source(RappState.UNDEPLOYING).target(RappState.FAILED).event(RappEvent.ACMUNDEPLOYFAILED)
-                    .and()
-                .withExternal()
-                    .source(RappState.UNDEPLOYING).target(RappState.FAILED).event(RappEvent.SMEUNDEPLOYFAILED)
-                    .and()
-                .withExternal()
-                    .source(RappState.DEPLOYED).target(RappState.UNDEPLOYING).event(RappEvent.UNDEPLOYING)
-                    .and()
-                .withExternal()
-                    .source(RappState.DEPLOYING).target(RappState.DEPLOYED).event(RappEvent.ACMDEPLOYED)
-                    .guard(deployedGuard())
-                    .and()
-                .withExternal()
-                    .source(RappState.DEPLOYING).target(RappState.DEPLOYED).event(RappEvent.SMEDEPLOYED)
-                    .guard(deployedGuard())
-                    .and()
-                .withExternal()
-                    .source(RappState.UNDEPLOYING).target(RappState.UNDEPLOYED).event(RappEvent.ACMUNDEPLOYED)
-                    .guard(undeployedGuard())
-                    .and()
-                .withExternal()
-                    .source(RappState.UNDEPLOYING).target(RappState.UNDEPLOYED).event(RappEvent.SMEUNDEPLOYED)
-                    .guard(undeployedGuard());
-
-    }
-    // @formatter:on
-
-    @Bean
-    public Guard<RappState, RappEvent> deployedGuard() {
-        return stateContext -> {
-            stateContext.getExtendedState().getVariables().put(stateContext.getEvent(), true);
-            return stateContext.getExtendedState().getVariables().get(RappEvent.ACMDEPLOYED) != null
-                           && stateContext.getExtendedState().getVariables().get(RappEvent.SMEDEPLOYED) != null;
-        };
-    }
-
-    @Bean
-    public Guard<RappState, RappEvent> undeployedGuard() {
-        return stateContext -> {
-            stateContext.getExtendedState().getVariables().put(stateContext.getEvent(), true);
-            return stateContext.getExtendedState().getVariables().get(RappEvent.ACMUNDEPLOYED) != null
-                           && stateContext.getExtendedState().getVariables().get(RappEvent.SMEUNDEPLOYED) != null;
-        };
-    }
-}
diff --git a/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandlerTest.java b/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandlerTest.java
new file mode 100755 (executable)
index 0000000..10f5d96
--- /dev/null
@@ -0,0 +1,191 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.csar;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.rapp.RappResources;
+import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
+import com.oransc.rappmanager.models.rappinstance.RappSMEInstance;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+import org.apache.http.entity.ContentType;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.web.multipart.MultipartFile;
+
+@SpringBootTest
+@ContextConfiguration(classes = RappCsarConfigurationHandler.class)
+public class RappCsarConfigurationHandlerTest {
+
+    @Autowired
+    RappCsarConfigurationHandler rappCsarConfigurationHandler;
+
+    String validCsarFileLocation = "src/test/resources/";
+
+
+    private final String validRappFile = "valid-rapp-package.csar";
+
+    private final String invalidRappFile = "invalid-rapp-package.csar";
+
+    @Test
+    void testCsarPackageValidationSuccess() throws IOException {
+        String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
+        MultipartFile multipartFile =
+                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        assertEquals(Boolean.TRUE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
+    }
+
+    @Test
+    void testCsarPackageValidationFailure() throws IOException {
+        String rappCsarPath = validCsarFileLocation + File.separator + invalidRappFile;
+        MultipartFile multipartFile =
+                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
+    }
+
+    @Test
+    void testCsarInstantiationPayload() throws JSONException {
+        Rapp rapp = Rapp.builder().name("").packageName(validRappFile).packageLocation(validCsarFileLocation).build();
+        UUID compositionId = UUID.randomUUID();
+        RappACMInstance rappACMInstance = new RappACMInstance();
+        rappACMInstance.setInstance("kserve-instance");
+        JSONObject jsonObject = new JSONObject(
+                rappCsarConfigurationHandler.getInstantiationPayload(rapp, rappACMInstance, compositionId));
+        assertEquals(jsonObject.get("compositionId"), String.valueOf(compositionId));
+    }
+
+    @Test
+    void testFileListing() {
+        File file = new File(validCsarFileLocation + validRappFile);
+        List<String> fileListFromCsar =
+                rappCsarConfigurationHandler.getFileListFromCsar(file, "Files/Sme/serviceapis/");
+        assertThat(fileListFromCsar.size()).isEqualTo(2);
+    }
+
+    @Test
+    void testInvalidFileListing() {
+        File file = new File(validCsarFileLocation);
+        List<String> fileListFromCsar = rappCsarConfigurationHandler.getFileListFromCsar(file, null);
+        assertThat(fileListFromCsar.size()).isEqualTo(0);
+    }
+
+    @Test
+    void testListResources() {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .build();
+        RappResources rappResources = rappCsarConfigurationHandler.getRappResource(rapp);
+        assertThat(rappResources).isNotNull();
+        assertNotNull(rappResources.getAcm().getCompositionDefinitions());
+        assertThat(rappResources.getAcm().getCompositionInstances().size()).isEqualTo(3);
+        assertThat(rappResources.getSme().getProviderFunctions().size()).isEqualTo(4);
+        assertThat(rappResources.getSme().getServiceApis().size()).isEqualTo(2);
+        assertThat(rappResources.getSme().getInvokers().size()).isEqualTo(2);
+    }
+
+    @Test
+    void testListInvalidResources() {
+        UUID rappId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().rappId(rappId).name("").build();
+        RappResources rappResources = rappCsarConfigurationHandler.getRappResource(rapp);
+        assertThat(rappResources).isNotNull();
+        assertNull(rappResources.getAcm());
+        assertNull(rappResources.getSme());
+    }
+
+    @Test
+    void testGetAcmCompositionPayload() {
+        UUID rappId = UUID.randomUUID();
+        RappResources rappResources = new RappResources();
+        rappResources.setAcm(RappResources.ACMResources.builder().compositionDefinitions("compositions")
+                                     .compositionInstances(List.of()).build());
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .rappResources(rappResources).build();
+        String acmCompositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
+        assertNotNull(acmCompositionPayload);
+    }
+
+    @Test
+    void testGetInvalidAcmCompositionPayload() {
+        UUID rappId = UUID.randomUUID();
+        RappResources rappResources = new RappResources();
+        rappResources.setAcm(RappResources.ACMResources.builder().compositionDefinitions("invalidcomposition")
+                                     .compositionInstances(List.of()).build());
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .rappResources(rappResources).build();
+        String acmCompositionPayload = rappCsarConfigurationHandler.getAcmCompositionPayload(rapp);
+        assertEquals("", acmCompositionPayload);
+    }
+
+    @Test
+    void testGetSmeProviderDomainPayload() {
+        UUID rappId = UUID.randomUUID();
+        RappSMEInstance rappSMEInstance = new RappSMEInstance();
+        rappSMEInstance.setProviderFunction("aef-provider-function");
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .build();
+        String smeProviderDomainPayload =
+                rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappSMEInstance);
+        assertNotNull(smeProviderDomainPayload);
+    }
+
+    @Test
+    void testGetSmeServiceApiPayload() {
+        UUID rappId = UUID.randomUUID();
+        RappSMEInstance rappSMEInstance = new RappSMEInstance();
+        rappSMEInstance.setServiceApis("api-set-1");
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .build();
+        String smeProviderDomainPayload = rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappSMEInstance);
+        assertNotNull(smeProviderDomainPayload);
+    }
+
+    @Test
+    void testGetSmeInvokerPayload() {
+        UUID rappId = UUID.randomUUID();
+        RappSMEInstance rappSMEInstance = new RappSMEInstance();
+        rappSMEInstance.setServiceApis("invoker-app1");
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .build();
+        String smeProviderDomainPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappSMEInstance);
+        assertNotNull(smeProviderDomainPayload);
+    }
+
+}
diff --git a/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfigTest.java b/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineConfigTest.java
new file mode 100755 (executable)
index 0000000..1ab5481
--- /dev/null
@@ -0,0 +1,169 @@
+/*-
+ * ============LICENSE_START======================================================================
+ * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * ===============================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END========================================================================
+ */
+
+package com.oransc.rappmanager.models.statemachine;
+
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import java.util.UUID;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.statemachine.StateMachine;
+import org.springframework.statemachine.config.StateMachineFactory;
+import org.springframework.statemachine.test.StateMachineTestPlan;
+import org.springframework.statemachine.test.StateMachineTestPlanBuilder;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {RappInstanceStateMachineConfig.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+public class RappInstanceStateMachineConfigTest {
+
+    @Autowired
+    StateMachineFactory<RappInstanceState, RappEvent> stateMachineFactory;
+
+    StateMachine<RappInstanceState, RappEvent> stateMachine;
+
+    @BeforeEach
+    void getStateMachine() {
+        stateMachine = stateMachineFactory.getStateMachine(UUID.randomUUID());
+        stateMachine.startReactively().subscribe();
+    }
+
+    @AfterEach
+    void stopStateMachine() {
+        stateMachine.stopReactively().subscribe();
+    }
+
+    @Test
+    void testOnboardedState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().build();
+        plan.test();
+    }
+
+    @Test
+    void testDeployingState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().build();
+        plan.test();
+    }
+
+    @ParameterizedTest
+    @EnumSource(value = RappEvent.class, names = {"ACMDEPLOYED", "SMEDEPLOYED"})
+    void testIndividualDeployedState(RappEvent rappEvent) throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(rappEvent).expectState(RappInstanceState.DEPLOYING).and().build();
+        plan.test();
+    }
+
+    @Test
+    void testDeployedState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappInstanceState.DEPLOYED).expectStateChanged(1)
+                        .and().build();
+        plan.test();
+    }
+
+    @Test
+    void testDeployFailedState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYFAILED).expectState(RappInstanceState.UNDEPLOYED)
+                        .expectStateChanged(1).and().build();
+        plan.test();
+    }
+
+    @Test
+    void testUndeployingState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappInstanceState.DEPLOYED).expectStateChanged(1)
+                        .and().step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappInstanceState.UNDEPLOYING)
+                        .expectStateChanged(1).and().build();
+        plan.test();
+    }
+
+    @ParameterizedTest
+    @EnumSource(value = RappEvent.class, names = {"ACMUNDEPLOYED", "SMEUNDEPLOYED"})
+    void testIndividualUndeployedState(RappEvent rappEvent) throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappInstanceState.DEPLOYED).expectStateChanged(1)
+                        .and().step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappInstanceState.UNDEPLOYING)
+                        .expectStateChanged(1).and().step().sendEvent(rappEvent)
+                        .expectState(RappInstanceState.UNDEPLOYING).and().build();
+        plan.test();
+    }
+
+    @Test
+    void testUndeployedState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappInstanceState.DEPLOYED).expectStateChanged(1)
+                        .and().step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappInstanceState.UNDEPLOYING)
+                        .expectStateChanged(1).and().step().sendEvent(RappEvent.ACMUNDEPLOYED)
+                        .expectState(RappInstanceState.UNDEPLOYING).and().step().sendEvent(RappEvent.SMEUNDEPLOYED)
+                        .expectState(RappInstanceState.UNDEPLOYED).expectStateChanged(1).and().build();
+        plan.test();
+    }
+
+    @Test
+    void testUndeployFailedState() throws Exception {
+        StateMachineTestPlan plan =
+                StateMachineTestPlanBuilder.<RappInstanceState, RappEvent>builder().stateMachine(stateMachine).step()
+                        .expectState(RappInstanceState.UNDEPLOYED).and().step().sendEvent(RappEvent.DEPLOYING)
+                        .expectState(RappInstanceState.DEPLOYING).expectStateChanged(1).and().step()
+                        .sendEvent(RappEvent.ACMDEPLOYED).expectState(RappInstanceState.DEPLOYING).and().step()
+                        .sendEvent(RappEvent.SMEDEPLOYED).expectState(RappInstanceState.DEPLOYED).expectStateChanged(1)
+                        .and().step().sendEvent(RappEvent.UNDEPLOYING).expectState(RappInstanceState.UNDEPLOYING)
+                        .expectStateChanged(1).and().step().sendEvent(RappEvent.ACMUNDEPLOYED)
+                        .expectState(RappInstanceState.UNDEPLOYING).and().step().sendEvent(RappEvent.SMEUNDEPLOYFAILED)
+                        .expectState(RappInstanceState.DEPLOYED).expectStateChanged(1).and().build();
+        plan.test();
+    }
+}
diff --git a/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineTest.java b/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/statemachine/RappInstanceStateMachineTest.java
new file mode 100755 (executable)
index 0000000..db45d14
--- /dev/null
@@ -0,0 +1,61 @@
+package com.oransc.rappmanager.models.statemachine;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappInstanceState;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(classes = {RappInstanceStateMachine.class, RappInstanceStateMachineConfig.class})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
+public class RappInstanceStateMachineTest {
+
+    @Autowired
+    RappInstanceStateMachine rappInstanceStateMachine;
+
+    @Test
+    void testOnboardRappInstance() {
+        UUID rappInstanceId = UUID.randomUUID();
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        assertNotNull(rappInstanceStateMachine.stateMachineMap.get(rappInstanceId));
+    }
+
+    @Test
+    void testSendRappInstanceEvent() {
+        UUID rappInstanceId = UUID.randomUUID();
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        assertEquals(RappInstanceState.UNDEPLOYED, rappInstanceStateMachine.getRappInstanceState(rappInstanceId));
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setRappInstanceId(rappInstanceId);
+        rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING);
+        assertEquals(RappInstanceState.DEPLOYING, rappInstanceStateMachine.getRappInstanceState(rappInstanceId));
+    }
+
+    @Test
+    void testGetRappInstanceState() {
+        UUID rappInstanceId = UUID.randomUUID();
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        assertEquals(RappInstanceState.UNDEPLOYED, rappInstanceStateMachine.getRappInstanceState(rappInstanceId));
+    }
+
+    @Test
+    void testDeleteRappInstance() {
+        UUID rappInstanceId = UUID.randomUUID();
+        rappInstanceStateMachine.onboardRappInstance(rappInstanceId);
+        assertNotNull(rappInstanceStateMachine.stateMachineMap.get(rappInstanceId));
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setRappInstanceId(rappInstanceId);
+        rappInstanceStateMachine.deleteRappInstance(rappInstance);
+        assertNull(rappInstanceStateMachine.stateMachineMap.get(rappInstanceId));
+    }
+}
diff --git a/rapp-manager-models/src/test/resources/invalid-rapp-package.csar b/rapp-manager-models/src/test/resources/invalid-rapp-package.csar
new file mode 100755 (executable)
index 0000000..c9150f0
Binary files /dev/null and b/rapp-manager-models/src/test/resources/invalid-rapp-package.csar differ
diff --git a/rapp-manager-models/src/test/resources/valid-rapp-package.csar b/rapp-manager-models/src/test/resources/valid-rapp-package.csar
new file mode 100755 (executable)
index 0000000..b8b36e3
Binary files /dev/null and b/rapp-manager-models/src/test/resources/valid-rapp-package.csar differ
index cc607b2..ac7c97e 100755 (executable)
             <artifactId>jackson-databind-nullable</artifactId>
             <version>0.2.6</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>4.3.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 5901417..6a6581a 100755 (executable)
@@ -21,22 +21,21 @@ package com.oransc.rappmanager.sme.service;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappCsarConfigurationHandler;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
 import com.oransc.rappmanager.models.RappDeployer;
-import com.oransc.rappmanager.models.RappEvent;
+import com.oransc.rappmanager.models.rapp.RappEvent;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
 import com.oransc.rappmanager.models.cache.RappCacheService;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
 import com.oransc.rappmanager.sme.invoker.data.APIInvokerEnrolmentDetails;
 import com.oransc.rappmanager.sme.provider.data.APIProviderEnrolmentDetails;
 import com.oransc.rappmanager.sme.provider.data.APIProviderFunctionDetails;
 import com.oransc.rappmanager.sme.provider.data.ApiProviderFuncRole;
 import com.oransc.rappmanager.sme.provider.data.RegistrationInformation;
-import com.oransc.rappmanager.sme.publishservice.data.AefProfile;
 import com.oransc.rappmanager.sme.publishservice.data.ServiceAPIDescription;
 import java.util.List;
 import java.util.Optional;
-import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,7 +59,7 @@ public class SmeDeployer implements RappDeployer {
 
     private final RappCacheService rappCacheService;
 
-    private final RappStateMachine rappStateMachine;
+    private final RappInstanceStateMachine rappInstanceStateMachine;
 
     private String amfRegistrationId;
 
@@ -89,16 +88,17 @@ public class SmeDeployer implements RappDeployer {
         deleteProviderFunc(amfRegistrationId);
     }
 
-
     @Override
-    public boolean deployRapp(Rapp rapp) {
-        logger.debug("Deploying SME functions for Rapp {}", rapp.getName());
+    public boolean deployRappInstance(Rapp rapp, RappInstance rappInstance) {
+        logger.debug("Deploying SME functions for RappInstance {}", rappInstance.getRappInstanceId());
         try {
-            boolean deployState = createProviderDomain(rapp) && createPublishApi(rapp) && createInvoker(rapp);
+            boolean deployState =
+                    createProviderDomain(rapp, rappInstance) && createPublishApi(rapp, rappInstance) && createInvoker(
+                            rapp, rappInstance);
             if (deployState) {
-                rappStateMachine.sendRappEvent(rapp, RappEvent.SMEDEPLOYED);
+                rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYED);
             } else {
-                rappStateMachine.sendRappEvent(rapp, RappEvent.SMEDEPLOYFAILED);
+                rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEDEPLOYFAILED);
             }
             return deployState;
         } catch (JsonProcessingException e) {
@@ -108,40 +108,60 @@ public class SmeDeployer implements RappDeployer {
     }
 
     @Override
-    public boolean undeployRapp(Rapp rapp) {
+    public boolean undeployRappInstance(Rapp rapp, RappInstance rappInstance) {
         logger.debug("Undeploying SME functions for Rapp {}", rapp.getName());
         try {
-            rapp.getSmeInvokers().forEach(this::deleteInvoker);
-            rapp.getSmeServiceApis().forEach(s -> deletePublishApi(s, rapp.getSmeApfId()));
-            rapp.getSmeProviderFunctions().values().forEach(this::deleteProviderFunc);
-            rappStateMachine.sendRappEvent(rapp, RappEvent.SMEUNDEPLOYED);
+            rappInstance.getSme().getInvokerIds().forEach(this::deleteInvoker);
+            rappInstance.getSme().getServiceApiIds()
+                    .forEach(s -> deletePublishApi(s, rappInstance.getSme().getApfId()));
+            rappInstance.getSme().getProviderFunctionIds().forEach(this::deleteProviderFunc);
+            rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.SMEUNDEPLOYED);
             return true;
         } catch (Exception e) {
-            logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName());
+            logger.warn("Failed to Undeploy SME functions for Rapp {}", rapp.getName(), e);
         }
         return false;
     }
 
-    boolean createProviderDomain(Rapp rapp) throws JsonProcessingException {
+    @Override
+    public boolean primeRapp(Rapp rapp) {
+        //If there is any priming operations on SME
+        return true;
+    }
+
+    @Override
+    public boolean deprimeRapp(Rapp rapp) {
+        //If there is any deprimgng operations
+        return true;
+    }
+
+    boolean createProviderDomain(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
         try {
-            String providerDomainPayload = rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp);
+            String providerDomainPayload =
+                    rappCsarConfigurationHandler.getSmeProviderDomainPayload(rapp, rappInstance.getSme());
+            logger.info("provider domain payload " + providerDomainPayload);
             if (providerDomainPayload != null) {
                 APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
                         objectMapper.readValue(providerDomainPayload, APIProviderEnrolmentDetails.class);
+                //TODO Fix this Temporary workaround
+                apiProviderEnrolmentDetails.setRegSec(
+                        apiProviderEnrolmentDetails.getRegSec() + rappInstance.getRappInstanceId());
                 APIProviderEnrolmentDetails responseApiEnrollmentDetails =
                         providerDefaultApiClient.postRegistrations(apiProviderEnrolmentDetails);
                 if (responseApiEnrollmentDetails.getApiProvFuncs() != null) {
+                    rappInstance.getSme().setProviderFunctionIds(responseApiEnrollmentDetails.getApiProvFuncs().stream()
+                                                                         .map(APIProviderFunctionDetails::getApiProvFuncId)
+                                                                         .toList());
+
                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
-                            ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rapp.setSmeApfId(
-                            apiProviderFunctionDetails.getApiProvFuncId()));
+                            ApiProviderFuncRole.APF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
+                                                                                                     .setApfId(
+                                                                                                             apiProviderFunctionDetails.getApiProvFuncId()));
                     getProviderFuncId(responseApiEnrollmentDetails.getApiProvFuncs(),
-                            ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rapp.setSmeAefId(
-                            apiProviderFunctionDetails.getApiProvFuncId()));
-                    rapp.setSmeProviderFunctions(responseApiEnrollmentDetails.getApiProvFuncs().stream().collect(
-                            Collectors.toMap(APIProviderFunctionDetails::getApiProvFuncInfo,
-                                    APIProviderFunctionDetails::getApiProvFuncId)));
-                    rappCacheService.putRapp(rapp);
+                            ApiProviderFuncRole.AEF).ifPresent(apiProviderFunctionDetails -> rappInstance.getSme()
+                                                                                                     .setAefId(
+                                                                                                             apiProviderFunctionDetails.getApiProvFuncId()));
                     return true;
                 }
             }
@@ -163,24 +183,23 @@ public class SmeDeployer implements RappDeployer {
     }
 
 
-    boolean createPublishApi(Rapp rapp) throws JsonProcessingException {
+    boolean createPublishApi(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
         logger.debug("Creating publish api for Rapp {}", rapp.getName());
         try {
-            String providerApiPayload = rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp);
+            String providerApiPayload =
+                    rappCsarConfigurationHandler.getSmeProviderApiPayload(rapp, rappInstance.getSme());
             if (providerApiPayload != null) {
                 ServiceAPIDescription serviceAPIDescription =
                         objectMapper.readValue(providerApiPayload, ServiceAPIDescription.class);
                 serviceAPIDescription.getAefProfiles().forEach(aefProfile -> {
-                    aefProfile.setAefId(rapp.getSmeProviderFunctions().get(aefProfile.getAefId()));
+                    aefProfile.setAefId(rappInstance.getSme().getAefId());
                 });
                 ServiceAPIDescription serviceAPIDescriptionResponse =
-                        publishServiceDefaultApiClient.postApfIdServiceApis(rapp.getSmeApfId(), serviceAPIDescription);
+                        publishServiceDefaultApiClient.postApfIdServiceApis(rappInstance.getSme().getApfId(),
+                                serviceAPIDescription);
 
                 if (serviceAPIDescriptionResponse.getAefProfiles() != null) {
-                    rapp.setSmeServiceApis(
-                            serviceAPIDescriptionResponse.getAefProfiles().stream().map(AefProfile::getAefId)
-                                    .collect(Collectors.toList()));
-                    rappCacheService.putRapp(rapp);
+                    rappInstance.getSme().setServiceApiIds(List.of(serviceAPIDescriptionResponse.getApiId()));
                     return true;
                 }
             }
@@ -194,10 +213,10 @@ public class SmeDeployer implements RappDeployer {
         publishServiceDefaultApiClient.deleteApfIdServiceApisServiceApiId(serviceApiId, apfId);
     }
 
-    boolean createInvoker(Rapp rapp) throws JsonProcessingException {
+    boolean createInvoker(Rapp rapp, RappInstance rappInstance) throws JsonProcessingException {
         logger.debug("Creating provider domain for Rapp {}", rapp.getName());
         try {
-            String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp);
+            String invokerPayload = rappCsarConfigurationHandler.getSmeInvokerPayload(rapp, rappInstance.getSme());
             if (invokerPayload != null) {
                 List<APIInvokerEnrolmentDetails> apiInvokerEnrolmentDetails =
                         objectMapper.readValue(invokerPayload, new TypeReference<>() { });
@@ -205,10 +224,8 @@ public class SmeDeployer implements RappDeployer {
                     APIInvokerEnrolmentDetails apiInvokerEnrolmentDetailsResponse =
                             invokerDefaultApiClient.postOnboardedInvokers(apiInvokerEnrolmentDetail);
                     if (apiInvokerEnrolmentDetailsResponse.getApiList() != null) {
-                        rapp.getSmeInvokers().addAll(apiInvokerEnrolmentDetailsResponse.getApiList().stream()
-                                                             .map(com.oransc.rappmanager.sme.invoker.data.ServiceAPIDescription::getApiId)
-                                                             .toList());
-                        rappCacheService.putRapp(rapp);
+                        rappInstance.getSme()
+                                .setInvokerIds(List.of(apiInvokerEnrolmentDetailsResponse.getApiInvokerId()));
                     }
                 });
                 return true;
index 0c21c1b..cb5b049 100755 (executable)
@@ -41,7 +41,7 @@ public class SmeLifecycleManager implements SmartLifecycle {
             APIProviderEnrolmentDetails providerServiceAMF = smeDeployer.createAMF();
             logger.info("Rapp Manager AMF Registration Id: " + providerServiceAMF.getApiProvDomId());
             running = true;
-        }catch (Exception e){
+        } catch (Exception e) {
             logger.warn("Error in initializing AMF", e);
             running = false;
         }
diff --git a/rapp-manager-sme/src/test/java/com/oransc/rappmanager/sme/service/BeanTestConfiguration.java b/rapp-manager-sme/src/test/java/com/oransc/rappmanager/sme/service/BeanTestConfiguration.java
new file mode 100755 (executable)
index 0000000..191ed07
--- /dev/null
@@ -0,0 +1,79 @@
+package com.oransc.rappmanager.sme.service;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.sme.configuration.SmeConfiguration;
+import com.oransc.rappmanager.sme.provider.rest.DefaultApiClient;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+@TestConfiguration
+@RequiredArgsConstructor
+public class BeanTestConfiguration {
+
+    private final SmeConfiguration smeConfiguration;
+
+    @Bean
+    public ObjectMapper objectMapper() {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        return objectMapper;
+    }
+
+    @Bean
+    public RestTemplateBuilder restTemplateBuilder() {
+        return new RestTemplateBuilder();
+    }
+
+    @Bean
+    public CacheManager cacheManager() {
+        return new ConcurrentMapCacheManager(); // or any other CacheManager implementation you want to use in the test
+    }
+
+    @Bean
+    public RestTemplate restTemplate(RestTemplateBuilder builder) {
+        return builder.build();
+    }
+
+    @Bean("smeProviderApiClient")
+    public com.oransc.rappmanager.sme.provider.ApiClient smeProviderApiClient(RestTemplate restTemplate) {
+        return new com.oransc.rappmanager.sme.provider.ApiClient(restTemplate);
+    }
+
+    @Bean("smePublishServiceApiClient")
+    public com.oransc.rappmanager.sme.publishservice.ApiClient smePublishServiceApiClient(RestTemplate restTemplate) {
+        return new com.oransc.rappmanager.sme.publishservice.ApiClient(restTemplate);
+    }
+
+    @Bean("smeInvokerApiClient")
+    public com.oransc.rappmanager.sme.invoker.ApiClient smeInvokerApiClient(RestTemplate restTemplate) {
+        return new com.oransc.rappmanager.sme.invoker.ApiClient(restTemplate);
+    }
+
+    @Bean
+    public DefaultApiClient defaultProviderApiClient(
+            @Qualifier("smeProviderApiClient") com.oransc.rappmanager.sme.provider.ApiClient apiClient) {
+        apiClient.setBasePath(smeConfiguration.getBaseUrl() + smeConfiguration.getProviderBasePath());
+        return new DefaultApiClient(apiClient);
+    }
+
+    @Bean
+    public com.oransc.rappmanager.sme.publishservice.rest.DefaultApiClient defaultPublishServiceApiClient(
+            @Qualifier("smePublishServiceApiClient") com.oransc.rappmanager.sme.publishservice.ApiClient apiClient) {
+        apiClient.setBasePath(smeConfiguration.getBaseUrl() + smeConfiguration.getPublishApiBasePath());
+        return new com.oransc.rappmanager.sme.publishservice.rest.DefaultApiClient(apiClient);
+    }
+
+    @Bean
+    public com.oransc.rappmanager.sme.invoker.rest.DefaultApiClient defaultInvokerApiClient(
+            @Qualifier("smeInvokerApiClient") com.oransc.rappmanager.sme.invoker.ApiClient apiClient) {
+        apiClient.setBasePath(smeConfiguration.getBaseUrl() + smeConfiguration.getInvokerBasePath());
+        return new com.oransc.rappmanager.sme.invoker.rest.DefaultApiClient(apiClient);
+    }
+}
@@ -25,15 +25,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.oransc.rappmanager.configuration.RappManagerConfiguration;
-import com.oransc.rappmanager.models.Rapp;
-import com.oransc.rappmanager.models.RappState;
+import com.oransc.rappmanager.models.rapp.Rapp;
+import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
+import com.oransc.rappmanager.models.rappinstance.RappInstance;
+import com.oransc.rappmanager.models.rappinstance.RappSMEInstance;
+import com.oransc.rappmanager.models.rapp.RappState;
 import com.oransc.rappmanager.models.cache.RappCacheService;
-import com.oransc.rappmanager.models.statemachine.RappStateMachine;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
+import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachineConfig;
 import com.oransc.rappmanager.sme.configuration.SmeConfiguration;
 import com.oransc.rappmanager.sme.invoker.data.APIInvokerEnrolmentDetails;
 import com.oransc.rappmanager.sme.provider.data.APIProviderEnrolmentDetails;
@@ -41,12 +43,9 @@ import com.oransc.rappmanager.sme.provider.data.APIProviderFunctionDetails;
 import com.oransc.rappmanager.sme.provider.data.ApiProviderFuncRole;
 import com.oransc.rappmanager.sme.publishservice.data.AefProfile;
 import com.oransc.rappmanager.sme.publishservice.data.ServiceAPIDescription;
-import java.io.File;
-import java.io.FileInputStream;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import org.apache.http.entity.ContentType;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -58,37 +57,33 @@ import org.springframework.boot.test.mock.mockito.SpyBean;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.test.context.TestPropertySource;
 import org.springframework.test.web.client.ExpectedCount;
 import org.springframework.test.web.client.MockRestServiceServer;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 import org.springframework.web.client.RestTemplate;
 
-@SpringBootTest
-@TestPropertySource(properties = "rappmanager.csarlocation=src/test/resources")
+@SpringBootTest(classes = {SmeConfiguration.class, SmeDeployer.class, BeanTestConfiguration.class,
+        RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
+        RappInstanceStateMachine.class})
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 @AutoConfigureMockMvc
 public class SmeDeployerTest {
 
     MockRestServiceServer mockServer;
+    @Autowired
     @SpyBean
     SmeDeployer smeDeployer;
     @Autowired
     RestTemplate restTemplate;
     @Autowired
     SmeConfiguration smeConfiguration;
+    String validCsarFileLocation = "src/test/resources/";
     @Autowired
-    RappManagerConfiguration rappManagerConfiguration;
-    @Autowired
-    private MockMvc mockMvc;
+    RappInstanceStateMachine rappInstanceStateMachine;
     @Autowired
     RappCacheService rappCacheService;
-    @SpyBean
-    RappStateMachine rappStateMachine;
+    @Autowired
+    ObjectMapper objectMapper;
     private final String validRappFile = "valid-rapp-package.csar";
-    ObjectMapper objectMapper = new ObjectMapper();
     String URI_PROVIDER_REGISTRATIONS, URI_PROVIDER_REGISTRATION, URI_PUBLISH_APIS, URI_PUBLISH_API, URI_INVOKERS,
             URI_INVOKER;
 
@@ -150,16 +145,16 @@ public class SmeDeployerTest {
     @Test
     void testCreateProviderDomain() throws Exception {
         UUID rappId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         APIProviderEnrolmentDetails apiProviderEnrolmentDetails = getProviderDomainApiEnrollmentDetails();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_PROVIDER_REGISTRATIONS))
                 .andExpect(method(HttpMethod.POST)).andRespond(
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
                                 .body(objectMapper.writeValueAsString(apiProviderEnrolmentDetails)));
-        boolean createProviderDomain = smeDeployer.createProviderDomain(rapp);
+        RappInstance rappInstance = getRappInstance();
+        boolean createProviderDomain = smeDeployer.createProviderDomain(rapp, rappInstance);
         mockServer.verify();
         assertTrue(createProviderDomain);
     }
@@ -167,13 +162,13 @@ public class SmeDeployerTest {
     @Test
     void testCreateProviderDomainFailure() throws Exception {
         UUID rappId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_PROVIDER_REGISTRATIONS))
                 .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
-        boolean createProviderDomain = smeDeployer.createProviderDomain(rapp);
+        RappInstance rappInstance = getRappInstance();
+        boolean createProviderDomain = smeDeployer.createProviderDomain(rapp, rappInstance);
         mockServer.verify();
         assertFalse(createProviderDomain);
     }
@@ -191,16 +186,17 @@ public class SmeDeployerTest {
     void testCreatePublishApi() throws Exception {
         UUID rappId = UUID.randomUUID();
         UUID apfId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         ServiceAPIDescription serviceAPIDescription = getServiceApiDescription();
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_PUBLISH_APIS, apfId)))
                 .andExpect(method(HttpMethod.POST)).andRespond(
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
                                 .body(objectMapper.writeValueAsString(serviceAPIDescription)));
-        boolean publishApi = smeDeployer.createPublishApi(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstance.getSme().setApfId(String.valueOf(apfId));
+        boolean publishApi = smeDeployer.createPublishApi(rapp, rappInstance);
         mockServer.verify();
         assertTrue(publishApi);
     }
@@ -210,13 +206,14 @@ public class SmeDeployerTest {
     void testCreatePublishApiFailure() throws Exception {
         UUID rappId = UUID.randomUUID();
         UUID apfId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_PUBLISH_APIS, apfId)))
                 .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
-        boolean publishApi = smeDeployer.createPublishApi(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstance.getSme().setApfId(String.valueOf(apfId));
+        boolean publishApi = smeDeployer.createPublishApi(rapp, rappInstance);
         mockServer.verify();
         assertFalse(publishApi);
     }
@@ -234,16 +231,15 @@ public class SmeDeployerTest {
     @Test
     void testCreateInvoker() throws Exception {
         UUID rappId = UUID.randomUUID();
-        UUID apfId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         APIInvokerEnrolmentDetails apiInvokerEnrolmentDetails = getApiInvokerEnrollmentDetails();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_INVOKERS)).andExpect(method(HttpMethod.POST)).andRespond(
                 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
                         .body(objectMapper.writeValueAsString(apiInvokerEnrolmentDetails)));
-        boolean createInvoker = smeDeployer.createInvoker(rapp);
+        RappInstance rappInstance = getRappInstance();
+        boolean createInvoker = smeDeployer.createInvoker(rapp, rappInstance);
         mockServer.verify();
         assertTrue(createInvoker);
     }
@@ -251,14 +247,13 @@ public class SmeDeployerTest {
     @Test
     void testCreateInvokerFailure() throws Exception {
         UUID rappId = UUID.randomUUID();
-        UUID apfId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).build();
-        onBoardRappCsar(rappId);
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_INVOKERS)).andExpect(method(HttpMethod.POST))
                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
-        boolean createInvoker = smeDeployer.createInvoker(rapp);
+        RappInstance rappInstance = getRappInstance();
+        boolean createInvoker = smeDeployer.createInvoker(rapp, rappInstance);
         mockServer.verify();
         assertFalse(createInvoker);
     }
@@ -273,15 +268,16 @@ public class SmeDeployerTest {
     }
 
     @Test
-    void testDeployRapp() throws Exception {
+    void testDeployRappInstance() throws Exception {
         UUID rappId = UUID.randomUUID();
         APIProviderEnrolmentDetails apiProviderEnrolmentDetails = getProviderDomainApiEnrollmentDetails();
         APIProviderFunctionDetails apfProviderFunctionDetails = apiProviderEnrolmentDetails.getApiProvFuncs().stream()
                                                                         .filter(apiProviderFunctionDetails -> apiProviderFunctionDetails.getApiProvFuncRole()
                                                                                                                       .equals(ApiProviderFuncRole.APF))
                                                                         .findFirst().get();
-        onBoardRappCsar(rappId);
-        Rapp rapp = rappCacheService.getRapp(String.valueOf(rappId)).get();
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_PROVIDER_REGISTRATIONS))
                 .andExpect(method(HttpMethod.POST)).andRespond(
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
@@ -296,7 +292,9 @@ public class SmeDeployerTest {
         mockServer.expect(ExpectedCount.once(), requestTo(URI_INVOKERS)).andExpect(method(HttpMethod.POST)).andRespond(
                 withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
                         .body(objectMapper.writeValueAsString(apiInvokerEnrolmentDetails)));
-        boolean deployRapp = smeDeployer.deployRapp(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean deployRapp = smeDeployer.deployRappInstance(rapp, rappInstance);
         mockServer.verify();
         assertTrue(deployRapp);
     }
@@ -309,8 +307,9 @@ public class SmeDeployerTest {
                                                                         .filter(apiProviderFunctionDetails -> apiProviderFunctionDetails.getApiProvFuncRole()
                                                                                                                       .equals(ApiProviderFuncRole.APF))
                                                                         .findFirst().get();
-        onBoardRappCsar(rappId);
-        Rapp rapp = rappCacheService.getRapp(String.valueOf(rappId)).get();
+        Rapp rapp =
+                Rapp.builder().rappId(rappId).name("").packageName(validRappFile).packageLocation(validCsarFileLocation)
+                        .state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(URI_PROVIDER_REGISTRATIONS))
                 .andExpect(method(HttpMethod.POST)).andRespond(
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
@@ -323,13 +322,15 @@ public class SmeDeployerTest {
                                 .body(objectMapper.writeValueAsString(serviceAPIDescription)));
         mockServer.expect(ExpectedCount.once(), requestTo(URI_INVOKERS)).andExpect(method(HttpMethod.POST))
                 .andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
-        boolean deployRapp = smeDeployer.deployRapp(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean deployRapp = smeDeployer.deployRappInstance(rapp, rappInstance);
         mockServer.verify();
         assertFalse(deployRapp);
     }
 
     @Test
-    void testUndeployRapp() throws Exception {
+    void testUndeployRappInstance() {
         UUID rappId = UUID.randomUUID();
         UUID apfId = UUID.randomUUID();
         List<String> invokers = List.of(String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()));
@@ -337,11 +338,7 @@ public class SmeDeployerTest {
         Map<String, String> providerFuncs = Map.of(String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()),
                 String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()));
         Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).smeInvokers(invokers).smeServiceApis(serviceApis)
-                            .smeProviderFunctions(providerFuncs).build();
-        onBoardRappCsar(rappId);
-        rapp.setRappId(rappCacheService.getRapp(String.valueOf(rappId)).get().getRappId());
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INVOKER, invokers.get(0))))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INVOKER, invokers.get(1))))
@@ -356,14 +353,19 @@ public class SmeDeployerTest {
         mockServer.expect(ExpectedCount.once(),
                         requestTo(String.format(URI_PROVIDER_REGISTRATION, providerFuncs.values().toArray()[1])))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
-
-        boolean undeployRapp = smeDeployer.undeployRapp(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstance.getSme().setApfId(String.valueOf(apfId));
+        rappInstance.getSme().setProviderFunctionIds(providerFuncs.values().stream().toList());
+        rappInstance.getSme().setServiceApiIds(serviceApis);
+        rappInstance.getSme().setInvokerIds(invokers);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean undeployRapp = smeDeployer.undeployRappInstance(rapp, rappInstance);
         mockServer.verify();
         assertTrue(undeployRapp);
     }
 
     @Test
-    void testUndeployRappFailure() throws Exception {
+    void testUndeployRappInstanceFailure() throws Exception {
         UUID rappId = UUID.randomUUID();
         UUID apfId = UUID.randomUUID();
         List<String> invokers = List.of(String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()));
@@ -371,10 +373,7 @@ public class SmeDeployerTest {
         Map<String, String> providerFuncs = Map.of(String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()),
                 String.valueOf(UUID.randomUUID()), String.valueOf(UUID.randomUUID()));
         Rapp rapp = Rapp.builder().rappId(rappId).name(rappId.toString()).packageName(validRappFile)
-                            .packageLocation(rappManagerConfiguration.getCsarLocation()).state(RappState.ONBOARDED)
-                            .smeApfId(String.valueOf(apfId)).smeInvokers(invokers).smeServiceApis(serviceApis)
-                            .smeProviderFunctions(providerFuncs).build();
-        onBoardRappCsar(rappId);
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INVOKER, invokers.get(0))))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.NO_CONTENT));
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_INVOKER, invokers.get(1))))
@@ -389,12 +388,28 @@ public class SmeDeployerTest {
         mockServer.expect(ExpectedCount.once(),
                         requestTo(String.format(URI_PROVIDER_REGISTRATION, providerFuncs.values().toArray()[1])))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
-
-        boolean undeployRapp = smeDeployer.undeployRapp(rapp);
+        RappInstance rappInstance = getRappInstance();
+        rappInstance.getSme().setApfId(String.valueOf(apfId));
+        rappInstance.getSme().setProviderFunctionIds(providerFuncs.values().stream().toList());
+        rappInstance.getSme().setServiceApiIds(serviceApis);
+        rappInstance.getSme().setInvokerIds(invokers);
+        boolean undeployRapp = smeDeployer.undeployRappInstance(rapp, rappInstance);
         mockServer.verify();
         assertFalse(undeployRapp);
     }
 
+    RappInstance getRappInstance() {
+        RappSMEInstance rappSMEInstance = new RappSMEInstance();
+        rappSMEInstance.setInvokers("invoker-app1");
+        rappSMEInstance.setServiceApis("api-set-1");
+        rappSMEInstance.setAefId("TEST_AEF_ID");
+        rappSMEInstance.setApfId(String.valueOf(UUID.randomUUID()));
+        rappSMEInstance.setProviderFunction("aef-provider-function");
+        RappInstance rappInstance = new RappInstance();
+        rappInstance.setSme(rappSMEInstance);
+        return rappInstance;
+    }
+
     APIProviderEnrolmentDetails getProviderDomainApiEnrollmentDetails() {
         APIProviderEnrolmentDetails apiProviderEnrolmentDetails =
                 new APIProviderEnrolmentDetails(UUID.randomUUID().toString());
@@ -414,6 +429,7 @@ public class SmeDeployerTest {
 
     ServiceAPIDescription getServiceApiDescription() {
         ServiceAPIDescription serviceAPIDescription = new ServiceAPIDescription();
+        serviceAPIDescription.setApiId(String.valueOf(UUID.randomUUID()));
         AefProfile aefProfile = new AefProfile();
         aefProfile.setAefId(String.valueOf(UUID.randomUUID()));
         serviceAPIDescription.setAefProfiles(List.of(aefProfile));
@@ -421,20 +437,12 @@ public class SmeDeployerTest {
     }
 
     APIInvokerEnrolmentDetails getApiInvokerEnrollmentDetails() {
-        APIInvokerEnrolmentDetails apiInvokerEnrolmentDetails = new APIInvokerEnrolmentDetails();
+        APIInvokerEnrolmentDetails apiInvokerEnrolmentDetails =
+                new APIInvokerEnrolmentDetails(String.valueOf(UUID.randomUUID()));
         com.oransc.rappmanager.sme.invoker.data.ServiceAPIDescription serviceAPIDescription =
                 new com.oransc.rappmanager.sme.invoker.data.ServiceAPIDescription();
         serviceAPIDescription.setApiId(String.valueOf(UUID.randomUUID()));
         apiInvokerEnrolmentDetails.setApiList(List.of(serviceAPIDescription));
         return apiInvokerEnrolmentDetails;
     }
-
-    void onBoardRappCsar(UUID rappId) throws Exception {
-        String rappCsarPath = rappManagerConfiguration.getCsarLocation() + File.separator + validRappFile;
-        MockMultipartFile multipartFile =
-                new MockMultipartFile("file", validRappFile, ContentType.MULTIPART_FORM_DATA.getMimeType(),
-                        new FileInputStream(rappCsarPath));
-        mockMvc.perform(MockMvcRequestBuilders.multipart("/rapps/{rapp_id}/onboard", rappId).file(multipartFile))
-                .andExpect(status().isAccepted());
-    }
 }
diff --git a/rapp-manager-sme/src/test/resources/application.yaml b/rapp-manager-sme/src/test/resources/application.yaml
new file mode 100755 (executable)
index 0000000..c2b8a9d
--- /dev/null
@@ -0,0 +1,8 @@
+rappmanager:
+  sme:
+    baseurl: http://localhost:56379 #http://10.101.3.22:61761
+    providerBasePath: /api-provider-management/v1/
+    invokerBasePath: /api-invoker-management/v1/
+    publishApiBasePath: /published-apis/v1/
+    maxRetries: 3
+    retryInterval: 2 #seconds
\ No newline at end of file
diff --git a/rapp-manager-sme/src/test/resources/valid-rapp-package.csar b/rapp-manager-sme/src/test/resources/valid-rapp-package.csar
new file mode 100755 (executable)
index 0000000..b8b36e3
Binary files /dev/null and b/rapp-manager-sme/src/test/resources/valid-rapp-package.csar differ