Merge "Create Pre Building Block validator"
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / onap / so / apihandlerinfra / ServiceInstances.java
index 676dca1..e3b218b 100644 (file)
@@ -44,6 +44,7 @@ import org.onap.so.apihandler.common.ResponseHandler;
 import org.onap.so.apihandlerinfra.exceptions.ApiException;
 import org.onap.so.apihandlerinfra.exceptions.BPMNFailureException;
 import org.onap.so.apihandlerinfra.exceptions.ClientConnectionException;
+import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException;
 import org.onap.so.apihandlerinfra.exceptions.DuplicateRequestException;
 import org.onap.so.apihandlerinfra.exceptions.RecipeNotFoundException;
 import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
@@ -51,6 +52,7 @@ import org.onap.so.apihandlerinfra.exceptions.ValidateException;
 import org.onap.so.apihandlerinfra.exceptions.VfModuleNotFoundException;
 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
 import org.onap.so.db.catalog.beans.NetworkResource;
+import org.onap.so.db.catalog.beans.NetworkResourceCustomization;
 import org.onap.so.db.catalog.beans.Recipe;
 import org.onap.so.db.catalog.beans.ServiceRecipe;
 import org.onap.so.db.catalog.beans.VfModule;
@@ -62,6 +64,7 @@ import org.onap.so.db.catalog.client.CatalogDbClient;
 import org.onap.so.db.request.beans.InfraActiveRequests;
 import org.onap.so.db.request.client.RequestsDbClient;
 import org.onap.so.exceptions.ValidationException;
+import org.onap.so.logger.LogConstants;
 import org.onap.so.logger.MessageEnum;
 import org.onap.so.logger.MsoLogger;
 import org.onap.so.serviceinstancebeans.CloudConfiguration;
@@ -78,10 +81,21 @@ import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
 import org.onap.so.serviceinstancebeans.ServiceInstancesResponse;
 import org.onap.so.serviceinstancebeans.VfModules;
 import org.onap.so.serviceinstancebeans.Vnfs;
+import org.onap.so.utils.CryptoUtils;
 import org.onap.so.utils.UUIDChecker;
+import org.slf4j.MDC;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpStatusCodeException;
+import org.springframework.web.client.RestTemplate;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
 
 import javax.transaction.Transactional;
 import javax.ws.rs.Consumes;
@@ -96,8 +110,10 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import javax.xml.bind.DatatypeConverter;
 import java.io.IOException;
 import java.net.URL;
+import java.security.GeneralSecurityException;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -133,6 +149,9 @@ public class ServiceInstances {
        @Autowired
        private MsoRequest msoRequest;
        
+       @Autowired
+       private RestTemplate restTemplate;
+       
        @POST
     @Path("/{version:[vV][5-7]}/serviceInstances")
        @Consumes(MediaType.APPLICATION_JSON)
@@ -666,6 +685,8 @@ public class ServiceInstances {
 
        public String getRequestUri(ContainerRequestContext context){
                String requestUri = context.getUriInfo().getPath();
+               String httpUrl = MDC.get(LogConstants.URI_BASE).concat(requestUri);
+               MDC.put(LogConstants.HTTP_URL, httpUrl);
                requestUri = requestUri.substring(requestUri.indexOf("/serviceInstantiation/") + 22);
                return requestUri;
        }
@@ -714,11 +735,15 @@ public class ServiceInstances {
                }
                
                InfraActiveRequests dup = null;
-                               
+               boolean inProgress = false;             
 
                dup = duplicateCheck(action, instanceIdMap, startTime, msoRequest, instanceName,requestScope, currentActiveReq);
 
-               if (dup != null) {
+               if(dup != null){
+                       inProgress = camundaHistoryCheck(dup, currentActiveReq);
+               }
+               
+               if (dup != null && inProgress) {
             buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, startTime, msoRequest, instanceName, requestScope, dup);
                }
                ServiceInstancesResponse serviceResponse = new ServiceInstancesResponse();
@@ -877,8 +902,13 @@ public class ServiceInstances {
                }
                
                InfraActiveRequests dup = duplicateCheck(action, instanceIdMap, startTime, msoRequest, null, requestScope, currentActiveReq);
-
-               if (dup != null) {
+               boolean inProgress = false;
+               
+               if(dup != null){
+                       inProgress = camundaHistoryCheck(dup, currentActiveReq);
+               }
+               
+               if (dup != null && inProgress) {
             buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, startTime, msoRequest, null, requestScope, dup);
                }
                
@@ -1145,6 +1175,49 @@ public class ServiceInstances {
                }
                return dup;
        }
+    protected boolean camundaHistoryCheck(InfraActiveRequests duplicateRecord, InfraActiveRequests currentActiveReq) throws RequestDbFailureException, ContactCamundaException{
+       String requestId = duplicateRecord.getRequestId();
+       String path = env.getProperty("mso.camunda.rest.history.uri") + requestId;
+       String targetUrl = env.getProperty("mso.camundaURL") + path;
+       HttpHeaders headers = setCamundaHeaders(env.getRequiredProperty("mso.camundaAuth"), env.getRequiredProperty("mso.msoKey")); 
+       HttpEntity<?> requestEntity = new HttpEntity<>(headers);
+       ResponseEntity<List<HistoricProcessInstanceEntity>> response = null;
+       try{
+               response = restTemplate.exchange(targetUrl, HttpMethod.GET, requestEntity, new ParameterizedTypeReference<List<HistoricProcessInstanceEntity>>(){});
+       }catch(HttpStatusCodeException e){
+               ErrorLoggerInfo errorLoggerInfo = new ErrorLoggerInfo.Builder(MessageEnum.APIH_DUPLICATE_CHECK_EXC, MsoLogger.ErrorCode.DataError).errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
+            ContactCamundaException contactCamundaException= new ContactCamundaException.Builder(requestId, e.toString(), HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
+                    .errorInfo(errorLoggerInfo).build();
+            updateStatus(currentActiveReq, Status.FAILED, contactCamundaException.getMessage());
+            throw contactCamundaException;
+               }
+       if(response.getBody().isEmpty()){
+               updateStatus(duplicateRecord, Status.COMPLETE, "Request Completed");
+       }
+               for(HistoricProcessInstance instance : response.getBody()){
+                       if(instance.getState().equals("ACTIVE")){
+                               return true;
+                       }else{
+                               updateStatus(duplicateRecord, Status.COMPLETE, "Request Completed");
+                       }
+       }       
+               return false;
+       }
+    protected HttpHeaders setCamundaHeaders(String auth, String msoKey) {
+               HttpHeaders headers = new HttpHeaders();
+               List<org.springframework.http.MediaType> acceptableMediaTypes = new ArrayList<>();
+               acceptableMediaTypes.add(org.springframework.http.MediaType.APPLICATION_JSON);
+               headers.setAccept(acceptableMediaTypes);
+               try {
+                       String userCredentials = CryptoUtils.decrypt(auth, msoKey);
+                       if(userCredentials != null) {
+                               headers.add(HttpHeaders.AUTHORIZATION, "Basic " + DatatypeConverter.printBase64Binary(userCredentials.getBytes()));
+                       }
+        } catch(GeneralSecurityException e) {
+                msoLogger.error("Security exception", e);
+        }
+               return headers;
+       }
 
        private ServiceInstancesRequest convertJsonToServiceInstanceRequest(String requestJSON, Actions action, long startTime,
                                                                         ServiceInstancesRequest sir, MsoRequest msoRequest, String requestId, String requestUri) throws ApiException {
@@ -1668,7 +1741,9 @@ public class ServiceInstances {
                Recipe recipe = null;
 
                if(modelInfo.getModelCustomizationId()!=null){
-            NetworkResource networkResource = catalogDbClient.getNetworkResourceCustomizationByModelCustomizationUUID(modelInfo.getModelCustomizationId()).getNetworkResource();
+            NetworkResourceCustomization networkResourceCustomization = catalogDbClient.getNetworkResourceCustomizationByModelCustomizationUUID(modelInfo.getModelCustomizationId());
+                       if(networkResourceCustomization != null){
+                               NetworkResource networkResource = networkResourceCustomization.getNetworkResource();
                        if(networkResource!=null){
                                if(modelInfo.getModelVersionId() == null) {
                                        modelInfo.setModelVersionId(networkResource.getModelUUID());
@@ -1677,6 +1752,9 @@ public class ServiceInstances {
                        }else{
                                throw new ValidationException("no catalog entry found");
                        }
+                       }else if(action != Action.deleteInstance){
+                               throw new ValidationException("modelCustomizationId for networkResourceCustomization lookup", true);
+                       }
                }else{
                        //ok for version < 3 and action delete
                        if(modelName != null){
@@ -1729,6 +1807,7 @@ public class ServiceInstances {
                String serviceInstanceId = (instanceIdMap ==null)? null:instanceIdMap.get("serviceInstanceId");
                Boolean aLaCarte = null;
                String apiVersion = version.substring(1);
+               boolean inProgress = false;
                
                long startTime = System.currentTimeMillis ();
                ServiceInstancesRequest sir = null;             
@@ -1746,8 +1825,12 @@ public class ServiceInstances {
                InfraActiveRequests dup = null;
                
                dup = duplicateCheck(action, instanceIdMap, startTime, msoRequest, instanceName,requestScope, currentActiveReq);
+               
+               if(dup != null){
+                       inProgress = camundaHistoryCheck(dup, currentActiveReq);
+               }
 
-               if (instanceIdMap != null && dup != null) {
+               if (instanceIdMap != null && dup != null && inProgress) {
             buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, startTime, msoRequest, instanceName, requestScope, dup);
                }
                
@@ -1825,7 +1908,7 @@ public class ServiceInstances {
                        return postBPELRequest(currentActiveReq, requestClientParameter, orchestrationUri, requestScope);
        }
 
-    public String getRequestId(ContainerRequestContext requestContext) throws ValidateException {
+       public String getRequestId(ContainerRequestContext requestContext) throws ValidateException {
        String requestId = null;
        if (requestContext.getProperty("requestId") != null) {
                requestId = requestContext.getProperty("requestId").toString();