Correct flow for ScaleOut

Change-Id: I347fec1e15526fa9b43ab57612235b55dee3eeba
Issue-ID: VID-321
Signed-off-by: Wojciech Sliwka <wojciech.sliwka@nokia.com>
diff --git a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system_template.properties b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system_template.properties
index 60ef9a7..f41c4cf 100755
--- a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system_template.properties
+++ b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system_template.properties
@@ -144,4 +144,4 @@
 mso.dme2.client.read.timeout=${MSO_DME2_CLIENT_READ_TIMEOUT}

 mso.dme2.server.url=${MSO_DME2_SERVER_URL}

 mso.dme2.enabled=${MSO_DME2_ENABLED}

-

+scheduler.basic.auth=

diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogic.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogic.java
index 96fb15a..0ecb925 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogic.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogic.java
@@ -28,7 +28,7 @@
 
     MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId);
 
-    MsoResponseWrapper scaleOutVfModuleInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId);
+    MsoResponseWrapper scaleOutVfModuleInstance(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId);
 
     MsoResponseWrapper createConfigurationInstance(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper, String serviceInstanceId);
 
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java
index d4ca865..0b4ca12 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoBusinessLogicImpl.java
@@ -175,7 +175,7 @@
     }
 
     @Override
-    public MsoResponseWrapper scaleOutVfModuleInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
+    public MsoResponseWrapper scaleOutVfModuleInstance(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
         String methodName = "scaleOutVfModuleInstance";
         logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + START);
 
@@ -184,8 +184,12 @@
 
         String partial_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
         String vf_module_endpoint = partial_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+        RequestDetailsWrapper wrapper = new RequestDetailsWrapper();
+        requestDetails.setVnfName(null);
+        requestDetails.setVnfInstanceId(null);
+        wrapper.requestDetails = requestDetails;
 
-        return msoClientInterface.createVfModuleInstance(requestDetails, vf_module_endpoint);
+        return msoClientInterface.scaleOutVFModuleInstance(wrapper, vf_module_endpoint);
     }
     @Override
     public MsoResponseWrapper createConfigurationInstance(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper, String serviceInstanceId) {
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java
index 3cba12f..834f808 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoInterface.java
@@ -74,6 +74,8 @@
 
     MsoResponseWrapper createConfigurationInstance(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper, String endpoint);
 
+    MsoResponseWrapper scaleOutVFModuleInstance(RequestDetailsWrapper requestDetailsWrapper, String endpoint);
+
     MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String endpoint);
 
     MsoResponseWrapper unassignSvcInstance(RequestDetails requestDetails, String endpoint);
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java b/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java
index 9cac3e4..59bd667 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/rest/MsoRestClientNew.java
@@ -124,6 +124,14 @@
     }
 
     @Override
+    public MsoResponseWrapper scaleOutVFModuleInstance(RequestDetailsWrapper requestDetailsWrapper, String endpoint) {
+        String methodName = "scaleOutVFModuleInstance";
+        logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + START);
+        String path = baseUrl + endpoint;
+        return createInstance(requestDetailsWrapper, path);
+    }
+
+    @Override
     public MsoResponseWrapper createConfigurationInstance(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper, String endpoint) {
         String methodName = "createConfigurationInstance";
         logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + START);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
index f1440fc..6029ed2 100644
--- a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
@@ -269,11 +269,15 @@
 				var data;
 				if(workflowType=="VNF Scale Out") {
                     data = {
+                        vnfName: vnf.name,
+                        vnfInstanceId: vnf.id,
                         modelInfo: {
                             modelType: 'vfModule',
                             modelInvariantId: moduleToScale.invariantUuid,
                             modelName: moduleToScale.modelCustomizationName,
                             modelVersion: moduleToScale.version,
+                            modelCustomizationName: moduleToScale.modelCustomizationName,
+                            modelCustomizationId: moduleToScale.customizationUuid,
                             modelVersionId: moduleToScale.uuid
                         },
                         cloudConfiguration: vnf.cloudConfiguration,
@@ -335,6 +339,7 @@
                         var relatedInstance = {
                             instanceId: vnf.id,
                             modelInfo: {
+                                modelCustomizationId: vnf.availableVersions[0].modelInfo.modelCustomizationId,
                                 modelCustomizationName: vnf.availableVersions[0].modelInfo.modelCustomizationName,
                                 modelInvariantId: vnf.availableVersions[0].modelInfo.modelInvariantId,
                                 modelName: vnf.availableVersions[0].modelInfo.modelName,
@@ -377,18 +382,8 @@
 				//no scheduling support
 				var dataToSo = extractChangeManagementCallbackDataStr(vm.changeManagement);
                 if(dataToSo) {
-
-                    if(vm.changeManagement.workflow==="VNF Scale Out") {
-                        dataToSo = JSON.parse(dataToSo);
-                        dataToSo = {requestDetails: dataToSo.requestDetails[0]};
-                        changeManagementService.postChangeManagementScaleOutNow(dataToSo,
-                            vm.changeManagement.vnfNames[0]["service-instance-node"][0].properties["service-instance-id"],
-                            vm.changeManagement.vnfNames[0].id);
-                    }else{
-                        //TODO: foreach
-                        var vnfName = vm.changeManagement.vnfNames[0].name;
-                        changeManagementService.postChangeManagementNow(dataToSo, vnfName);
-                    }
+                    var vnfName = vm.changeManagement.vnfNames[0].name;
+                    changeManagementService.postChangeManagementNow(dataToSo, vnfName);
                 }
 			}
         };
diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java
index 36f4bdd..e0e3c36 100644
--- a/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/mso/MsoBusinessLogicImplTest.java
@@ -1,12 +1,17 @@
 package org.onap.vid.mso;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.changeManagement.RequestDetailsWrapper;
+import org.onap.vid.controllers.MsoController;
 import org.onap.vid.mso.rest.RequestDetails;
 import org.onap.vid.properties.Features;
-import org.onap.portalsdk.core.util.SystemProperties;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -16,16 +21,28 @@
 import org.testng.annotations.Test;
 import org.togglz.core.manager.FeatureManager;
 
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.onap.vid.controllers.MsoController.SVC_INSTANCE_ID;
-import static org.onap.vid.controllers.MsoController.VNF_INSTANCE_ID;
 import static org.onap.vid.mso.MsoBusinessLogicImpl.validateEndpointPath;
 
 @ContextConfiguration(classes = {SystemProperties.class})
 @WebAppConfiguration
 public class MsoBusinessLogicImplTest extends AbstractTestNGSpringContextTests {
 
+    private static final String SERVICE_INSTANCE_ID = "1";
+    private static final String VNF_INSTANCE_ID = "1";
+    private static final String EXPECTED_SCALE_OUT_PATH = "/serviceInstantiation/v7/serviceInstances/1/vnfs/1/vfModules/scaleOut";
+    private static final Path PATH_TO_NOT_PROCESSED_SCALE_OUT_REQUEST = Paths.get("src", "test", "resources", "payload_jsons", "scaleOutVfModulePayload.json");
+    private static final Path PATH_TO_FINAL_SCALE_OUT_REQUEST = Paths.get("src", "test", "resources", "payload_jsons", "scaleOutVfModulePayloadToMso.json");
+    private static final ObjectMapper OBJECT_MAPPER=new ObjectMapper();
+
     @InjectMocks
     private MsoBusinessLogicImpl msoBusinessLogic;
 
@@ -37,31 +54,31 @@
 
 
     @BeforeTest
-    public void initMocks(){
+    public void initMocks() {
         MockitoAnnotations.initMocks(this);
     }
 
     @Test
-    public void validateEndpointPath_endPointIsNotEmptyAndVaild_returnProperty(){
-        System.setProperty("TestEnv","123");
+    public void validateEndpointPath_endPointIsNotEmptyAndVaild_returnProperty() {
+        System.setProperty("TestEnv", "123");
         String foundEndPoint = validateEndpointPath("TestEnv");
-        Assert.assertEquals("123",foundEndPoint);
+        Assert.assertEquals("123", foundEndPoint);
     }
 
     @Test(expectedExceptions = RuntimeException.class)
-    public void validateEndpointPath_endPointIsNull_throwRuntimeException(){
+    public void validateEndpointPath_endPointIsNull_throwRuntimeException() {
         validateEndpointPath("NotExists");
     }
 
     @Test(expectedExceptions = RuntimeException.class)
-    public void validateEndpointPath_endPointIsNotEmptyButDoesntExists_throwRuntimeException(){
-        System.setProperty("EmptyEndPoint","");
+    public void validateEndpointPath_endPointIsNotEmptyButDoesntExists_throwRuntimeException() {
+        System.setProperty("EmptyEndPoint", "");
         validateEndpointPath("EmptyEndPoint");
     }
 
 
     //@Test(dataProvider = "unAssignOrDeleteParams")
-    public void deleteSvcInstance_verifyEndPointPathConstructing_unAssignFeatureOffOrUnAssignFlagIsFalse(boolean isAssignFlag,String status) {
+    public void deleteSvcInstance_verifyEndPointPathConstructing_unAssignFeatureOffOrUnAssignFlagIsFalse(boolean isAssignFlag, String status) {
         Mockito.reset(msoInterfaceMock);
         String endpoint = validateEndpointPath(isAssignFlag ? MsoProperties.MSO_DELETE_OR_UNASSIGN_REST_API_SVC_INSTANCE : MsoProperties.MSO_REST_API_SVC_INSTANCE);
         RequestDetails requestDetails = new RequestDetails();
@@ -114,7 +131,7 @@
 
         String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, "serviceInstanceTempId");
 
-        msoBusinessLogic.deleteVnf(requestDetails, "serviceInstanceTempId","vnfInstanceTempId");
+        msoBusinessLogic.deleteVnf(requestDetails, "serviceInstanceTempId", "vnfInstanceTempId");
         verify(msoInterfaceMock).deleteVnf(requestDetails, vnf_endpoint + "/vnfInstanceTempId");
     }
 
@@ -123,31 +140,34 @@
         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
         RequestDetails requestDetails = new RequestDetails();
 
-        String vf__modules_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, "serviceInstanceTempId").replaceFirst(VNF_INSTANCE_ID, "vnfInstanceTempId");
+        String vf__modules_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, "serviceInstanceTempId").replaceFirst(MsoController.VNF_INSTANCE_ID, "vnfInstanceTempId");
 
-        msoBusinessLogic.deleteVfModule(requestDetails, "serviceInstanceTempId","vnfInstanceTempId", "vfModuleTempId");
-        verify(msoInterfaceMock).deleteVfModule(requestDetails, vf__modules_endpoint + "/vfModuleTempId" );
+        msoBusinessLogic.deleteVfModule(requestDetails, "serviceInstanceTempId", "vnfInstanceTempId", "vfModuleTempId");
+        verify(msoInterfaceMock).deleteVfModule(requestDetails, vf__modules_endpoint + "/vfModuleTempId");
     }
 
-    @Test
-    public void insertServiceInstantiationToDB_StartJob() {
 
-//        broker = new JobsBrokerServiceInDatabaseImpl(dataAccessServiceMock, sessionFactory);
-//        ((JobsBrokerServiceInDatabaseImpl)broker).deleteAll();
-//
-////        msoBusinessLogic.setDataAccessService(dataAccessServiceMock);
-////        msoBusinessLogic.setJobsBrokerService(broker);
-////        msoBusinessLogic.setJobAdapter(jobAdapter);
-//
-//        ServiceInstantiation serviceInstantiation = new ServiceInstantiation();
-//        serviceInstantiation.setCount(2);
-//        serviceInstantiation.setInstanceName("TestName");
-//
-//        msoBusinessLogic.pushBulkJob(serviceInstantiation, "testUserId");
-//
-//        List<ServiceInfo> serviceInfoList = dataAccessServiceMock.getList(ServiceInfo.class, null);
-//        int k = 9;
-//        Assert.assertEquals(serviceInstantiation, containsInAnyOrder(serviceInfoList.toArray()));
+    @Test
+    public void shouldSendProperScaleOutRequest() throws IOException {
+        ArgumentCaptor<RequestDetailsWrapper> requestDetailsWrapperArgumentCaptor = ArgumentCaptor.forClass(RequestDetailsWrapper.class);
+        org.onap.vid.changeManagement.RequestDetails requestDetails = getScaleOutRequest();
+        RequestDetailsWrapper expectedRequestWrapper = getExpectedRequestWrapper();
+
+        msoBusinessLogic.scaleOutVfModuleInstance(requestDetails, SERVICE_INSTANCE_ID, VNF_INSTANCE_ID);
+
+        verify(msoInterfaceMock).scaleOutVFModuleInstance(requestDetailsWrapperArgumentCaptor.capture(), eq(EXPECTED_SCALE_OUT_PATH));
+        RequestDetailsWrapper actual = requestDetailsWrapperArgumentCaptor.getAllValues().get(0);
+
+        assertThat(expectedRequestWrapper.requestDetails).isEqualTo(actual.requestDetails);
+    }
+
+    private org.onap.vid.changeManagement.RequestDetails getScaleOutRequest() throws IOException {
+        return OBJECT_MAPPER.readValue(PATH_TO_NOT_PROCESSED_SCALE_OUT_REQUEST.toFile(), org.onap.vid.changeManagement.RequestDetails.class);
+    }
+
+    private RequestDetailsWrapper getExpectedRequestWrapper() throws IOException {
+        return OBJECT_MAPPER.readValue(PATH_TO_FINAL_SCALE_OUT_REQUEST.toFile(), new TypeReference<RequestDetailsWrapper<org.onap.vid.changeManagement.RequestDetails>>() {
+        });
     }
 }
 
diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java
index 402386a..6996640 100644
--- a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientNewTest.java
@@ -21,17 +21,11 @@
 package org.onap.vid.mso.rest;
 
 import com.xebialabs.restito.server.StubServer;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Properties;
-import java.util.UUID;
 import org.glassfish.grizzly.http.util.HttpStatus;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.onap.portalsdk.core.util.SystemProperties;
 import org.onap.vid.client.SyncRestClient;
 import org.onap.vid.controllers.MsoController;
 import org.onap.vid.mso.MsoInterface;
@@ -39,16 +33,30 @@
 import org.onap.vid.mso.MsoResponseWrapper;
 import org.onap.vid.mso.MsoResponseWrapperInterface;
 import org.onap.vid.mso.RestObject;
+import org.springframework.test.context.ContextConfiguration;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+import java.util.UUID;
+
+import static org.onap.vid.controllers.MsoController.SVC_INSTANCE_ID;
+import static org.onap.vid.controllers.MsoController.VNF_INSTANCE_ID;
+
+@ContextConfiguration(classes = {SystemProperties.class})
 public class MsoRestClientNewTest {
 
     private static StubServer server;
     private static StubServer securedServer;
     private static Properties props = new Properties();
     private static String msoCreateServiceInstanceJson;
+    private static String msoScaleOutVfModule;
     private final static String CREATE_INSTANCE_RESPONSE_STR =
-        "{\"requestReferences\":{\"instanceId\":\"baa13544-0e95-4644-9565-9a198a29a294\","
-            + "\"requestId\":\"a42a1a35-3d63-4629-bbe0-4989fa7414cb\"}}";
+            "{\"requestReferences\":{\"instanceId\":\"baa13544-0e95-4644-9565-9a198a29a294\","
+                    + "\"requestId\":\"a42a1a35-3d63-4629-bbe0-4989fa7414cb\"}}";
     private final static String SERVICE_INSTANCE_ID = "12345";
     private static final String SAMPLE_VNF_INSTANCE_ID = "111";
     private static final String SAMPLE_VNF_MODULE_ID = "987";
@@ -63,15 +71,19 @@
         securedServer = new StubServer().secured().run();
 
         Path resourceDirectory =
-            Paths.get("src", "test", "resources", "WEB-INF", "conf", "system.properties");
-        try(InputStream is = Files.newInputStream(resourceDirectory)) {
+                Paths.get("src", "test", "resources", "WEB-INF", "conf", "system.properties");
+        try (InputStream is = Files.newInputStream(resourceDirectory)) {
             props.load(is);
         }
 
         Path msoServiceInstantiationJsonFilePath =
-            Paths.get("src", "test", "resources", "payload_jsons", "mso_service_instantiation.json");
+                Paths.get("src", "test", "resources", "payload_jsons", "mso_service_instantiation.json");
+
+        Path scaleOutJsonFilePath = Paths.get("src", "test", "resources", "payload_jsons", "scaleOutVfModulePayloadToMso.json");
         msoCreateServiceInstanceJson =
-            String.join("\n", Files.readAllLines(msoServiceInstantiationJsonFilePath));
+                String.join("\n", Files.readAllLines(msoServiceInstantiationJsonFilePath));
+        msoScaleOutVfModule = String.join("\n", Files.readAllLines(scaleOutJsonFilePath));
+
     }
 
     @AfterClass
@@ -89,11 +101,11 @@
     public void testCreateSvcInstance() throws Exception {
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_CONFIGURATIONS);
         endpoint = endpoint.replace(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            endpoint,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::createSvcInstance);
         }
     }
@@ -102,12 +114,12 @@
     public void testCreateVnf() throws Exception {
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_VNF_INSTANCE);
         endpoint = endpoint.replace(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            endpoint,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
-            
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
+
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::createVnf);
         }
     }
@@ -116,11 +128,11 @@
     public void testCreateNwInstance() throws Exception {
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
         String nw_endpoint = endpoint.replaceFirst(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            nw_endpoint,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                nw_endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::createNwInstance);
         }
     }
@@ -130,11 +142,11 @@
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
         String vnf_endpoint = endpoint.replaceFirst(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
         vnf_endpoint = vnf_endpoint.replaceFirst(MsoController.VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            vnf_endpoint,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                vnf_endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::createVolumeGroupInstance);
         }
     }
@@ -144,14 +156,14 @@
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
         String partial_endpoint = endpoint.replaceFirst(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
         String vf_module_endpoint =
-            partial_endpoint.replaceFirst(MsoController.VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
+                partial_endpoint.replaceFirst(MsoController.VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
 
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            vf_module_endpoint,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                vf_module_endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::createVfModuleInstance);
         }
     }
@@ -177,11 +189,11 @@
         endpoint = endpoint.replaceFirst(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
 
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            endpoint,
-            HttpStatus.NO_CONTENT_204,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                endpoint,
+                HttpStatus.NO_CONTENT_204,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executeDelete(msoCreateServiceInstanceJson, msoRestClient()::deleteSvcInstance);
         }
     }
@@ -191,11 +203,11 @@
         String endpoint = props.getProperty(MsoProperties.MSO_REST_API_VNF_INSTANCE);
         endpoint = endpoint.replaceFirst(MsoController.SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            endpoint,
-            HttpStatus.NO_CONTENT_204,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                endpoint,
+                HttpStatus.NO_CONTENT_204,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executeDelete(msoCreateServiceInstanceJson, msoRestClient()::deleteVnf);
         }
     }
@@ -207,11 +219,11 @@
         String vf_modules_endpoint = part_endpoint.replaceFirst(MsoController.VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
         String delete_vf_endpoint = vf_modules_endpoint + '/' + SAMPLE_VNF_MODULE_ID;
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            delete_vf_endpoint,
-            HttpStatus.NO_CONTENT_204,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                delete_vf_endpoint,
+                HttpStatus.NO_CONTENT_204,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executeDelete(msoCreateServiceInstanceJson, msoRestClient()::deleteVfModule);
         }
     }
@@ -223,11 +235,11 @@
         String vnf_endpoint = svc_endpoint.replaceFirst(MsoController.VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
         String delete_volume_group_endpoint = vnf_endpoint + "/" + SAMPLE_VNF_MODULE_ID;
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            delete_volume_group_endpoint,
-            HttpStatus.NO_CONTENT_204,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                delete_volume_group_endpoint,
+                HttpStatus.NO_CONTENT_204,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executeDelete(msoCreateServiceInstanceJson, msoRestClient()::deleteVolumeGroupInstance);
         }
     }
@@ -410,11 +422,11 @@
         String serviceEndpoint = props.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
         String removeRelationshipsPath = serviceEndpoint + "/" + SERVICE_INSTANCE_ID + "/removeRelationships";
 
-        try(MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
-            server,
-            removeRelationshipsPath,
-            HttpStatus.ACCEPTED_202,
-            CREATE_INSTANCE_RESPONSE_STR,CREATE_INSTANCE_RESPONSE_STR)) {
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                removeRelationshipsPath,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
             closure.executePost(msoCreateServiceInstanceJson, msoRestClient()::removeRelationshipFromServiceInstance);
         }
     }
@@ -433,6 +445,20 @@
         } catch (Exception e) {
         }
     }
+    @Test
+    public void testScaleOutVfModule() throws IOException {
+        String serviceEndpoint = props.getProperty(MsoProperties.MSO_REST_API_VF_MODULE_SCALE_OUT);
+        String partial_endpoint = serviceEndpoint.replaceFirst(SVC_INSTANCE_ID, SERVICE_INSTANCE_ID);
+        String vf_module_endpoint = partial_endpoint.replaceFirst(VNF_INSTANCE_ID, SAMPLE_VNF_INSTANCE_ID);
+        try (MsoRestClientTestUtil closure = new MsoRestClientTestUtil(
+                server,
+                vf_module_endpoint,
+                HttpStatus.ACCEPTED_202,
+                CREATE_INSTANCE_RESPONSE_STR, CREATE_INSTANCE_RESPONSE_STR)) {
+            closure.executePostCall(msoScaleOutVfModule, msoRestClient()::scaleOutVFModuleInstance);
+        }
+
+    }
 
     private MsoRestClientNew msoRestClient() {
         return new MsoRestClientNew(new SyncRestClient(MsoInterface.objectMapper()), baseUrl());
diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTestUtil.java b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTestUtil.java
index e8f5569..c81fa16 100644
--- a/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTestUtil.java
+++ b/vid-app-common/src/test/java/org/onap/vid/mso/rest/MsoRestClientTestUtil.java
@@ -20,11 +20,13 @@
 import java.util.function.Function;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+
 import org.glassfish.grizzly.http.Method;
 import org.glassfish.grizzly.http.util.HttpStatus;
 import org.json.JSONObject;
 import org.junit.Assert;
 import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.changeManagement.RequestDetailsWrapper;
 import org.onap.vid.mso.MsoResponseWrapper;
 
 class MsoRestClientTestUtil implements AutoCloseable {
@@ -60,6 +62,21 @@
     verifyServer(server, endpoint, Method.POST);
 
   }
+  void executePostCall(String jsonPayload, BiFunction<RequestDetailsWrapper, String, MsoResponseWrapper> func) throws IOException {
+    whenHttp(server)
+            .match(post(endpoint))
+            .then(status(expectedStatus), jsonContent(responsePayload), contentType(MediaType.APPLICATION_JSON));
+
+    RequestDetailsWrapper  sampleRequestDetails =
+            new ObjectMapper().readValue(jsonPayload, RequestDetailsWrapper.class);
+
+    MsoResponseWrapper response = func.apply(sampleRequestDetails, endpoint);
+    JSONObject actualJson = new JSONObject(response.getEntity());
+
+    Assert.assertEquals(expectedStatus.getStatusCode(), response.getStatus());
+    Assert.assertEquals(expectedResponseStr, actualJson.toString());
+    verifyServer(server, endpoint, Method.POST);
+  }
 
   void executeDelete(String jsonPayload, BiFunction<RequestDetails, String, MsoResponseWrapper> func)
       throws IOException {
diff --git a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
index bf0f826..fff5456 100644
--- a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
+++ b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
@@ -154,7 +154,8 @@
 mso.restapi.vnf.instance=/serviceInstances/v5/<service_instance_id>/vnfs
 mso.restapi.vnf.changemanagement.instance=/serviceInstances/v5/<service_instance_id>/vnfs/<vnf_instance_id>/<request_type>
 mso.restapi.network.instance=/serviceInstances/v5/<service_instance_id>/networks
-mso.restapi.vf.module.instance=/serviceInstantiation/v7/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules/scaleOut
+mso.restapi.vf.module.instance=/serviceInstances/v6/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules
+mso.restapi.vf.module.scaleout=/serviceInstantiation/v7/serviceInstances/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules/scaleOut
 mso.restapi.volume.group.instance=/serviceInstances/v5/<service_instance_id>/vnfs/<vnf_instance_id>/volumeGroups
 mso.restapi.get.orc.req=/orchestrationRequests/v5
 mso.restapi.get.orc.reqs=/orchestrationRequests/v5?
diff --git a/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayload.json b/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayload.json
new file mode 100644
index 0000000..c509c62
--- /dev/null
+++ b/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayload.json
@@ -0,0 +1,67 @@
+{
+    "vnfName":"test",
+    "vnfInstanceId":"123",
+    "relatedInstanceList": [
+      {
+        "relatedInstance": {
+          "instanceId": "fd84f066-ea75-4b23-acd0-3cf3fce7a99b",
+          "modelInfo": {
+            "modelType": "service",
+            "modelInvariantId": "c9817f08-07b2-458b-a02f-cd5407ee7a7b",
+            "modelVersionId": "0e0bb964-e687-4439-9a9e-de9cd1ff5367",
+            "modelName": "ws-service",
+            "modelVersion": "1.0",
+            "additionalProperties": {}
+          }
+        }
+      },
+      {
+        "relatedInstance": {
+          "instanceId": "980fe98e-47f8-4164-862d-4ebb026cec75",
+          "modelInfo": {
+            "modelType": "vnf",
+            "modelInvariantId": "734f0952-6678-44e7-8918-f9aa4694b687",
+            "modelVersionId": "0e0bb964-e687-4439-9a9e-de9cd1ff5367",
+            "modelName": "ws-sp",
+            "modelVersion": "1.0",
+            "modelCustomizationName": "ws-sp 0",
+            "modelCustomizationId": "5815868c-35f8-4c5a-b899-e6eb49f52986",
+            "additionalProperties": {}
+          }
+        }
+      }
+    ],
+    "cloudConfiguration": {
+      "lcpCloudRegionId": "RegionOne",
+      "tenantId": "1e097c6713e74fd7ac8e4295e605ee1e",
+      "additionalProperties": {}
+    },
+    "modelInfo": {
+      "modelCustomizationName": "WsSp..base_ws..module-0",
+      "modelCustomizationId": "bfcc8f57-7b56-4be8-a8f1-e44262c83318",
+      "modelInvariantId": "763b1172-b5f5-4062-9d79-2459710fa0bc",
+      "modelVersionId": "53f52586-236b-4d52-a94c-990883e054f0",
+      "modelName": "WsSp..base_ws..module-0",
+      "modelNameVersionId": null,
+      "modelType": "vfModule",
+      "modelVersion": "1",
+      "additionalProperties": {}
+    },
+    "requestInfo": {
+      "instanceName": "ws-test-0310-8_NaN",
+      "source": "VID",
+      "suppressRollback": false,
+      "requestorId": "demo",
+      "additionalProperties": {}
+    },
+    "requestParameters": {
+      "additionalProperties": {}
+    },
+    "configurationParameters": [
+      {
+        "availability-zone": "$.vnf-topology.vnf-resource-assignments.availability-zones.availability-zone[0]",
+        "xtz-123": "$.vnf-topology.vnf-resource-assignments.availability-zones.availability-zone[0]"
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayloadToMso.json b/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayloadToMso.json
new file mode 100644
index 0000000..ddbebac
--- /dev/null
+++ b/vid-app-common/src/test/resources/payload_jsons/scaleOutVfModulePayloadToMso.json
@@ -0,0 +1,66 @@
+{
+  "requestDetails": {
+    "relatedInstanceList": [
+      {
+        "relatedInstance": {
+          "instanceId": "fd84f066-ea75-4b23-acd0-3cf3fce7a99b",
+          "modelInfo": {
+            "modelType": "service",
+            "modelInvariantId": "c9817f08-07b2-458b-a02f-cd5407ee7a7b",
+            "modelVersionId": "0e0bb964-e687-4439-9a9e-de9cd1ff5367",
+            "modelName": "ws-service",
+            "modelVersion": "1.0",
+            "additionalProperties": {}
+          }
+        }
+      },
+      {
+        "relatedInstance": {
+          "instanceId": "980fe98e-47f8-4164-862d-4ebb026cec75",
+          "modelInfo": {
+            "modelType": "vnf",
+            "modelInvariantId": "734f0952-6678-44e7-8918-f9aa4694b687",
+            "modelVersionId": "0e0bb964-e687-4439-9a9e-de9cd1ff5367",
+            "modelName": "ws-sp",
+            "modelVersion": "1.0",
+            "modelCustomizationName": "ws-sp 0",
+            "modelCustomizationId": "5815868c-35f8-4c5a-b899-e6eb49f52986",
+            "additionalProperties": {}
+          }
+        }
+      }
+    ],
+    "cloudConfiguration": {
+      "lcpCloudRegionId": "RegionOne",
+      "tenantId": "1e097c6713e74fd7ac8e4295e605ee1e",
+      "additionalProperties": {}
+    },
+    "modelInfo": {
+      "modelCustomizationName": "WsSp..base_ws..module-0",
+      "modelCustomizationId": "bfcc8f57-7b56-4be8-a8f1-e44262c83318",
+      "modelInvariantId": "763b1172-b5f5-4062-9d79-2459710fa0bc",
+      "modelVersionId": "53f52586-236b-4d52-a94c-990883e054f0",
+      "modelName": "WsSp..base_ws..module-0",
+      "modelNameVersionId": null,
+      "modelType": "vfModule",
+      "modelVersion": "1",
+      "additionalProperties": {}
+    },
+    "requestInfo": {
+      "instanceName": "ws-test-0310-8_NaN",
+      "source": "VID",
+      "suppressRollback": false,
+      "requestorId": "demo",
+      "additionalProperties": {}
+    },
+    "requestParameters": {
+      "additionalProperties": {}
+    },
+    "configurationParameters": [
+      {
+        "availability-zone": "$.vnf-topology.vnf-resource-assignments.availability-zones.availability-zone[0]",
+        "xtz-123": "$.vnf-topology.vnf-resource-assignments.availability-zones.availability-zone[0]"
+      }
+    ]
+  }
+}
\ No newline at end of file