Merge "Cloud Config Updates"
diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.2__ScaleOutRecipe.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.2__ScaleOutRecipe.sql
new file mode 100644
index 0000000..b3d8b98
--- /dev/null
+++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.2__ScaleOutRecipe.sql
@@ -0,0 +1,5 @@
+use catalogdb;
+
+INSERT INTO vnf_components_recipe (VNF_COMPONENT_TYPE, ACTION, VERSION, DESCRIPTION, ORCHESTRATION_URI, RECIPE_TIMEOUT, VF_MODULE_MODEL_UUID)
+VALUES
+('vfModule', 'scaleOut', '1', 'Gr api recipe to scale out vfModule', '/mso/async/services/WorkflowActionBB', '180', 'GR-API-DEFAULT');               
diff --git a/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/infrastructure/pnf/delegate/bpmn/CreateAndActivatePnfResourceTest.java b/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/infrastructure/pnf/delegate/bpmn/CreateAndActivatePnfResourceTest.java
index d42717f..b514c38 100644
--- a/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/infrastructure/pnf/delegate/bpmn/CreateAndActivatePnfResourceTest.java
+++ b/bpmn/mso-infrastructure-bpmn/src/test/java/org/onap/so/bpmn/infrastructure/pnf/delegate/bpmn/CreateAndActivatePnfResourceTest.java
@@ -30,18 +30,17 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.camunda.bpm.engine.RuntimeService;
 import org.camunda.bpm.engine.history.HistoricVariableInstance;
 import org.camunda.bpm.engine.runtime.ProcessInstance;
 import org.camunda.bpm.engine.test.Deployment;
 import org.camunda.bpm.engine.test.ProcessEngineRule;
 import org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareTests;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.onap.so.bpmn.infrastructure.pnf.delegate.AaiConnectionTestImpl;
+import org.onap.so.bpmn.infrastructure.pnf.delegate.DmaapClientTestImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringRunner;
@@ -61,6 +60,9 @@
     @Autowired
     private AaiConnectionTestImpl aaiConnection;
 
+    @Autowired
+    private DmaapClientTestImpl dmaapClientTestImpl;
+
     @Test
     @Deployment(resources = {"process/CreateAndActivatePnfResource.bpmn"})
     public void shouldSaveCurrentIpToVariableIfItAlreadyExistsInAai() throws Exception {
@@ -96,9 +98,8 @@
         ProcessInstance instance = runtimeService
                 .startProcessInstanceByKey("CreateAndActivatePnfResource", "businessKey", variables);
         assertThat(instance).isWaitingAt("WaitForDmaapPnfReadyNotification").isWaitingFor("WorkflowMessage");
-        runtimeService.createMessageCorrelation("WorkflowMessage")
-                .processInstanceBusinessKey("businessKey")
-                .correlateWithResult();
+        dmaapClientTestImpl.sendMessage();
+
         // then
         assertThat(instance).isEnded().hasPassedInOrder(
                 "CreateAndActivatePnf_StartEvent",
@@ -125,9 +126,8 @@
         ProcessInstance instance = runtimeService
                 .startProcessInstanceByKey("CreateAndActivatePnfResource", "businessKey", variables);
         assertThat(instance).isWaitingAt("WaitForDmaapPnfReadyNotification").isWaitingFor("WorkflowMessage");
-        runtimeService.createMessageCorrelation("WorkflowMessage")
-                .processInstanceBusinessKey("businessKey")
-                .correlateWithResult();
+        dmaapClientTestImpl.sendMessage();
+
         // then
         assertThat(instance).isEnded().hasPassedInOrder(
                 "CreateAndActivatePnf_StartEvent",
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/pnf/delegate/InformDmaapClient.java b/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/pnf/delegate/InformDmaapClient.java
index bb490a0..61b1ca4 100644
--- a/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/pnf/delegate/InformDmaapClient.java
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/java/org/onap/so/bpmn/infrastructure/pnf/delegate/InformDmaapClient.java
@@ -20,6 +20,7 @@
 
 package org.onap.so.bpmn.infrastructure.pnf.delegate;
 
+import org.camunda.bpm.engine.RuntimeService;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.camunda.bpm.engine.delegate.JavaDelegate;
 import org.onap.so.bpmn.infrastructure.pnf.dmaap.DmaapClient;
@@ -30,12 +31,15 @@
     private DmaapClient dmaapClient;
 
     @Override
-    public void execute(DelegateExecution execution) throws Exception {
+    public void execute(DelegateExecution execution) {
         String correlationId = (String) execution.getVariable(ExecutionVariableNames.CORRELATION_ID);
-        dmaapClient.registerForUpdate(correlationId, () -> execution.getProcessEngineServices().getRuntimeService()
+        RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService();
+        dmaapClient.registerForUpdate(correlationId, () ->
+            runtimeService
                 .createMessageCorrelation("WorkflowMessage")
                 .processInstanceBusinessKey(execution.getProcessBusinessKey())
-                .correlateWithResult());
+                .correlateWithResult()
+        );
     }
 
     @Autowired
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/BaseClient.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/BaseClient.java
index 5a63d20..50137cf 100644
--- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/BaseClient.java
+++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/BaseClient.java
@@ -52,20 +52,19 @@
 		this.targetUrl = targetUrl;
 	}
 
-	public O get(I data, Object... uriVariables) throws RestClientException {
-		return run(data, HttpMethod.GET, uriVariables);
+	public O get(I data, ParameterizedTypeReference<O> typeRef, Object... uriVariables) throws RestClientException {
+		return run(data, HttpMethod.GET, typeRef, uriVariables);
 	}
 
-	public O post(I data, Object... uriVariables) throws RestClientException {
-		return run(data, HttpMethod.POST, uriVariables);
+	public O post(I data, ParameterizedTypeReference<O> typeRef, Object... uriVariables) throws RestClientException {
+		return run(data, HttpMethod.POST, typeRef, uriVariables);
 	}
 
-	public O run(I data, HttpMethod method, Object... uriVariables) throws RestClientException {
+	public O run(I data, HttpMethod method, ParameterizedTypeReference<O> typeRef, Object... uriVariables) throws RestClientException {
 		HttpEntity<I> requestEntity = new HttpEntity<I>(data, getHttpHeader());
 		RestTemplate restTemplate = new RestTemplate();
 		restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
-		ParameterizedTypeReference<O> output = new ParameterizedTypeReference<O>() {};
-		ResponseEntity<O> responseEntity = restTemplate.exchange(getTargetUrl(), method, requestEntity, output,
+		ResponseEntity<O> responseEntity = restTemplate.exchange(getTargetUrl(), method, requestEntity, typeRef,
 				uriVariables);
 		return responseEntity.getBody();
 	}
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/SDNCClient.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/SDNCClient.java
index 1f0d654..9e60196 100644
--- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/SDNCClient.java
+++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sdnc/SDNCClient.java
@@ -21,6 +21,7 @@
 package org.onap.so.client.sdnc;
 
 import java.util.LinkedHashMap;
+
 import javax.ws.rs.core.UriBuilder;
 
 import org.onap.so.client.exception.BadResponseException;
@@ -29,6 +30,7 @@
 import org.onap.so.client.sdnc.endpoint.SDNCTopology;
 import org.onap.so.logger.MsoLogger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.HttpHeaders;
 import org.springframework.stereotype.Component;
 
@@ -58,7 +60,7 @@
 			HttpHeaders httpHeader = sdnCommonTasks.getHttpHeaders(properties.getAuth());
 			STOClient.setHttpHeader(httpHeader);
 			msoLogger.info("Running SDNC CLIENT for TargetUrl: " + targetUrl);
-			LinkedHashMap<?, ?> output = STOClient.post(jsonRequest);
+			LinkedHashMap<?, ?> output = STOClient.post(jsonRequest, new ParameterizedTypeReference<LinkedHashMap<? ,?>>() {});
 			msoLogger.info("Validating output...");
 			return sdnCommonTasks.validateSDNResponse(output);
 	}
@@ -84,7 +86,7 @@
 			HttpHeaders httpHeader = sdnCommonTasks.getHttpHeaders(properties.getAuth());
 			STOClient.setHttpHeader(httpHeader);
 			msoLogger.info("Running SDNC CLIENT...");
-			LinkedHashMap<?, ?> output = STOClient.get(jsonRequest);
+			LinkedHashMap<?, ?> output = STOClient.get(jsonRequest, new ParameterizedTypeReference<LinkedHashMap<? ,?>>() {});
 			msoLogger.info("Validating output...");
 			return sdnCommonTasks.validateSDNGetResponse(output);
 	}
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sniro/SniroClient.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sniro/SniroClient.java
index 979b9e5..cee94e2 100644
--- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sniro/SniroClient.java
+++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/sniro/SniroClient.java
@@ -31,6 +31,7 @@
 import org.onap.so.client.sniro.beans.SniroManagerRequest;
 import org.onap.so.logger.MsoLogger;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
@@ -76,7 +77,7 @@
 		baseClient.setTargetUrl(url);
 		baseClient.setHttpHeader(header);
 
-		LinkedHashMap<?, ?> response = baseClient.post(homingRequest.toJsonString());
+		LinkedHashMap<?, ?> response = baseClient.post(homingRequest.toJsonString(), new ParameterizedTypeReference<LinkedHashMap<? ,?>>() {});
 		validator.validateDemandsResponse(response);
 		log.trace("Completed Sniro Client Post Demands");
 	}
@@ -106,7 +107,7 @@
 		baseClient.setTargetUrl(url);
 		baseClient.setHttpHeader(header);
 
-		LinkedHashMap<?, ?> response = baseClient.post(releaseRequest.toJsonString());
+		LinkedHashMap<?, ?> response = baseClient.post(releaseRequest.toJsonString(), new ParameterizedTypeReference<LinkedHashMap<? ,?>>() {});
 		SniroValidator v = new SniroValidator();
 		v.validateReleaseResponse(response);
 		log.trace("Completed Sniro Client Post Release");
diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/sdnc/BaseClientTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/sdnc/BaseClientTest.java
new file mode 100644
index 0000000..a564d8a
--- /dev/null
+++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/client/sdnc/BaseClientTest.java
@@ -0,0 +1,50 @@
+package org.onap.so.client.sdnc;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.springframework.core.ParameterizedTypeReference;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+
+import wiremock.org.apache.http.entity.ContentType;
+public class BaseClientTest {
+
+	
+	@Rule
+	public WireMockRule wm = new WireMockRule(options().dynamicPort());
+	
+	@Test
+	public void verifyString() {
+		BaseClient<String, String> client = new BaseClient<>();
+		String response = "{\"hello\" : \"world\"}";
+		client.setTargetUrl(UriBuilder.fromUri("http://localhost/test").port(wm.port()).build().toString());
+		wm.stubFor(get(urlEqualTo("/test"))
+                .willReturn(aResponse().withStatus(200).withBody(response).withHeader("Content-Type", ContentType.APPLICATION_JSON.toString())));
+		
+		String result = client.get("", new ParameterizedTypeReference<String>() {});
+		assertThat(result, equalTo(response));
+	}
+	
+	@Test
+	public void verifyMap() {
+		BaseClient<String, Map<String, Object>> client = new BaseClient<>();
+		String response = "{\"hello\" : \"world\"}";
+		client.setTargetUrl(UriBuilder.fromUri("http://localhost/test").port(wm.port()).build().toString());
+		wm.stubFor(get(urlEqualTo("/test"))
+                .willReturn(aResponse().withStatus(200).withBody(response).withHeader("Content-Type", ContentType.APPLICATION_JSON.toString())));
+		
+		Map<String, Object> result = client.get("", new ParameterizedTypeReference<Map<String, Object>>() {});
+		assertThat("world", equalTo(result.get("hello")));
+	}
+}
diff --git a/common/src/main/java/org/onap/so/client/RestClientSSL.java b/common/src/main/java/org/onap/so/client/RestClientSSL.java
index 461bb58..8eaeee9 100644
--- a/common/src/main/java/org/onap/so/client/RestClientSSL.java
+++ b/common/src/main/java/org/onap/so/client/RestClientSSL.java
@@ -72,23 +72,15 @@
 	private KeyStore getKeyStore() {
 		KeyStore ks = null;
 	    char[] password = System.getProperty(RestClientSSL.SSL_KEY_STORE_PASSWORD_KEY).toCharArray();
-	    FileInputStream fis = null;
-	    try {
+	    try(FileInputStream fis = new FileInputStream(System.getProperty(RestClientSSL.SSL_KEY_STORE_KEY))) {
 	    	ks = KeyStore.getInstance(KeyStore.getDefaultType());
-	        fis = new FileInputStream(System.getProperty(RestClientSSL.SSL_KEY_STORE_KEY));
+	        
 	        ks.load(fis, password);
 	    }
 	    catch(Exception e) {
 	    	return null;
 	    }
-	    finally {
-	        if (fis != null) {
-	            try { 
-	            	fis.close();
-	            }
-	            catch(Exception e) {}
-	        }
-	    }
+	    
 	    return ks;
 	}
 }
diff --git a/common/src/main/java/org/onap/so/serviceinstancebeans/RequestDetails.java b/common/src/main/java/org/onap/so/serviceinstancebeans/RequestDetails.java
index d713342..0364043 100644
--- a/common/src/main/java/org/onap/so/serviceinstancebeans/RequestDetails.java
+++ b/common/src/main/java/org/onap/so/serviceinstancebeans/RequestDetails.java
@@ -58,6 +58,8 @@
     protected LineOfBusiness lineOfBusiness;
 	@JsonProperty("instanceName")
 	private List<Map<String, String>> instanceName = new ArrayList<>();
+	@JsonProperty("configurationParameters")
+	protected List<Map<String, String>> configurationParameters = new ArrayList<>();
     
 
 	/**
@@ -290,14 +292,20 @@
 	public void setInstanceName(List<Map<String, String>> instanceName) {
 		this.instanceName = instanceName;
 	}
+	public List<Map<String, String>> getConfigurationParameters() {
+		return configurationParameters;
+	}
+
+	public void setConfigurationParameters(List<Map<String, String>> configurationParameters) {
+		this.configurationParameters = configurationParameters;
+	}
+
 	@Override
 	public String toString() {
-		return "RequestDetails [modelInfo=" + modelInfo + ", requestInfo="
-				+ requestInfo + ", relatedInstanceList="
-				+ Arrays.toString(relatedInstanceList) + ", subscriberInfo="
-				+ subscriberInfo + ", cloudConfiguration=" + cloudConfiguration
-				+ ", requestParameters=" + requestParameters + ", platform=" + platform 
-				+ ", lineOfBusiness=" + ", project=" + project + ", owningEntity=" + owningEntity 
-				+ ", instanceName" + instanceName + "]";
+		return "RequestDetails [modelInfo=" + modelInfo + ", requestInfo=" + requestInfo + ", relatedInstanceList="
+				+ Arrays.toString(relatedInstanceList) + ", subscriberInfo=" + subscriberInfo + ", cloudConfiguration="
+				+ cloudConfiguration + ", requestParameters=" + requestParameters + ", project=" + project
+				+ ", owningEntity=" + owningEntity + ", platform=" + platform + ", lineOfBusiness=" + lineOfBusiness
+				+ ", instanceName=" + instanceName + ", configurationParameters=" + configurationParameters + "]";
 	}
 }
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java
index 3eee14e..5b08cc1 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java
@@ -42,5 +42,6 @@
 	unassignInstance,
 	compareModel,
 	scaleInstance,
-	deactivateAndCloudDelete
+	deactivateAndCloudDelete,
+	scaleOut
 }
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/MsoRequest.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/MsoRequest.java
index 38b3dd6..66afcf3 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/MsoRequest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/MsoRequest.java
@@ -44,6 +44,7 @@
 import org.onap.so.apihandlerinfra.tasksbeans.TasksRequest;
 import org.onap.so.apihandlerinfra.validation.ApplyUpdatedConfigValidation;
 import org.onap.so.apihandlerinfra.validation.CloudConfigurationValidation;
+import org.onap.so.apihandlerinfra.validation.ConfigurationParametersValidation;
 import org.onap.so.apihandlerinfra.validation.InPlaceSoftwareUpdateValidation;
 import org.onap.so.apihandlerinfra.validation.InstanceIdMapValidation;
 import org.onap.so.apihandlerinfra.validation.ModelInfoValidation;
@@ -178,6 +179,7 @@
 	        rules.add(new PlatformLOBValidation());
 	        rules.add(new ProjectOwningEntityValidation());
 	        rules.add(new RelatedInstancesValidation());
+	        rules.add(new ConfigurationParametersValidation());
         } 
 	    if(reqVersion >= 7 && requestParameters != null && requestParameters.getUserParams() != null){
 	    	for(Map<String, Object> params : requestParameters.getUserParams()){
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java
index b241a51..ced69df 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java
@@ -525,6 +525,21 @@
 		Response response = serviceInstances(request, Action.deactivateAndCloudDelete, instanceIdMap, version, requestId, getRequestUri(requestContext));
 		return response;
 	}
+	
+	@POST
+	@Path("/{version:[vV][7]}/serviceInstances/{serviceInstanceId}/vnfs/{vnfInstanceId}/vfModules/scaleOut")
+	@Consumes(MediaType.APPLICATION_JSON)
+	@Produces(MediaType.APPLICATION_JSON)
+	@ApiOperation(value="VF Auto Scale Out",response=Response.class)
+	@Transactional
+	public Response scaleOutVfModule(String request,  @PathParam("version") String version, @PathParam("serviceInstanceId") String serviceInstanceId,
+                                           @PathParam("vnfInstanceId") String vnfInstanceId, @Context ContainerRequestContext requestContext) throws ApiException {
+		String requestId = getRequestId(requestContext);
+		HashMap<String, String> instanceIdMap = new HashMap<>();
+		instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+		instanceIdMap.put("vnfInstanceId", vnfInstanceId);
+		return serviceInstances(request, Action.scaleOut, instanceIdMap, version, requestId, getRequestUri(requestContext));
+	}
 
 
 	@POST
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/CloudConfigurationValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/CloudConfigurationValidation.java
index 4c7365b..f366c7e 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/CloudConfigurationValidation.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/CloudConfigurationValidation.java
@@ -53,7 +53,7 @@
 					(action == Action.enablePort || action == Action.disablePort || action == Action.activateInstance || action == Action.deactivateInstance)){
 				throw new ValidationException ("cloudConfiguration");
 			}
-			if(requestScope.equalsIgnoreCase(ModelType.vfModule.name()) && action == Action.deactivateAndCloudDelete){
+			if(requestScope.equalsIgnoreCase(ModelType.vfModule.name()) && (action == Action.deactivateAndCloudDelete || action == Action.scaleOut)){
 				throw new ValidationException("cloudConfiguration");
 			}
 		}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ConfigurationParametersValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ConfigurationParametersValidation.java
new file mode 100644
index 0000000..edd1b1a
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ConfigurationParametersValidation.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 org.onap.so.apihandlerinfra.validation;
+
+import java.util.List;
+import java.util.Map;
+
+import org.onap.so.apihandlerinfra.Action;
+import org.onap.so.apihandlerinfra.Actions;
+import org.onap.so.exceptions.ValidationException;
+import org.onap.so.serviceinstancebeans.ModelType;
+import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
+
+public class ConfigurationParametersValidation implements ValidationRule{
+    private static boolean empty(String s) {
+  	  return (s == null || s.trim().isEmpty());
+    }
+	@Override
+	public ValidationInformation validate(ValidationInformation info) throws ValidationException{
+    	ServiceInstancesRequest sir = info.getSir();
+		List<Map<String, String>> configParams = sir.getRequestDetails().getConfigurationParameters();
+		String requestScope = info.getRequestScope();
+		Actions action = info.getAction();
+		
+		if(requestScope.equalsIgnoreCase(ModelType.vfModule.name()) && action == Action.scaleOut && configParams.isEmpty()){
+			throw new ValidationException("configuration parameters");
+		}
+        return info;
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ModelInfoValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ModelInfoValidation.java
index 8ab7fcc..aa98d2a 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ModelInfoValidation.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ModelInfoValidation.java
@@ -23,6 +23,7 @@
 
 import org.onap.so.apihandlerinfra.Action;
 import org.onap.so.apihandlerinfra.Actions;
+import org.onap.so.apihandlerinfra.TestApi;
 import org.onap.so.exceptions.ValidationException;
 import org.onap.so.serviceinstancebeans.ModelInfo;
 import org.onap.so.serviceinstancebeans.ModelType;
@@ -73,19 +74,22 @@
                 (requestScope.equalsIgnoreCase(ModelType.configuration.name()) && (action == Action.activateInstance || action == Action.deactivateInstance))))) {
         	throw new ValidationException ("modelInvariantId");
         }
+        if(empty(modelInfo.getModelInvariantId()) && (requestScope.equalsIgnoreCase(ModelType.vfModule.name()) && action == Action.scaleOut)){
+        	throw new ValidationException("modelInvariantId");
+        }
 
         if (!empty (modelInfo.getModelInvariantId ()) && !UUIDChecker.isValidUUID (modelInfo.getModelInvariantId ())) {
         	throw new ValidationException ("modelInvariantId format");
         }
 
         if(reqVersion >= 4 && !(requestScope.equalsIgnoreCase(ModelType.configuration.name())) && empty (modelInfo.getModelName ()) && (action == Action.createInstance || action == Action.updateInstance || 
-        		action == Action.addRelationships || action == Action.removeRelationships || (action == Action.deleteInstance && (requestScope.equalsIgnoreCase (ModelType.vfModule.name ()))))){
+        		action == Action.addRelationships || action == Action.removeRelationships || ((action == Action.deleteInstance || action == Action.scaleOut) && (requestScope.equalsIgnoreCase (ModelType.vfModule.name ()))))){
         	throw new ValidationException ("modelName");
         }
 
         if (empty (modelInfo.getModelVersion ()) && !(requestScope.equalsIgnoreCase(ModelType.configuration.name())) && 
         		(!(reqVersion < 4 && requestScope.equalsIgnoreCase (ModelType.network.name ())) 
-        				&& (action == Action.createInstance || action == Action.updateInstance || action == Action.addRelationships || action == Action.removeRelationships))) {
+        				&& (action == Action.createInstance || action == Action.updateInstance || action == Action.addRelationships || action == Action.removeRelationships || action == Action.scaleOut))) {
         	throw new ValidationException ("modelVersion");
         }
 
@@ -95,6 +99,9 @@
         		(requestScope.equalsIgnoreCase(ModelType.configuration.name()) && (action == Action.activateInstance || action == Action.deactivateInstance))))) {
         	throw new ValidationException ("modelVersionId");
          }
+        if(empty(modelInfo.getModelVersionId()) && (requestScope.equalsIgnoreCase(ModelType.vfModule.name()) && action == Action.scaleOut)){
+        	throw new ValidationException("modelVersionId");
+        }
         
         if(requestScope.equalsIgnoreCase(ModelType.vnf.name()) && action != Action.deleteInstance && empty (modelInfo.getModelCustomizationName ())) {
         	if (!UUIDChecker.isValidUUID (modelInfo.getModelCustomizationId())) {
@@ -106,6 +113,9 @@
         		&& (action == Action.updateInstance || action == Action.createInstance)){
         	throw new ValidationException ("modelCustomizationId");
         }
+        if(empty(modelInfo.getModelCustomizationId()) && action == Action.scaleOut && !(requestParameters.getTestApi() == TestApi.VNF_API.name() && requestParameters.isUsePreload() == true)){
+        	throw new ValidationException ("modelCustomizationId");
+        }
         return info;
 	}
 }
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/RelatedInstancesValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/RelatedInstancesValidation.java
index 096b309..1f4fbc9 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/RelatedInstancesValidation.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/RelatedInstancesValidation.java
@@ -217,7 +217,8 @@
         }
         else if ((( requestScope.equalsIgnoreCase(ModelType.vnf.name ()) || requestScope.equalsIgnoreCase(ModelType.volumeGroup.name ()) || requestScope.equalsIgnoreCase(ModelType.vfModule.name ()) 
         			|| requestScope.equalsIgnoreCase(ModelType.configuration.name())) && (action == Action.createInstance || action == Action.enablePort || action == Action.disablePort)) ||
-        		(reqVersion >= 4 && (requestScope.equalsIgnoreCase(ModelType.volumeGroup.name ()) || requestScope.equalsIgnoreCase(ModelType.vfModule.name ())) && action == Action.updateInstance) ||
+        		(reqVersion >= 4 && (requestScope.equalsIgnoreCase(ModelType.volumeGroup.name ()) || requestScope.equalsIgnoreCase(ModelType.vfModule.name ())) && action == Action.updateInstance ||
+        		(requestScope.equalsIgnoreCase(ModelType.vfModule.name ()) && action == Action.scaleOut)) ||
         			(requestScope.equalsIgnoreCase(ModelType.service.name()) && (action.equals(Action.addRelationships) || action.equals(Action.removeRelationships)))){
         	 msoLogger.debug ("related instance exception");
         	throw new ValidationException ("related instances");
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/MsoRequestTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/MsoRequestTest.java
index 7feea9a..63dc96f 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/MsoRequestTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/MsoRequestTest.java
@@ -192,6 +192,7 @@
 			{"No valid cloudConfiguration is specified", mapper.readValue(inputStream("/CloudConfiguration/CloudConfigurationConfig.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.enablePort, 5},
 			{"No valid cloudConfiguration is specified", mapper.readValue(inputStream("/CloudConfiguration/InPlaceSoftwareUpdateCloudConfiguration.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.inPlaceSoftwareUpdate, 6},
 			{"No valid cloudConfiguration is specified", mapper.readValue(inputStream("/CloudConfiguration/DeactivateAndCloudDeleteCloudConfiguration.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.deactivateAndCloudDelete, 7},
+			{"No valid cloudConfiguration is specified", mapper.readValue(inputStream("/CloudConfiguration/ScaleOutNoCloudConfig.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid lcpCloudRegionId is specified", mapper.readValue(inputStream("/CloudConfiguration/EmptyLcpCloudConfiguration.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid lcpCloudRegionId is specified", mapper.readValue(inputStream("/CloudConfiguration/InPlaceSoftwareUpdateCloudRegionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.inPlaceSoftwareUpdate, 6},
 			{"No valid tenantId is specified", mapper.readValue(inputStream("/CloudConfiguration/EmptyTenantId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
@@ -206,6 +207,7 @@
 			{"No valid modelCustomizationId or modelCustomizationName is specified", mapper.readValue(inputStream("/ModelInfo/ModelCustomization.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.replaceInstance, 6},
 			{"No valid modelCustomizationId or modelCustomizationName is specified", mapper.readValue(inputStream("/ModelInfo/ModelCustomization.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.updateInstance, 6},
 			{"No valid modelCustomizationId or modelCustomizationName is specified", mapper.readValue(inputStream("/ModelInfo/VnfModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.replaceInstance, 5},
+			{"No valid modelCustomizationId is specified", mapper.readValue(inputStream("/ModelInfo/ScaleOutNoModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid model-info is specified", mapper.readValue(inputStream("/ModelInfo/ModelInfoNull.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid modelInvariantId format is specified", mapper.readValue(inputStream("/ModelInfo/InvalidModelInvariantId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 2},
 			{"No valid modelInvariantId is specified", mapper.readValue(inputStream("/ModelInfo/ModelInvariantId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.deactivateInstance, 4},
@@ -215,11 +217,14 @@
 			{"No valid modelInvariantId is specified", mapper.readValue(inputStream("/ModelInfo/ModelInvariantIdConfiguration.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 3},
 			{"No valid modelInvariantId is specified", mapper.readValue(inputStream("/ModelInfo/v5DeactivateModelInvariantId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.deactivateInstance, 5},
 			{"No valid modelInvariantId is specified", mapper.readValue(inputStream("/ModelInfo/v3UpdateNetworkBad.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.updateInstance, 4},
+			{"No valid modelInvariantId is specified", mapper.readValue(inputStream("/ModelInfo/ScaleOutNoModelInvariantId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid modelName is specified", mapper.readValue(inputStream("/ModelInfo/VfModuleModelName.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.deleteInstance, 4},
+			{"No valid modelName is specified", mapper.readValue(inputStream("/ModelInfo/ScaleOutNoModelName.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid modelType is specified", mapper.readValue(inputStream("/ModelInfo/ModelTypeNull.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid modelVersion is specified", mapper.readValue(inputStream("/ModelInfo/ModelVersionService.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.updateInstance, 3},
 			{"No valid modelVersion is specified", mapper.readValue(inputStream("/ModelInfo/ModelVersionVfModule.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 3},
 			{"No valid modelVersion is specified", mapper.readValue(inputStream("/ModelInfo/ModelVersionServiceCreate.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 3},
+			{"No valid modelVersion is specified", mapper.readValue(inputStream("/ModelInfo/ScaleOutNoModelVersion.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/ModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/ConfigurationModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 5},
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/v2ModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 4},
@@ -229,6 +234,7 @@
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/v2ModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.disablePort, 5},
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/ModelVersionIdCreate.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/v5ActivateModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 5},
+			{"No valid modelVersionId is specified", mapper.readValue(inputStream("/ModelInfo/ScaleOutNoModelVersionId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			//ValidationException for Platform and LineOfBusiness
 			{"No valid lineOfBusinessName is specified", mapper.readValue(inputStream("/PlatformAndLineOfBusiness/EmptyLineOfBusiness.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid platform is specified", mapper.readValue(inputStream("/PlatformAndLineOfBusiness/Platform.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 6},
@@ -261,6 +267,7 @@
 			{"No valid related instances is specified", mapper.readValue(inputStream("/RelatedInstances/v5EnablePortNoRelatedInstance.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.enablePort, 5},			
 			{"No valid related instances is specified", mapper.readValue(inputStream("/RelatedInstances/v5CreateNoRelatedInstances.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid related instances is specified", mapper.readValue(inputStream("/RelatedInstances/v4RelatedInstancesNull.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.updateInstance, 4},
+			{"No valid related instances is specified", mapper.readValue(inputStream("/RelatedInstances/ScaleOutNoRelatedInstances.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid related service instance for vfModule request is specified", mapper.readValue(inputStream("/RelatedInstances/VfModuleRelatedInstancesService.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 5},
 			{"No valid related service instance for vnf request is specified", mapper.readValue(inputStream("/RelatedInstances/VnfRelatedInstancesService.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 5},			
 			{"No valid related service instance for volumeGroup request is specified", mapper.readValue(inputStream("/RelatedInstances/RelatedInstancesServiceInstance.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.activateInstance, 5},
@@ -275,6 +282,7 @@
 			{"No valid requestInfo is specified", mapper.readValue(inputStream("/RequestInfo/RequestInfoNull.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 5},
 			{"No valid requestInfo is specified", mapper.readValue(inputStream("/RequestInfo/RequestInfo.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.applyUpdatedConfig, 6},
 			{"No valid requestInfo is specified", mapper.readValue(inputStream("/RequestInfo/RequestInfo.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.inPlaceSoftwareUpdate, 6},
+			{"No valid requestInfo is specified", mapper.readValue(inputStream("/RequestInfo/ScaleOutNoRequestInfo.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7},
 			{"No valid productFamilyId is specified", mapper.readValue(inputStream("/RequestInfo/VnfProductFamilyId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 3},
 			{"No valid productFamilyId is specified", mapper.readValue(inputStream("/RequestInfo/NetworkProductFamilyId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.createInstance, 3},
 			{"No valid productFamilyId is specified", mapper.readValue(inputStream("/RequestInfo/NetworkProductFamilyId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.updateInstance, 3},
@@ -310,7 +318,9 @@
 			{"No valid model-info in userParams network resources is specified", mapper.readValue(inputStream("/RequestParameters/Network.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.assignInstance, 7},	
 			{"No valid modelCustomizationId in userParams vfModule resources is specified", mapper.readValue(inputStream("/RequestParameters/VfModuleModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.assignInstance, 7},
 			{"No valid modelCustomizationId in userParams vnf resources is specified", mapper.readValue(inputStream("/RequestParameters/VnfModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.assignInstance, 7},
-			{"No valid modelCustomizationId in userParams network resources is specified", mapper.readValue(inputStream("/RequestParameters/NetworkModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.assignInstance, 7}
+			{"No valid modelCustomizationId in userParams network resources is specified", mapper.readValue(inputStream("/RequestParameters/NetworkModelCustomizationId.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.assignInstance, 7},
+			//Validation for ConfigurationParameters
+			{"No valid configuration parameters is specified", mapper.readValue(inputStream("/ConfigurationParameters/NoConfigurationParameters.json"), ServiceInstancesRequest.class), instanceIdMapTest, Action.scaleOut, 7}
 		});
 	}
 	@Test
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
index ef31851..48d424c 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java
@@ -1433,4 +1433,26 @@
         System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(request));
         assertThat(request, sameBeanAs(expected));
     }
+    @Test
+    public void scaleOutVfModule() throws JsonParseException, JsonMappingException, IOException {
+        stubFor(post(urlPathEqualTo("/mso/async/services/WorkflowActionBB"))
+                .willReturn(aResponse().withHeader("Content-Type", "application/json")
+                        .withBodyFile("Camunda/TestResponse.json").withStatus(org.apache.http.HttpStatus.SC_OK)));
+
+        //expected response
+        ServiceInstancesResponse expectedResponse = new ServiceInstancesResponse();
+        RequestReferences requestReferences = new RequestReferences();
+        requestReferences.setInstanceId("1882939");
+        expectedResponse.setRequestReferences(requestReferences);
+        uri = servInstanceuri + "v7" + "/serviceInstances/7a88cbeb-0ec8-4765-a271-4f9e90c3da7b/vnfs/cbba721b-4803-4df7-9347-307c9a955426/vfModules/scaleOut";
+        ResponseEntity<String> response = sendRequest(inputStream("/ScaleOutRequest.json"), uri, HttpMethod.POST);
+
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+        assertEquals(Response.Status.ACCEPTED.getStatusCode(), response.getStatusCode().value());
+        ServiceInstancesResponse realResponse = mapper.readValue(response.getBody(), ServiceInstancesResponse.class);
+        assertThat(realResponse, sameBeanAs(expectedResponse).ignoring("requestReferences.requestId"));	
+        assertTrue(response.getBody().contains("1882939"));
+    }
 }
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/CloudConfiguration/ScaleOutNoCloudConfig.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/CloudConfiguration/ScaleOutNoCloudConfig.json
new file mode 100644
index 0000000..1cc9150
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/CloudConfiguration/ScaleOutNoCloudConfig.json
@@ -0,0 +1,50 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ConfigurationParameters/NoConfigurationParameters.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ConfigurationParameters/NoConfigurationParameters.json
new file mode 100644
index 0000000..2f3f42e
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ConfigurationParameters/NoConfigurationParameters.json
@@ -0,0 +1,54 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "ff305d54-75b4-431b-adb2-eb6b9e5ff000",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "ff305d54-75b4-431b-adb2-eb6b9e5ff000",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelCustomizationId.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelCustomizationId.json
new file mode 100644
index 0000000..d1220ad
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelCustomizationId.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelInvariantId.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelInvariantId.json
new file mode 100644
index 0000000..9447250
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelInvariantId.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelName.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelName.json
new file mode 100644
index 0000000..ca60ffc
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelName.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersion.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersion.json
new file mode 100644
index 0000000..b9914d3
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersion.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionId.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionId.json
new file mode 100644
index 0000000..b4afcda
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionId.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionVersion.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionVersion.json
new file mode 100644
index 0000000..b9914d3
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/ModelInfo/ScaleOutNoModelVersionVersion.json
@@ -0,0 +1,53 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"requestInfo": {
+			"instanceName": "MSO-DEV-VF-1806BB-vSAMP10a-base-it2-1",
+			"source": "VID",
+			"suppressRollback": false,
+			"requestorId": "xxxxxx"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RelatedInstances/ScaleOutNoRelatedInstances.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RelatedInstances/ScaleOutNoRelatedInstances.json
new file mode 100644
index 0000000..47f49a7
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RelatedInstances/ScaleOutNoRelatedInstances.json
@@ -0,0 +1,34 @@
+{
+   "requestDetails":{
+      "modelInfo":{
+         "modelType":"vfModule",
+         "modelInvariantId":"ff5256d2-5a33-55df-13ab-12abad84e7ff",
+         "modelVersionId":"fe6478e5-ea33-3346-ac12-ab121484a3fe",
+         "modelCustomizationId":"cb82ffd8-252a-11e7-93ae-92361f002672",
+         "modelName":"vSAMP12..base..module-0",
+         "modelVersion":"1"
+      },
+      "cloudConfiguration":{
+         "lcpCloudRegionId":"mdt1",
+         "tenantId":"88a6ca3ee0394ade9403f075db23167e"
+      },
+      "requestInfo":{
+         "instanceName":"MSOTEST103a-vSAMP12_base_module-0",
+         "source":"VID",
+         "suppressRollback":true,
+         "requestorId":"xxxxxx"
+      },
+      "requestParameters":{
+         "usePreload":true,
+         "userParams":[
+
+         ]
+      },
+      "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/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestInfo/ScaleOutNoRequestInfo.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestInfo/ScaleOutNoRequestInfo.json
new file mode 100644
index 0000000..d403cc2
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestInfo/ScaleOutNoRequestInfo.json
@@ -0,0 +1,48 @@
+{
+	"requestDetails": {
+		"modelInfo": {
+			"modelType": "vfModule",
+			"modelName": "vSAMP10aDEV::base::module-0",
+			"modelVersionId": "20c4431c-246d-11e7-93ae-92361f002671",
+			"modelInvariantId": "78ca26d0-246d-11e7-93ae-92361f002671",
+			"modelVersion": "2",
+			"modelCustomizationId": "cb82ffd8-252a-11e7-93ae-92361f002671"
+		},
+		"cloudConfiguration": {
+			"lcpCloudRegionId": "mtn6",
+			"tenantId": "0422ffb57ba042c0800a29dc85ca70f8"
+		},
+		"relatedInstanceList": [
+		{
+			"relatedInstance": {
+				"instanceId": "7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+				"modelInfo": {
+					"modelType": "service",
+					"modelName": "MSOTADevInfra_vSAMP10a_Service",
+					"modelVersionId": "5df8b6de-2083-11e7-93ae-92361f002671",
+					"modelInvariantId": "9647dfc4-2083-11e7-93ae-92361f002671",
+					"modelVersion": "1.0"
+				}
+			}
+		},
+		{
+			"relatedInstance": {
+				"instanceId": "cbba721b-4803-4df7-9347-307c9a955426",
+				"modelInfo": {
+					"modelType": "vnf",
+					"modelName": "vSAMP10a",
+					"modelVersionId": "d40be095-940e-4738-a72a-59aa9eb5671e",
+					"modelInvariantId": "2fff5b20-214b-11e7-93ae-92361f002671",
+					"modelVersion": "1.0",
+					"modelCustomizationId": "68dc9a92-214c-11e7-93ae-92361f002671",
+					"modelCustomizationName": "vSAMP10a 1"
+				}
+			}
+		}
+		],
+		"requestParameters": {
+			"usePreload": true,
+			"userParams": []
+		}
+	}
+}
\ No newline at end of file
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ScaleOutRequest.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ScaleOutRequest.json
new file mode 100644
index 0000000..ba5a8a9
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ScaleOutRequest.json
@@ -0,0 +1,71 @@
+{
+   "requestDetails":{
+      "modelInfo":{
+         "modelType":"vfModule",
+         "modelInvariantId":"ff5256d2-5a33-55df-13ab-12abad84e7ff",
+         "modelVersionId":"fe6478e5-ea33-3346-ac12-ab121484a3fe",
+         "modelCustomizationId":"cb82ffd8-252a-11e7-93ae-92361f002672",
+         "modelName":"vSAMP12..base..module-0",
+         "modelVersion":"1"
+      },
+      "cloudConfiguration":{
+         "lcpCloudRegionId":"mdt1",
+         "tenantId":"88a6ca3ee0394ade9403f075db23167e"
+      },
+      "requestInfo":{
+         "instanceName":"MSOTEST103a-vSAMP12_base_module-0",
+         "source":"VID",
+         "suppressRollback":true,
+         "requestorId":"xxxxxx"
+      },
+      "relatedInstanceList":[
+         {
+            "relatedInstance":{
+               "instanceId":"cbba721b-4803-4df7-9347-307c9a955426",
+               "instanceName":"MSOTESTVOL103a-vSAMP12_base_module-0_vol",
+               "modelInfo":{
+                  "modelType":"volumeGroup"
+               }
+            }
+         },
+         {
+            "relatedInstance":{
+               "instanceId":"7a88cbeb-0ec8-4765-a271-4f9e90c3da7b",
+               "modelInfo":{
+                  "modelType":"service",
+                  "modelInvariantId":"ff3514e3-5a33-55df-13ab-12abad84e7ff",
+                  "modelVersionId":"fe6985cd-ea33-3346-ac12-ab121484a3fe",
+                  "modelName":"{parent service model name}",
+                  "modelVersion":"1.0"
+               }
+            }
+         },
+         {
+            "relatedInstance":{
+               "instanceId":"cbba721b-4803-4df7-9347-307c9a955426",
+               "modelInfo":{
+                  "modelType":"vnf",
+                  "modelInvariantId":"ff5256d1-5a33-55df-13ab-12abad84e7ff",
+                  "modelVersionId":"fe6478e4-ea33-3346-ac12-ab121484a3fe",
+                  "modelName":"vSAMP12",
+                  "modelVersion":"1.0",
+                  "modelCustomizationName":"vSAMP12 1",
+                  "modelCustomizationId":"a7f1d08e-b02d-11e6-80f5-76304dec7eb7"
+               }
+            }
+         }
+      ],
+      "requestParameters":{
+         "usePreload":true,
+         "userParams":[
+
+         ]
+      },
+      "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/mso-api-handlers/mso-api-handler-infra/src/test/resources/data.sql b/mso-api-handlers/mso-api-handler-infra/src/test/resources/data.sql
index 54984ee..70c0791 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/resources/data.sql
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/data.sql
@@ -224,8 +224,7 @@
 ('19', 'vfModule', 'vfModule', 'createInstance', '', '1', 'VID_DEFAULT recipe to create vf-module if no custom BPMN flow is found', '/mso/async/services/CreateVfModuleInfra', '', '180', '2016-09-14 19:18:20', '20c4431c-246d-11e7-93ae-92361f002672'),
 ('20', 'vfModule', 'vfModule', 'deleteInstance', '', '1', 'VID_DEFAULT recipe to delete vf-module if no custom BPMN flow is found', '/mso/async/services/DeleteVfModuleInfra', '', '180', '2016-09-14 19:18:20', 'VID_DEFAULT'),
 ('21', 'vfModule', 'vfModule', 'updateInstance', '', '1', 'VID_DEFAULT recipe to update vf-module if no custom BPMN flow is found', '/mso/async/services/UpdateVfModuleInfra', '', '180', '2016-09-14 19:18:20', 'VID_DEFAULT'),
-('25', 'vfModule', 'vfModule', 'replaceInstance', '', '1', 'VID_DEFAULT vfModule replace', '/mso/async/services/ReplaceVfModuleInfra', '', '180', '2017-07-28 18:25:06', 'VID_DEFAULT');               
-
+('25', 'vfModule', 'vfModule', 'replaceInstance', '', '1', 'VID_DEFAULT vfModule replace', '/mso/async/services/ReplaceVfModuleInfra', '', '180', '2017-07-28 18:25:06', 'VID_DEFAULT');
 
 INSERT INTO catalogdb.network_recipe(ID, MODEL_NAME, ACTION, DESCRIPTION, ORCHESTRATION_URI, NETWORK_PARAM_XSD, RECIPE_TIMEOUT, SERVICE_TYPE, CREATION_TIMESTAMP, VERSION_STR) VALUES
 ('17', 'VID_DEFAULT', 'createInstance', 'VID_DEFAULT recipe to create network if no custom BPMN flow is found', '/mso/async/services/CreateNetworkInstance', '', '180', '', '2016-09-14 19:18:20', '1.0'),
@@ -274,7 +273,9 @@
 ('vfModule', 'deleteInstance', '1', 'Gr api recipe to delete vf-module', '/mso/async/services/WorkflowActionBB', 180, 'GR-API-DEFAULT'),
 ('vfModule', 'updateInstance', '1', 'Gr api recipe to update vf-module', '/mso/async/services/WorkflowActionBB', 180, 'GR-API-DEFAULT'),
 ('vfModule', 'replaceInstance', '1', 'Gr api recipe to replace vf-module', '/mso/async/services/WorkflowActionBB', 180, 'GR-API-DEFAULT'),
-('vfModule', 'deactivateAndCloudDelete', '1', 'Gr api recipe to deactivateAndCloudDelete vf-module', '/mso/async/services/WorkflowActionBB', 180, 'GR-API-DEFAULT');
+('vfModule', 'deactivateAndCloudDelete', '1', 'Gr api recipe to deactivateAndCloudDelete vf-module', '/mso/async/services/WorkflowActionBB', 180, 'GR-API-DEFAULT'),
+('vfModule', 'scaleOut', '1', 'Gr api recipe to scale out vfModule', '/mso/async/services/WorkflowActionBB', '180', 'GR-API-DEFAULT');               
+
 
 UPDATE vnf_components_recipe
 SET vf_module_model_uuid = 'VNF-API-DEFAULT'