Initial commit of validation framework to APIH

Move ListenerRunner to common location
Adjust request params name, update junit tests
Update validations to work properly
Properly escape period for the string split

Issue-ID: SO-2232
Signed-off-by: Benjamin, Max (mb388a) <mb388a@att.com>
Change-Id: Ia468cf7062cccf30e28afeb7a5cddc37ceb2e002
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
index b6f3f82..2fddfd9 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/RequestHandlerUtils.java
@@ -479,24 +479,11 @@
             boolean isAlaCarte, Actions action) throws IOException {
         ObjectMapper mapper = new ObjectMapper();
         mapper.setSerializationInclusion(Include.NON_NULL);
-        if (msoRawRequest != null) {
-            ServiceInstancesRequest sir = mapper.readValue(msoRawRequest, ServiceInstancesRequest.class);
-            if (serviceInstRequest != null && serviceInstRequest.getRequestDetails() != null
-                    && serviceInstRequest.getRequestDetails().getRequestParameters() != null) {
-                if (!isAlaCarte && Action.createInstance.equals(action)) {
-                    sir.getRequestDetails()
-                            .setCloudConfiguration(serviceInstRequest.getRequestDetails().getCloudConfiguration());
-                    sir.getRequestDetails().getRequestParameters().setUserParams(
-                            serviceInstRequest.getRequestDetails().getRequestParameters().getUserParams());
-                }
-                sir.getRequestDetails().getRequestParameters()
-                        .setUsePreload(serviceInstRequest.getRequestDetails().getRequestParameters().getUsePreload());
-            }
-
-            logger.debug("Value as string: {}", mapper.writeValueAsString(sir));
-            return mapper.writeValueAsString(sir);
+        if (serviceInstRequest != null) {
+            return mapper.writeValueAsString(serviceInstRequest);
+        } else {
+            return msoRawRequest;
         }
-        return null;
     }
 
     public Optional<String> retrieveModelName(RequestParameters requestParams) {
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 5b827d9..b1d3898 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
@@ -51,6 +51,7 @@
 import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
 import org.onap.so.apihandlerinfra.infra.rest.handler.AbstractRestHandler;
+import org.onap.so.apihandlerinfra.infra.rest.validators.RequestValidatorListenerRunner;
 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
 import org.onap.so.constants.Status;
 import org.onap.so.db.catalog.beans.NetworkResource;
@@ -124,6 +125,9 @@
     @Autowired
     private RequestHandlerUtils requestHandlerUtils;
 
+    @Autowired
+    private RequestValidatorListenerRunner requestValidatorListenerRunner;
+
     @POST
     @Path("/{version:[vV][5-7]}/serviceInstances")
     @Consumes(MediaType.APPLICATION_JSON)
@@ -764,6 +768,13 @@
 
     public Response serviceInstances(String requestJSON, Actions action, HashMap<String, String> instanceIdMap,
             String version, String requestId, String requestUri) throws ApiException {
+        return serviceInstances(requestJSON, action, instanceIdMap, version, requestId, requestUri, null);
+
+    }
+
+    public Response serviceInstances(String requestJSON, Actions action, HashMap<String, String> instanceIdMap,
+            String version, String requestId, String requestUri, HashMap<String, String> queryParams)
+            throws ApiException {
         String serviceInstanceId;
         Boolean aLaCarte = null;
         ServiceInstancesRequest sir;
@@ -771,6 +782,8 @@
 
         sir = requestHandlerUtils.convertJsonToServiceInstanceRequest(requestJSON, action, requestId, requestUri);
         action = handleReplaceInstance(action, sir);
+        requestValidatorListenerRunner.runValidations(requestUri, instanceIdMap, sir, queryParams);
+
         String requestScope = requestHandlerUtils.deriveRequestScope(action, sir, requestUri);
         InfraActiveRequests currentActiveReq =
                 msoRequest.createRequestObject(sir, action, requestId, Status.IN_PROGRESS, requestJSON, requestScope);
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/AAIDataRetrieval.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/AAIDataRetrieval.java
new file mode 100644
index 0000000..344e543
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/AAIDataRetrieval.java
@@ -0,0 +1,85 @@
+package org.onap.so.apihandlerinfra.infra.rest;
+
+import java.util.Optional;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.L3Network;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.aai.domain.yang.VfModule;
+import org.onap.aai.domain.yang.VolumeGroup;
+import org.onap.so.apihandlerinfra.infra.rest.exception.AAIEntityNotFound;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.AAIResourcesClient;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
+import org.onap.so.client.aai.entities.uri.AAIUriFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AAIDataRetrieval {
+
+    private static final String VF_MODULE_NOT_FOUND_IN_INVENTORY_VNF_ID = "VF Module Not Found In Inventory, VnfId: ";
+
+    private AAIResourcesClient aaiResourcesClient;
+
+    private static final Logger logger = LoggerFactory.getLogger(AAIDataRetrieval.class);
+
+    public ServiceInstance getServiceInstance(String serviceInstanceId) {
+        return this.getAaiResourcesClient()
+                .get(ServiceInstance.class,
+                        AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId))
+                .orElseGet(() -> {
+                    logger.debug("No Service Instance found in A&AI ServiceInstanceId: {}", serviceInstanceId);
+                    return null;
+                });
+    }
+
+
+    public VfModule getAAIVfModule(String vnfId, String vfModuleId) {
+        return this.getAaiResourcesClient()
+                .get(VfModule.class, AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId))
+                .orElseGet(() -> {
+                    logger.debug("No Vf Module found in A&AI VnfId: {}" + ", VfModuleId: {}", vnfId, vfModuleId);
+                    return null;
+                });
+    }
+
+    public GenericVnf getGenericVnf(String vnfId) {
+        return this.getAaiResourcesClient()
+                .get(GenericVnf.class, AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId))
+                .orElseGet(() -> {
+                    logger.debug("No Generic VNF found in A&AI VnfId: {}", vnfId);
+                    return null;
+                });
+    }
+
+    public VolumeGroup getVolumeGroup(String vnfId, String volumeGroupId) throws AAIEntityNotFound {
+        AAIResultWrapper wrapper =
+                this.getAaiResourcesClient().get(AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId)
+                        .relatedTo(AAIObjectType.VOLUME_GROUP, volumeGroupId));
+        Optional<VolumeGroup> volume = wrapper.asBean(VolumeGroup.class);
+        if (volume.isPresent()) {
+            return volume.get();
+        } else {
+            logger.debug("No VolumeGroup in A&AI found: {}", vnfId);
+            return null;
+        }
+    }
+
+    public L3Network getNetwork(String networkId) {
+        return this.getAaiResourcesClient()
+                .get(L3Network.class, AAIUriFactory.createResourceUri(AAIObjectType.L3_NETWORK, networkId))
+                .orElseGet(() -> {
+                    logger.debug("No Network found in A&AI NetworkId: {}", networkId);
+                    return null;
+                });
+    }
+
+    protected AAIResourcesClient getAaiResourcesClient() {
+        if (aaiResourcesClient == null) {
+            aaiResourcesClient = new AAIResourcesClient();
+        }
+        return aaiResourcesClient;
+    }
+
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilder.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilder.java
index bb5b4ed..ee2bb58 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilder.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilder.java
@@ -33,10 +33,7 @@
 import org.onap.so.apihandlerinfra.infra.rest.exception.AAIEntityNotFound;
 import org.onap.so.apihandlerinfra.infra.rest.exception.CloudConfigurationNotFoundException;
 import org.onap.so.client.aai.AAIObjectType;
-import org.onap.so.client.aai.AAIResourcesClient;
 import org.onap.so.client.aai.entities.AAIResultWrapper;
-import org.onap.so.client.aai.entities.uri.AAIResourceUri;
-import org.onap.so.client.aai.entities.uri.AAIUriFactory;
 import org.onap.so.constants.Status;
 import org.onap.so.db.request.beans.InfraActiveRequests;
 import org.onap.so.db.request.client.RequestsDbClient;
@@ -75,17 +72,19 @@
     @Autowired
     private RequestsDbClient infraActiveRequestsClient;
 
+    @Autowired
+    private AAIDataRetrieval aaiDataRet;
+
     private ObjectMapper mapper = new ObjectMapper();
 
-    private AAIResourcesClient aaiResourcesClient;
 
     public ServiceInstancesRequest buildVFModuleDeleteRequest(String vnfId, String vfModuleId, ModelType modelType)
             throws AAIEntityNotFound {
-        GenericVnf vnf = getGenericVnf(vnfId);
+        GenericVnf vnf = aaiDataRet.getGenericVnf(vnfId);
         if (vnf == null) {
             throw new AAIEntityNotFound(GENERIC_VNF_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId);
         }
-        VfModule vfModule = getAAIVfModule(vnfId, vfModuleId);
+        VfModule vfModule = aaiDataRet.getAAIVfModule(vnfId, vfModuleId);
         if (vfModule == null) {
             throw new AAIEntityNotFound(VF_MODULE_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId + " vfModuleId: " + vfModuleId);
         }
@@ -94,11 +93,11 @@
 
     public ServiceInstancesRequest buildVolumeGroupDeleteRequest(String vnfId, String volumeGroupId)
             throws AAIEntityNotFound {
-        GenericVnf vnf = getGenericVnf(vnfId);
+        GenericVnf vnf = aaiDataRet.getGenericVnf(vnfId);
         if (vnf == null) {
             throw new AAIEntityNotFound(GENERIC_VNF_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId);
         }
-        VolumeGroup volumeGroup = getVolumeGroup(vnfId, volumeGroupId);
+        VolumeGroup volumeGroup = aaiDataRet.getVolumeGroup(vnfId, volumeGroupId);
         if (volumeGroup == null) {
             throw new AAIEntityNotFound(
                     VF_MODULE_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId + " volumeGroupId: " + volumeGroupId);
@@ -107,7 +106,7 @@
     }
 
     public ServiceInstancesRequest buildServiceDeleteRequest(String serviceInstanceId) throws AAIEntityNotFound {
-        ServiceInstance serviceInstance = getServiceInstance(serviceInstanceId);
+        ServiceInstance serviceInstance = aaiDataRet.getServiceInstance(serviceInstanceId);
         if (serviceInstance == null) {
             throw new AAIEntityNotFound(
                     "ServiceInstance Not Found In Inventory, ServiceInstanceId: " + serviceInstanceId);
@@ -116,7 +115,7 @@
     }
 
     public ServiceInstancesRequest buildVnfDeleteRequest(String vnfId) throws AAIEntityNotFound {
-        GenericVnf vnf = getGenericVnf(vnfId);
+        GenericVnf vnf = aaiDataRet.getGenericVnf(vnfId);
         if (vnf == null) {
             throw new AAIEntityNotFound(GENERIC_VNF_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId);
         }
@@ -124,7 +123,7 @@
     }
 
     public ServiceInstancesRequest buildNetworkDeleteRequest(String networkId) throws AAIEntityNotFound {
-        L3Network network = getNetwork(networkId);
+        L3Network network = aaiDataRet.getNetwork(networkId);
         if (network == null) {
             throw new AAIEntityNotFound("Network Not Found In Inventory, NetworkId: " + networkId);
         }
@@ -407,72 +406,5 @@
         return requestParams;
     }
 
-    public VfModule getAAIVfModule(String vnfId, String vfModuleId) {
-        return this.getAaiResourcesClient()
-                .get(VfModule.class, AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId))
-                .orElseGet(() -> {
-                    logger.debug("No Vf Module found in A&AI VnfId: {}" + ", VfModuleId: {}", vnfId, vfModuleId);
-                    return null;
-                });
-    }
-
-    public GenericVnf getGenericVnf(String vnfId) {
-        return this.getAaiResourcesClient()
-                .get(GenericVnf.class, AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId))
-                .orElseGet(() -> {
-                    logger.debug("No Generic VNF found in A&AI VnfId: {}", vnfId);
-                    return null;
-                });
-    }
-
-    public VolumeGroup getVolumeGroup(String vnfId, String volumeGroupId) throws AAIEntityNotFound {
-        GenericVnf vnf = getGenericVnf(vnfId);
-        AAIResultWrapper wrapper = new AAIResultWrapper(vnf);
-        List<AAIResourceUri> listVserverWrapper;
-        Optional<AAIResourceUri> volumeGroupURI;
-        if (wrapper.getRelationships().isPresent()) {
-            listVserverWrapper = wrapper.getRelationships().get().getRelatedUris(AAIObjectType.VOLUME_GROUP);
-            volumeGroupURI = listVserverWrapper.stream()
-                    .filter(resourceURI -> resourceURI.getURIKeys().get("volume-group-id").equals(volumeGroupId))
-                    .findFirst();
-        } else {
-            throw new AAIEntityNotFound(
-                    VF_MODULE_NOT_FOUND_IN_INVENTORY_VNF_ID + vnfId + " volumeGroupId: " + volumeGroupId);
-        }
-        return this.getAaiResourcesClient().get(VolumeGroup.class, volumeGroupURI.get()).orElseGet(() -> {
-            logger.debug("No VolumeGroup in A&AI found: {}", vnfId);
-            return null;
-        });
-    }
-
-    public ServiceInstance getServiceInstance(String serviceInstanceId) {
-        return this.getAaiResourcesClient()
-                .get(ServiceInstance.class,
-                        AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE, serviceInstanceId))
-                .orElseGet(() -> {
-                    logger.debug("No Service Instance found in A&AI ServiceInstanceId: {}", serviceInstanceId);
-                    return null;
-                });
-    }
-
-    public L3Network getNetwork(String networkId) {
-        return this.getAaiResourcesClient()
-                .get(L3Network.class, AAIUriFactory.createResourceUri(AAIObjectType.L3_NETWORK, networkId))
-                .orElseGet(() -> {
-                    logger.debug("No Network found in A&AI NetworkId: {}", networkId);
-                    return null;
-                });
-    }
-
-    public AAIResourcesClient getAaiResourcesClient() {
-        if (aaiResourcesClient == null) {
-            aaiResourcesClient = new AAIResourcesClient();
-        }
-        return aaiResourcesClient;
-    }
-
-    public void setAaiResourcesClient(AAIResourcesClient aaiResourcesClient) {
-        this.aaiResourcesClient = aaiResourcesClient;
-    }
 
 }
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidator.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidator.java
new file mode 100644
index 0000000..4aa6015
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidator.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. 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.infra.rest.validators;
+
+import java.util.Map;
+import java.util.Optional;
+import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
+
+public interface RequestValidator {
+
+
+    /**
+     * Should this validator run for given request
+     * 
+     * @return
+     */
+    public boolean shouldRunFor(String uri, ServiceInstancesRequest request);
+
+
+    public Optional<String> validate(Map<String, String> instanceIdMap, ServiceInstancesRequest request,
+            Map<String, String> queryParams);
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidatorListenerRunner.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidatorListenerRunner.java
new file mode 100644
index 0000000..d689c6b
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/infra/rest/validators/RequestValidatorListenerRunner.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. 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.infra.rest.validators;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
+import org.javatuples.Pair;
+import org.onap.so.apihandlerinfra.exceptions.ApiException;
+import org.onap.so.apihandlerinfra.exceptions.ValidateException;
+import org.onap.so.listener.ListenerRunner;
+import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RequestValidatorListenerRunner extends ListenerRunner {
+
+    private static Logger logger = LoggerFactory.getLogger(RequestValidatorListenerRunner.class);
+
+    protected List<RequestValidator> requestValidators;
+
+    @PostConstruct
+    protected void init() {
+        requestValidators = new ArrayList<>(
+                Optional.ofNullable(context.getBeansOfType(RequestValidator.class)).orElse(new HashMap<>()).values());
+    }
+
+    public boolean runValidations(String requestURI, Map<String, String> instanceIdMap, ServiceInstancesRequest request,
+            Map<String, String> queryParams) throws ApiException {
+        logger.info("Running local validations");
+        List<Pair<String, Optional<String>>> results =
+                runValidations(requestValidators, instanceIdMap, request, queryParams, requestURI);
+        if (!results.isEmpty()) {
+            throw new ValidateException("Failed Validations:\n"
+                    + results.stream().map(item -> String.format("%s: %s", item.getValue0(), item.getValue1().get()))
+                            .collect(Collectors.joining("\n")),
+                    400);
+        }
+
+        return true;
+    }
+
+    protected List<Pair<String, Optional<String>>> runValidations(List<? extends RequestValidator> validators,
+            Map<String, String> instanceIdMap, ServiceInstancesRequest request, Map<String, String> queryParams,
+            String requestURI) {
+
+        List<? extends RequestValidator> filtered =
+                filterListeners(validators, (item -> item.shouldRunFor(requestURI, request)));
+
+        List<Pair<String, Optional<String>>> results = new ArrayList<>();
+        filtered.forEach(item -> results
+                .add(new Pair<>(item.getClass().getName(), item.validate(instanceIdMap, request, queryParams))));
+
+        return results.stream().filter(item -> item.getValue1().isPresent()).collect(Collectors.toList());
+    }
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/PlatformLOBValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/PlatformLOBValidation.java
index 71405b0..20be2b5 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/PlatformLOBValidation.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/PlatformLOBValidation.java
@@ -43,7 +43,8 @@
 
         platform = info.getSir().getRequestDetails().getPlatform();
         lineOfBusiness = info.getSir().getRequestDetails().getLineOfBusiness();
-        if (reqVersion >= 5 && requestScope.equalsIgnoreCase(ModelType.vnf.name()) && action == Action.createInstance) {
+        if (reqVersion >= 5 && requestScope.equalsIgnoreCase(ModelType.vnf.name()) && action == Action.createInstance
+                && !info.getReqParameters().getEnforceValidNfValues()) {
             if (reqVersion > 5 && platform == null) {
                 throw new ValidationException("platform");
             }
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ProjectOwningEntityValidation.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ProjectOwningEntityValidation.java
index 5842697..cebbd63 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ProjectOwningEntityValidation.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/ProjectOwningEntityValidation.java
@@ -41,10 +41,12 @@
         String requestScope = info.getRequestScope();
         Actions action = info.getAction();
 
+
         project = info.getSir().getRequestDetails().getProject();
         owningEntity = info.getSir().getRequestDetails().getOwningEntity();
         if (reqVersion >= 5 && requestScope.equalsIgnoreCase(ModelType.service.name())
-                && action == Action.createInstance || action == Action.assignInstance) {
+                && !info.getReqParameters().getEnforceValidNfValues() && action == Action.createInstance
+                || action == Action.assignInstance) {
             if (reqVersion > 5 && owningEntity == null) {
                 throw new ValidationException("owningEntity");
             }
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 e28e36d..a79aeb2 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
@@ -2934,15 +2934,5 @@
         Actions action = servInstances.handleReplaceInstance(Action.replaceInstance, sir);
         assertEquals(Action.replaceInstanceRetainAssignments, action);
     }
-    /*
-     * @Test public void buildSelfLinkUrlTest() throws Exception { // v - version String incomingUrl =
-     * "http://localhost:8080/onap/infra/so/serviceInstantiation/v7/serviceInstances"; String expectedSelfLink =
-     * "http://localhost:8080/orchestrationRequests/v7/efce3167-5e45-4666-9d4d-22e23648e5d1"; String requestId =
-     * "efce3167-5e45-4666-9d4d-22e23648e5d1"; Optional<URL> actualSelfLinkUrl = buildSelfLinkUrl(incomingUrl,
-     * requestId); assertEquals(expectedSelfLink, actualSelfLinkUrl.get().toString()); // V - Version String
-     * incomingUrlV = "http://localhost:8080/onap/infra/so/serviceInstantiation/V7/serviceInstances"; String
-     * expectedSelfLinkV = "http://localhost:8080/orchestrationRequests/V7/efce3167-5e45-4666-9d4d-22e23648e5d1";
-     * Optional<URL> actualSelfLinkUrlV = buildSelfLinkUrl(incomingUrlV, requestId); assertEquals(expectedSelfLinkV,
-     * actualSelfLinkUrlV.get().toString()); }
-     */
 }
+
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilderTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilderTest.java
index 3644dd8..f73da49 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilderTest.java
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/infra/rest/BpmnRequestBuilderTest.java
@@ -23,6 +23,7 @@
 import static com.shazam.shazamcrest.MatcherAssert.assertThat;
 import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import java.io.File;
 import java.util.Optional;
 import org.junit.Before;
@@ -32,7 +33,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
-import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.onap.aai.domain.yang.GenericVnf;
 import org.onap.aai.domain.yang.ServiceInstance;
@@ -40,6 +40,7 @@
 import org.onap.aai.domain.yang.VolumeGroup;
 import org.onap.so.client.aai.AAIObjectType;
 import org.onap.so.client.aai.AAIResourcesClient;
+import org.onap.so.client.aai.entities.AAIResultWrapper;
 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
 import org.onap.so.client.graphinventory.GraphInventoryCommonObjectMapperProvider;
 import org.onap.so.db.request.client.RequestsDbClient;
@@ -55,15 +56,19 @@
     @Rule
     public ExpectedException exceptionRule = ExpectedException.none();
 
+
+    @Mock
+    private AAIResourcesClient aaiResourcesClient;
+
     @InjectMocks
-    @Spy
-    BpmnRequestBuilder reqBuilder;
+    private AAIDataRetrieval aaiData = spy(AAIDataRetrieval.class);
 
     @Mock
     private RequestsDbClient requestDBClient;
 
-    @Mock
-    private AAIResourcesClient aaiResourcesClient;
+    @InjectMocks
+    private BpmnRequestBuilder reqBuilder = spy(BpmnRequestBuilder.class);
+
 
     private ObjectMapper mapper = new ObjectMapper();
 
@@ -71,8 +76,7 @@
 
     @Before
     public void setup() {
-        reqBuilder.setAaiResourcesClient(aaiResourcesClient);
-
+        // aaiData.setAaiResourcesClient(aaiResourcesClient);
     }
 
     @Test
@@ -80,11 +84,11 @@
         ServiceInstance service =
                 provider.getMapper().readValue(new File(RESOURCE_PATH + "ServiceInstance.json"), ServiceInstance.class);
 
-        doReturn(service).when(reqBuilder).getServiceInstance("serviceId");
+        doReturn(service).when(aaiData).getServiceInstance("serviceId");
         ServiceInstancesRequest expectedRequest = mapper
                 .readValue(new File(RESOURCE_PATH + "ExpectedServiceRequest.json"), ServiceInstancesRequest.class);
-        expectedRequest.getRequestDetails().getModelInfo().setModelId(null);
-        // bad getter/setter setting multiple fields
+        expectedRequest.getRequestDetails().getModelInfo().setModelId(null); // bad getter/setter setting multiple
+                                                                             // fields
         ServiceInstancesRequest actualRequest = reqBuilder.buildServiceDeleteRequest("serviceId");
         assertThat(actualRequest, sameBeanAs(expectedRequest));
     }
@@ -128,13 +132,16 @@
                 AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, "vnfId"));
         VolumeGroup volumeGroup =
                 provider.getMapper().readValue(new File(RESOURCE_PATH + "VolumeGroup.json"), VolumeGroup.class);
-
-        doReturn(Optional.of(volumeGroup)).when(aaiResourcesClient).get(VolumeGroup.class, AAIUriFactory
-                .createResourceUri(AAIObjectType.VOLUME_GROUP, "cloudOwner", "regionOne", "volumeGroupId"));
+        AAIResultWrapper wrapper = new AAIResultWrapper(volumeGroup);
+        doReturn(wrapper).when(aaiResourcesClient)
+                .get(AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, "vnfId")
+                        .relatedTo(AAIObjectType.VOLUME_GROUP, "volumeGroupId"));
 
         ServiceInstancesRequest expectedRequest = mapper
                 .readValue(new File(RESOURCE_PATH + "ExpectedVolumeGroupRequest.json"), ServiceInstancesRequest.class);
         ServiceInstancesRequest actualRequest = reqBuilder.buildVolumeGroupDeleteRequest("vnfId", "volumeGroupId");
         assertThat(actualRequest, sameBeanAs(expectedRequest));
     }
+
 }
+
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ServiceInstanceNoOE.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ServiceInstanceNoOE.json
new file mode 100644
index 0000000..a6aa3e1
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ServiceInstanceNoOE.json
@@ -0,0 +1,33 @@
+{
+	"serviceInstanceId":"1882939",
+	"vnfInstanceId":"1882938",
+	"networkInstanceId":"1882937",
+	"volumeGroupInstanceId":"1882935",
+	"vfModuleInstanceId":"1882934",
+	"requestDetails": {
+		"requestInfo": {
+			"source": "VID", 
+			"requestorId": "xxxxxx",
+			"instanceName": "testService9"
+		},
+		"requestParameters": {
+			"aLaCarte": true,
+			"autoBuildVfModules": false,
+			"subscriptionServiceType": "test",
+			"disableOwningEntityProject": true
+		},
+		"modelInfo":{
+			"modelInvariantId": "f7ce78bb-423b-11e7-93f8-0050569a7965",
+			"modelVersion":"1", 
+			"modelVersionId":"10", 
+			"modelType":"service",
+			"modelName":"serviceModel",
+			"modelInstanceName":"modelInstanceName",
+			"modelCustomizationId":"f7ce78bb-423b-11e7-93f8-0050569a796"
+		},
+	 	"subscriberInfo": {
+		"globalSubscriberId": "someTestId", 
+		"subscriberName": "someTestId"
+    	}
+  	}
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/__files/infra/Vnf.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/__files/infra/Vnf.json
index 09f6d81..0b03f56 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/resources/__files/infra/Vnf.json
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/__files/infra/Vnf.json
@@ -101,7 +101,7 @@
 					},
 					{
 						"relationship-key": "volume-group.volume-group-id",
-						"relationship-value": "18b220c8-af84-4b82-a8c0-41bbea6328a6"
+						"relationship-value": "volumeGroupId"
 					}
 				]
 			},
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/schema.sql b/mso-api-handlers/mso-api-handler-infra/src/test/resources/schema.sql
index 731d2be..ee53e49 100644
--- a/mso-api-handlers/mso-api-handler-infra/src/test/resources/schema.sql
+++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/schema.sql
@@ -1111,6 +1111,7 @@
   `CREATION_TIMESTAMP` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `VNF_RESOURCE_MODEL_UUID` varchar(200) NOT NULL,
   `SERVICE_MODEL_UUID` varchar(200) NOT NULL,
+  `NF_DATA_VALID` tinyint(1) DEFAULT '0',
   `VNFCINSTANCEGROUP_ORDER` varchar(200) default NULL,
   PRIMARY KEY (`ID`),
   UNIQUE KEY `UK_vnf_resource_customization` (`MODEL_CUSTOMIZATION_UUID`,`SERVICE_MODEL_UUID`),