Add or Delete a PNF to an Active Service
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / onap / so / apihandlerinfra / ServiceInstances.java
index 91c6218..353daf8 100644 (file)
@@ -10,9 +10,9 @@
  * 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.
@@ -26,6 +26,7 @@ package org.onap.so.apihandlerinfra;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Optional;
+import java.util.stream.Collectors;
 import javax.transaction.Transactional;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -40,12 +41,15 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.HttpStatus;
+import org.onap.logging.filter.base.ErrorCode;
 import org.onap.so.apihandler.common.CommonConstants;
 import org.onap.so.apihandler.common.ErrorNumbers;
 import org.onap.so.apihandler.common.RequestClientParameter;
 import org.onap.so.apihandlerinfra.exceptions.ApiException;
 import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
+import org.onap.so.apihandlerinfra.infra.rest.BpmnRequestBuilder;
+import org.onap.so.apihandlerinfra.infra.rest.exception.CloudConfigurationNotFoundException;
 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;
@@ -54,8 +58,8 @@ 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.ErrorCode;
 import org.onap.so.logger.MessageEnum;
+import org.onap.so.serviceinstancebeans.CloudConfiguration;
 import org.onap.so.serviceinstancebeans.ModelInfo;
 import org.onap.so.serviceinstancebeans.ModelType;
 import org.onap.so.serviceinstancebeans.RequestDetails;
@@ -107,6 +111,9 @@ public class ServiceInstances extends AbstractRestHandler {
     @Autowired
     private RequestValidatorListenerRunner requestValidatorListenerRunner;
 
+    @Autowired
+    private BpmnRequestBuilder bpmnRequestBuilder;
+
     @POST
     @Path("/{version:[vV][5-7]}/serviceInstances")
     @Consumes(MediaType.APPLICATION_JSON)
@@ -371,6 +378,24 @@ public class ServiceInstances extends AbstractRestHandler {
         }
     }
 
+    @POST
+    @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/upgrade")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(description = "Upgrade a Service Instance to newer model", responses = @ApiResponse(
+            content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
+    @Transactional
+    public Response upgradeServiceInstance(String request, @PathParam("version") String version,
+            @PathParam("serviceInstanceId") String serviceInstanceId, @Context ContainerRequestContext requestContext)
+            throws ApiException {
+        String requestId = requestHandlerUtils.getRequestId(requestContext);
+        HashMap<String, String> instanceIdMap = new HashMap<>();
+        instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+
+        return serviceInstances(request, Action.upgradeInstance, instanceIdMap, version, requestId,
+                requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
+    }
+
     @POST
     @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/vnfs/{vnfInstanceId}/replace")
     @Consumes(MediaType.APPLICATION_JSON)
@@ -389,6 +414,42 @@ public class ServiceInstances extends AbstractRestHandler {
                 requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
     }
 
+    @POST
+    @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/vnfs/{vnfInstanceId}/healthcheck")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(description = "HealthCheck for provided VNF instance", responses = @ApiResponse(
+            content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
+    @Transactional
+    public Response cnfHealthCheck(String request, @PathParam("version") String version,
+            @PathParam("serviceInstanceId") String serviceInstanceId, @PathParam("vnfInstanceId") String vnfInstanceId,
+            @Context ContainerRequestContext requestContext) throws ApiException {
+        String requestId = requestHandlerUtils.getRequestId(requestContext);
+        HashMap<String, String> instanceIdMap = new HashMap<>();
+        instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+        instanceIdMap.put("vnfInstanceId", vnfInstanceId);
+        return serviceInstances(request, Action.healthCheck, instanceIdMap, version, requestId,
+                requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
+    }
+
+    @POST
+    @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/vnfs/{vnfInstanceId}/upgradeCnf")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(description = "Upgrade CNF instance", responses = @ApiResponse(
+            content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
+    @Transactional
+    public Response cnfUpgrade(String request, @PathParam("version") String version,
+            @PathParam("serviceInstanceId") String serviceInstanceId, @PathParam("vnfInstanceId") String vnfInstanceId,
+            @Context ContainerRequestContext requestContext) throws ApiException {
+        String requestId = requestHandlerUtils.getRequestId(requestContext);
+        HashMap<String, String> instanceIdMap = new HashMap<>();
+        instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+        instanceIdMap.put("vnfInstanceId", vnfInstanceId);
+        return serviceInstances(request, Action.upgradeCnf, instanceIdMap, version, requestId,
+                requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
+    }
+
     @PUT
     @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/vnfs/{vnfInstanceId}")
     @Consumes(MediaType.APPLICATION_JSON)
@@ -658,6 +719,53 @@ public class ServiceInstances extends AbstractRestHandler {
                 requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
     }
 
+
+    @POST
+    @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/pnfs")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(description = "Create VNF on a specified version and serviceInstance", responses = @ApiResponse(
+            content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
+    @Transactional
+    public Response createPnfInstance(String request, @PathParam("version") String version,
+            @PathParam("serviceInstanceId") String serviceInstanceId, @Context ContainerRequestContext requestContext)
+            throws ApiException {
+        String requestId = requestHandlerUtils.getRequestId(requestContext);
+        HashMap<String, String> instanceIdMap = new HashMap<>();
+        instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+        try {
+            return serviceInstances(request, Action.createInstance, instanceIdMap, version, requestId,
+                    requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
+        } catch (Exception e) {
+            logger.error("Error in pnf", e);
+            throw e;
+        }
+    }
+
+
+    @DELETE
+    @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/pnfs/{pnfInstanceId}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Operation(description = "Create PNF on a specified version and serviceInstance", responses = @ApiResponse(
+            content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
+    @Transactional
+    public Response deletePnfInstance(String request, @PathParam("version") String version,
+            @PathParam("serviceInstanceId") String serviceInstanceId, @PathParam("pnfInstanceId") String pnfInstanceId,
+            @Context ContainerRequestContext requestContext) throws ApiException {
+        String requestId = requestHandlerUtils.getRequestId(requestContext);
+        HashMap<String, String> instanceIdMap = new HashMap<>();
+        instanceIdMap.put("serviceInstanceId", serviceInstanceId);
+        instanceIdMap.put("pnfInstanceId", pnfInstanceId);
+        try {
+            return serviceInstances(request, Action.deleteInstance, instanceIdMap, version, requestId,
+                    requestHandlerUtils.getRequestUri(requestContext, uriPrefix));
+        } catch (Exception e) {
+            logger.error("Error in pnf", e);
+            throw e;
+        }
+    }
+
     @POST
     @Path("/{version:[vV][5-7]}/serviceInstances/{serviceInstanceId}/networks")
     @Consumes(MediaType.APPLICATION_JSON)
@@ -817,28 +925,45 @@ public class ServiceInstances extends AbstractRestHandler {
 
         sir = requestHandlerUtils.convertJsonToServiceInstanceRequest(requestJSON, action, requestId, requestUri);
         action = handleReplaceInstance(action, sir);
-        requestValidatorListenerRunner.runValidations(requestUri, instanceIdMap, sir, queryParams);
 
         String requestScope = requestHandlerUtils.deriveRequestScope(action, sir, requestUri);
+        try {
+            requestValidatorListenerRunner.runValidations(requestUri, instanceIdMap, sir, queryParams, action);
+        } catch (ApiException e) {
+            msoRequest.createErrorRequestRecord(Status.FAILED, requestId, e.getMessage(), action, requestScope,
+                    requestJSON, requestHandlerUtils
+                            .getServiceInstanceIdForValidationError(sir, instanceIdMap, requestScope).orElse(null),
+                    sir);
+            throw e;
+        }
+
         InfraActiveRequests currentActiveReq =
                 msoRequest.createRequestObject(sir, action, requestId, Status.IN_PROGRESS, requestJSON, requestScope);
         if (sir.getRequestDetails().getRequestParameters() != null) {
             aLaCarte = sir.getRequestDetails().getRequestParameters().getALaCarte();
         }
+
         requestHandlerUtils.parseRequest(sir, instanceIdMap, action, version, requestJSON, aLaCarte, requestId,
                 currentActiveReq);
+        if ((action == Action.replaceInstance || action == Action.replaceInstanceRetainAssignments)
+                && (requestScope.equals(ModelType.vnf.toString()) || requestScope.equals(ModelType.vfModule.toString()))
+                && sir.getRequestDetails().getCloudConfiguration() == null) {
+            CloudConfiguration cloudConfiguration =
+                    getCloudConfigurationOnReplace(requestScope, instanceIdMap, currentActiveReq);
+            sir.getRequestDetails().setCloudConfiguration(cloudConfiguration);
+            setCloudConfigurationCurrentActiveRequest(cloudConfiguration, currentActiveReq);
+        }
         requestHandlerUtils.setInstanceId(currentActiveReq, requestScope, null, instanceIdMap);
 
-        int requestVersion = Integer.parseInt(version.substring(1));
         String instanceName = null;
         if (sir.getRequestDetails().getRequestInfo() != null) {
             instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
         }
         boolean alaCarteFlag = msoRequest.getAlacarteFlag(sir);
-        String vnfType = msoRequest.getVnfType(sir, requestScope, action, requestVersion);
+        String vnfType = msoRequest.getVnfType(sir, requestScope);
         String networkType = msoRequest.getNetworkType(sir, requestScope);
         String sdcServiceModelVersion = msoRequest.getSDCServiceModelVersion(sir);
-        String vfModuleType = msoRequest.getVfModuleType(sir, requestScope, action, requestVersion);
+        String vfModuleType = msoRequest.getVfModuleType(sir, requestScope);
 
         if (requestScope.equalsIgnoreCase(ModelType.vnf.name()) && vnfType != null) {
             currentActiveReq.setVnfType(vnfType);
@@ -846,19 +971,9 @@ public class ServiceInstances extends AbstractRestHandler {
             currentActiveReq.setNetworkType(networkType);
         }
 
-        InfraActiveRequests dup = null;
-        boolean inProgress = false;
-
-        dup = requestHandlerUtils.duplicateCheck(action, instanceIdMap, instanceName, requestScope, currentActiveReq);
+        requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
+                instanceName);
 
-        if (dup != null) {
-            inProgress = requestHandlerUtils.camundaHistoryCheck(dup, currentActiveReq);
-        }
-
-        if (dup != null && inProgress) {
-            requestHandlerUtils.buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, instanceName,
-                    requestScope, dup);
-        }
         ServiceInstancesResponse serviceResponse = new ServiceInstancesResponse();
 
         RequestReferences referencesResponse = new RequestReferences();
@@ -920,14 +1035,16 @@ public class ServiceInstances extends AbstractRestHandler {
                     ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e).errorInfo(errorLoggerInfo).build();
         }
 
-        if (!requestScope.equalsIgnoreCase(ModelType.service.name()) && action != Action.recreateInstance) {
+        if (!requestScope.equalsIgnoreCase(ModelType.service.name()) && action != Action.recreateInstance
+                && !requestScope.equalsIgnoreCase(ModelType.vnf.name())
+                && !requestScope.equalsIgnoreCase(ModelType.pnf.name())) {
             aLaCarte = true;
         } else if (aLaCarte == null) {
             aLaCarte = false;
         }
 
 
-        RequestClientParameter requestClientParameter = null;
+        RequestClientParameter requestClientParameter;
         try {
             requestClientParameter = new RequestClientParameter.Builder().setRequestId(requestId)
                     .setBaseVfModule(isBaseVfModule).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
@@ -1006,18 +1123,7 @@ public class ServiceInstances extends AbstractRestHandler {
             throw validateException;
         }
 
-        InfraActiveRequests dup =
-                requestHandlerUtils.duplicateCheck(action, instanceIdMap, null, requestScope, currentActiveReq);
-        boolean inProgress = false;
-
-        if (dup != null) {
-            inProgress = requestHandlerUtils.camundaHistoryCheck(dup, currentActiveReq);
-        }
-
-        if (dup != null && inProgress) {
-            requestHandlerUtils.buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, null, requestScope,
-                    dup);
-        }
+        requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq, null);
 
         ServiceInstancesResponse serviceResponse = new ServiceInstancesResponse();
 
@@ -1062,7 +1168,6 @@ public class ServiceInstances extends AbstractRestHandler {
         String serviceInstanceId;
         Boolean aLaCarte = null;
         String apiVersion = version.substring(1);
-        boolean inProgress = false;
         ServiceInstancesRequest sir;
 
         sir = requestHandlerUtils.convertJsonToServiceInstanceRequest(requestJSON, action, requestId, requestUri);
@@ -1072,23 +1177,14 @@ public class ServiceInstances extends AbstractRestHandler {
         if (sir.getRequestDetails().getRequestParameters() != null) {
             aLaCarte = sir.getRequestDetails().getRequestParameters().getALaCarte();
         }
+
         requestHandlerUtils.parseRequest(sir, instanceIdMap, action, version, requestJSON, aLaCarte, requestId,
                 currentActiveReq);
         requestHandlerUtils.setInstanceId(currentActiveReq, requestScope, null, instanceIdMap);
         String instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
 
-        InfraActiveRequests dup = null;
-
-        dup = requestHandlerUtils.duplicateCheck(action, instanceIdMap, instanceName, requestScope, currentActiveReq);
-
-        if (dup != null) {
-            inProgress = requestHandlerUtils.camundaHistoryCheck(dup, currentActiveReq);
-        }
-
-        if (instanceIdMap != null && dup != null && inProgress) {
-            requestHandlerUtils.buildErrorOnDuplicateRecord(currentActiveReq, action, instanceIdMap, instanceName,
-                    requestScope, dup);
-        }
+        requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
+                instanceName);
 
         ServiceInstancesResponse serviceResponse = new ServiceInstancesResponse();
         RequestReferences referencesResponse = new RequestReferences();
@@ -1165,4 +1261,35 @@ public class ServiceInstances extends AbstractRestHandler {
                 requestScope);
     }
 
+    protected CloudConfiguration getCloudConfigurationOnReplace(String requestScope,
+            HashMap<String, String> instanceIdMap, InfraActiveRequests currentActiveReq) throws ApiException {
+        logger.debug("Replace request is missing cloudConfiguration, autofilling from create.");
+        CloudConfiguration cloudConfiguration = null;
+        if (requestScope.equals(ModelType.vfModule.toString())) {
+            cloudConfiguration = bpmnRequestBuilder.getCloudConfigurationVfModuleReplace(
+                    instanceIdMap.get("vnfInstanceId"), instanceIdMap.get("vfModuleInstanceId"));
+        } else {
+            cloudConfiguration = bpmnRequestBuilder.mapCloudConfigurationVnf(instanceIdMap.get("vnfInstanceId"));
+        }
+
+        if (cloudConfiguration == null) {
+            String errorMessage = "CloudConfiguration not found during autofill for replace request.";
+            logger.error(errorMessage);
+            updateStatus(currentActiveReq, Status.FAILED, errorMessage);
+            throw new CloudConfigurationNotFoundException(
+                    "CloudConfiguration not found during autofill for replace request.");
+        }
+        return cloudConfiguration;
+    }
+
+    protected void setCloudConfigurationCurrentActiveRequest(CloudConfiguration cloudConfiguration,
+            InfraActiveRequests currentActiveRequest) {
+        if (cloudConfiguration.getLcpCloudRegionId() != null) {
+            currentActiveRequest.setCloudRegion(cloudConfiguration.getLcpCloudRegionId());
+        }
+
+        if (cloudConfiguration.getTenantId() != null) {
+            currentActiveRequest.setTenantId(cloudConfiguration.getTenantId());
+        }
+    }
 }