diff options
author | 2017-07-03 20:16:55 +0300 | |
---|---|---|
committer | 2017-07-03 20:16:55 +0300 | |
commit | 153a35821f0d25ce23cca467b76c5a7c5092c744 (patch) | |
tree | 0c66c4d1310019479e446ea3a4c26faffb0aa33f /catalog-be/src/main/java/org/openecomp | |
parent | ffdda7d685029d6a88ac82ac637e43bba96423cb (diff) |
[sdc] - last merges before moving to LF
Change-Id: I0df3ec795f0de84229ea4bb4806ec8f959243557
Signed-off-by: Tal Gitelman <tg851x@intl.att.com>
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp')
8 files changed, 952 insertions, 645 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index f917d60553..8d8aa72c8f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -1632,6 +1632,7 @@ public abstract class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentInstance resResourceInfo = resultOp.left().value(); newComponentInstance.setName(resResourceInfo.getName()); + newComponentInstance.setInvariantName(resResourceInfo.getInvariantName()); newComponentInstance.setPosX(resResourceInfo.getPosX()); newComponentInstance.setPosY(resResourceInfo.getPosY()); newComponentInstance.setDescription(resResourceInfo.getDescription()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java index f545548b95..4f4ad7f838 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java @@ -448,7 +448,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { if (newInputsMap != null && !newInputsMap.isEmpty()) { int index = 0; for (Entry<String, List<InputDefinition>> entry : newInputsMap.entrySet()) { - List<ComponentInstanceInput> inputsValueToCreate = new ArrayList<>(); + String compInstId = entry.getKey(); Optional<ComponentInstance> op = ciList.stream().filter(ci -> ci.getUniqueId().equals(compInstId)).findAny(); @@ -475,7 +475,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { for (InputDefinition input : inputs) { - StorageOperationStatus status = addInputsToComponent(componentId, inputsToCreate, allDataTypes.left().value(), resList, index, inputsValueToCreate, compInstId, compInstname, origComponent, input); + StorageOperationStatus status = addInputsToComponent(componentId, inputsToCreate, inputsValueToCreateMap, allDataTypes.left().value(), resList, index, compInstId, compInstname, origComponent, input); if(status != StorageOperationStatus.OK ){ ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(status); log.debug("Failed to create inputs value under component {}, error: {}", componentId, actionStatus.name()); @@ -485,9 +485,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } } - if(!inputsValueToCreate.isEmpty()){ - inputsValueToCreateMap.put(compInstId, inputsValueToCreate); - } + } } @@ -556,8 +554,9 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } - private StorageOperationStatus addInputsToComponent(String componentId, Map<String, InputDefinition> inputsToCreate, Map<String, DataTypeDefinition> allDataTypes, List<InputDefinition> resList, int index, - List<ComponentInstanceInput> inputsValueToCreate, String compInstId, String compInstname, org.openecomp.sdc.be.model.Component origComponent, InputDefinition input) { + private StorageOperationStatus addInputsToComponent(String componentId, Map<String, InputDefinition> inputsToCreate, Map<String, List<ComponentInstanceInput>> inputsValueToCreateMap, Map<String, DataTypeDefinition> allDataTypes, List<InputDefinition> resList, int index, + String compInstId, String compInstname, org.openecomp.sdc.be.model.Component origComponent, InputDefinition input) { + Either<List<InputDefinition>, ResponseFormat> result; String innerType = null; @@ -604,8 +603,23 @@ public class InputsBusinessLogic extends BaseBusinessLogic { getInputValues.add(getInputValueDataDefinition); inputValue.setGetInputValues(getInputValues); + List<ComponentInstanceInput> inputsValueToCreate = null; + + if(inputsValueToCreateMap.containsKey(compInstId)){ + inputsValueToCreate = inputsValueToCreateMap.get(compInstId); + }else{ + inputsValueToCreate = new ArrayList<>(); + } + inputsValueToCreate.add(inputValue); + inputsValueToCreateMap.put(compInstId, inputsValueToCreate); + + inputsValueToCreate.add(inputValue); - input.setInputs(inputsValueToCreate); + List<ComponentInstanceInput> inputsValue = input.getInputs(); + if(inputsValue == null) + inputsValue = new ArrayList<>(); + inputsValue.add(inputValue); + input.setInputs(inputsValue); resList.add(input); return StorageOperationStatus.OK; @@ -881,22 +895,25 @@ public class InputsBusinessLogic extends BaseBusinessLogic { if(inputsValue != null && !inputsValue.isEmpty()){ for(ComponentInstanceInput inputValue: inputsValue){ + inputValue.setValue(inputValue.getDefaultValue()); + List<GetInputValueDataDefinition> getInputsValues = inputValue.getGetInputValues(); + if(getInputsValues != null && !getInputsValues.isEmpty()){ + Optional<GetInputValueDataDefinition> op = getInputsValues.stream().filter(gi -> gi.getInputId().equals(inputForDelete.getUniqueId())).findAny(); + if(op.isPresent()){ + getInputsValues.remove(op.get()); + } + } + inputValue.setGetInputValues(getInputsValues); List<ComponentInstanceInput> inputList = null; String ciId = inputValue.getComponentInstanceId(); - if(!insInputsMatToDelete.containsKey(ciId)){ - inputList = new ArrayList<>(); - }else{ - inputList = insInputsMatToDelete.get(ciId); + status = toscaOperationFacade.updateComponentInstanceInput(component, ciId, inputValue); + if(status != StorageOperationStatus.OK){ + log.debug("Component id: {} delete component instance input id: {} failed", componentId, inputId); + deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), component.getName())); + return deleteEither; } - inputList.add(inputValue); - insInputsMatToDelete.put(ciId, inputList); - } - status = toscaOperationFacade.deleteComponentInstanceInputsToComponent(insInputsMatToDelete, component.getUniqueId()); - if(status != StorageOperationStatus.OK){ - log.debug("Component id: {} delete component instance input id: {} failed", componentId, inputId); - deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), component.getName())); - return deleteEither; } + } // US848813 delete service input that relates to VL / CP property @@ -932,11 +949,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } } propertyValue.setGetInputValues(getInputsValues); - if(status != StorageOperationStatus.OK){ - log.debug("Component id: {} delete component instance property {} id: {} failed", componentId, propertyValue.getUniqueId(), inputId); - deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), component.getName())); - return deleteEither; - } + Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(propertyValue.getPath(), propertyValue.getUniqueId(), propertyValue.getDefaultValue()); if (findDefaultValue.isRight()) { deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())))); @@ -1187,8 +1200,14 @@ public class InputsBusinessLogic extends BaseBusinessLogic { List<ComponentInstance> ciList = component.getComponentInstances(); String componentId = component.getUniqueId(); for (Entry<String, List<ComponentInstancePropInput>> entry : newInputsPropsMap.entrySet()) { - List<ComponentInstanceProperty> propertiesToCreate = new ArrayList<>(); String compInstId = entry.getKey(); + List<ComponentInstanceProperty> propertiesToCreate = null; + if(propertiesToCreateMap.containsKey(compInstId)){ + propertiesToCreate = propertiesToCreateMap.get(compInstId); + }else{ + propertiesToCreate = new ArrayList<>(); + } + List<ComponentInstancePropInput> properties = entry.getValue(); Optional<ComponentInstance> op = ciList.stream().filter(ci -> ci.getUniqueId().equals(compInstId)).findAny(); @@ -1334,7 +1353,9 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } inputsToCreate.put(input.getName(), input); - List<ComponentInstanceProperty> propertiesList = new ArrayList<>(); // adding the property with the new value for UI + List<ComponentInstanceProperty> propertiesList = input.getProperties(); + if(propertiesList == null) + propertiesList = new ArrayList<>(); // adding the property with the new value for UI propertiesList.add(prop); input.setProperties(propertiesList); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java index 8c0041af9a..5ed0719f90 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java @@ -74,13 +74,14 @@ import io.swagger.annotations.ApiResponses; public class DistributionCatalogServlet extends BeGenericServlet { private static Logger log = LoggerFactory.getLogger(DistributionCatalogServlet.class.getName()); + @Context + private HttpServletRequest request; // ******************************************************* // Download (GET) artifacts // **********************************************************/ /** * - * @param request * @param requestId * @param instanceIdHeader * @param accept @@ -105,7 +106,7 @@ public class DistributionCatalogServlet extends BeGenericServlet { @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadServiceArtifact(@Context final HttpServletRequest request, + public Response downloadServiceArtifact( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @@ -158,7 +159,6 @@ public class DistributionCatalogServlet extends BeGenericServlet { /** * - * @param request * @param requestId * @param instanceIdHeader * @param accept @@ -186,7 +186,7 @@ public class DistributionCatalogServlet extends BeGenericServlet { @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadResourceArtifact(@Context final HttpServletRequest request, + public Response downloadResourceArtifact( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @@ -241,7 +241,6 @@ public class DistributionCatalogServlet extends BeGenericServlet { /** * - * @param request * @param requestId * @param instanceIdHeader * @param accept @@ -268,7 +267,7 @@ public class DistributionCatalogServlet extends BeGenericServlet { @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"), @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response downloadResourceInstanceArtifact(@Context final HttpServletRequest request, + public Response downloadResourceInstanceArtifact( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java index 6a7490650d..ab760218a7 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java @@ -84,10 +84,11 @@ public class DistributionServlet extends BeGenericServlet { private static Logger log = LoggerFactory.getLogger(DistributionServlet.class.getName()); @Resource private DistributionBusinessLogic distributionLogic; + @Context + private HttpServletRequest request; /** * - * @param request * @param requestId * @param instanceId * @param accept @@ -110,7 +111,7 @@ public class DistributionServlet extends BeGenericServlet { @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getUebServerList(@Context final HttpServletRequest request, + public Response getUebServerList( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @@ -157,7 +158,6 @@ public class DistributionServlet extends BeGenericServlet { /** * - * @param request * @param requestId * @param instanceId * @param accept @@ -185,7 +185,7 @@ public class DistributionServlet extends BeGenericServlet { @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) //TODO Tal G fix response headers and to check missing header validations with Michael L @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) - public Response registerForDistribution(@Context final HttpServletRequest request, + public Response registerForDistribution( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @@ -223,7 +223,6 @@ public class DistributionServlet extends BeGenericServlet { * Returns list of valid artifact types for validation done in the distribution client.<br> * The list is the representation of the values of the enum ArtifactTypeEnum. * - * @param request * @param requestId * @param instanceId * @param authorization @@ -242,7 +241,7 @@ public class DistributionServlet extends BeGenericServlet { @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( POST,PUT,DELETE will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) - public Response getValidArtifactTypes(@Context final HttpServletRequest request, + public Response getValidArtifactTypes( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, @@ -266,7 +265,6 @@ public class DistributionServlet extends BeGenericServlet { /** * Removes from subscription for distribution notifications * - * @param request * @param requestId * @param instanceId * @param accept @@ -294,7 +292,7 @@ public class DistributionServlet extends BeGenericServlet { @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution ( PUT,DELETE,GET will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The registration failed due to internal SDC problem or Cambria Service failure ECOMP Component should continue the attempts to register for distribution - POL5000")}) @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.distribution.api.client.RegistrationRequest", paramType = "body", value = "json describe the artifact")}) - public Response unRegisterForDistribution(@Context final HttpServletRequest request, + public Response unRegisterForDistribution( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java index fea300a8bb..74eea8b3ec 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -58,6 +58,8 @@ import org.slf4j.LoggerFactory; import com.jcabi.aspects.Loggable; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; @@ -87,18 +89,50 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { /** * Uploads an artifact to resource or service * + * @param contenType + * @param checksum + * @param userId + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization * @param assetType * @param uuid + * @param data * @return */ @POST @Path("/{assetType}/{uuid}/artifacts") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads of artifact to a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact uploaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response uploadArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @ApiParam(value = "json describe the artifact", required = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "uploads of artifact to a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 400, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response uploadArtifact( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + String data) { + init(log); Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); @@ -162,12 +196,35 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @POST @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "uploads an artifact to a resource instance", httpMethod = "POST", notes = "uploads an artifact to a resource instance", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact uploaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response uploadArtifactToInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, - @ApiParam(value = "json describe the artifact", required = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "uploads an artifact to a resource instance", httpMethod = "POST", notes = "uploads an artifact to a resource instance") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 400, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response uploadArtifactToInstance( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName, + String data) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -223,22 +280,51 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { } /** - * updates an artifact on a resource or service * + * @param contenType + * @param checksum + * @param userId + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization * @param assetType * @param uuid * @param artifactUUID + * @param data * @return */ @POST @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "updates an artifact on a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Updated"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response updateArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID, - @ApiParam(value = "json describe the artifact", required = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "updates an artifact on a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response updateArtifact( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, + String data) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -305,12 +391,35 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @POST @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "updates an artifact on a resource instance", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Updated"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response updateArtifactOnResourceInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, - @PathParam("artifactUUID") final String artifactUUID, @ApiParam(value = "json describe the artifact", required = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "updates an artifact on a resource instance", httpMethod = "POST", notes = "uploads of artifact to a resource or service") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response updateArtifactOnResourceInstance( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum, + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, + @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName, + String data) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -378,10 +487,31 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value = "deletes an artifact of a resource or service", httpMethod = "DELETE", notes = "deletes an artifact of a resource or service", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response deleteArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + /*@ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") })*/ + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + public Response deleteArtifact( + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -448,11 +578,30 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value = "deletes an artifact of a resource insatnce", httpMethod = "DELETE", notes = "deletes an artifact of a resource insatnce", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response deleteArtifactOnResourceInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, - @PathParam("artifactUUID") final String artifactUUID, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + public Response deleteArtifactOnResourceInstance( + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, + @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -519,13 +668,25 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @GET @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Download component artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Artifact not found") }) + @ApiOperation(value = "Download component artifact", httpMethod = "GET", notes = "Returns downloaded artifact") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")}) public Response downloadComponentArtifact( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, - @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID, - @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; @@ -587,12 +748,25 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_OCTET_STREAM) @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Artifact not found") }) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")}) public Response downloadResourceInstanceArtifact( - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, - @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, @PathParam("artifactUUID") final String artifactUUID, - @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID, + @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) { Wrapper<Response> responseWrapper = new Wrapper<>(); ResponseFormat responseFormat = null; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java index f6251689bc..ce8b967786 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java @@ -21,23 +21,17 @@ package org.openecomp.sdc.be.externalapi.servlet; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; -import java.util.Arrays; import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; import javax.inject.Singleton; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -46,47 +40,23 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.codehaus.jackson.JsonGenerationException; -import org.codehaus.jackson.map.JsonMappingException; -import org.codehaus.jackson.map.ObjectMapper; -import org.elasticsearch.common.Strings; -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; -import org.openecomp.sdc.be.components.impl.ImportUtils; -import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; -import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; -import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase; -import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; -import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter; import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata; import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; -import org.openecomp.sdc.be.model.LifecycleStateEnum; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.category.CategoryDefinition; -import org.openecomp.sdc.be.model.category.SubCategoryDefinition; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.servlets.AbstractValidationsServlet; import org.openecomp.sdc.be.servlets.RepresentationUtils; -import org.openecomp.sdc.be.utils.CommonBeUtils; import org.openecomp.sdc.common.api.Constants; -import org.openecomp.sdc.common.config.EcompErrorName; import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; -import org.openecomp.sdc.common.datastructure.Wrapper; import org.openecomp.sdc.common.util.GeneralUtility; -import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,26 +90,29 @@ public class AssetsDataServlet extends AbstractValidationsServlet { /** * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization * @param assetType * @param category * @param subCategory * @param distributionStatus * @param resourceType - * @param instanceIdHeader * @return */ @GET @Path("/{assetType}") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Fetch list of assets", httpMethod = "GET", notes = "Returns list of assets", response = AssetMetadata.class, responseContainer="List") + @ApiOperation(value = "Fetch list of assets", httpMethod = "GET", notes = "Returns list of assets") @ApiResponses(value = { @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = AssetMetadata.class, responseContainer="List"), @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), - @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used to register for distribution (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) - public Response getAssetList( + public Response getAssetListExternal( @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @@ -176,7 +149,7 @@ public class AssetsDataServlet extends AbstractValidationsServlet { ElementBusinessLogic elementLogic = getElementBL(context); AssetMetadataConverter assetMetadataUtils = getAssetUtils(context); - Map<FilterKeyEnum, String> filters = new HashMap<FilterKeyEnum, String>(); + Map<FilterKeyEnum, String> filters = new EnumMap<>(FilterKeyEnum.class); if (category != null) { filters.put(FilterKeyEnum.CATEGORY, category); @@ -230,20 +203,33 @@ public class AssetsDataServlet extends AbstractValidationsServlet { /** * + * @param requestId + * @param instanceIdHeader + * @param accept + * @param authorization * @param assetType * @param uuid - * @param request - * @param instanceIdHeader * @return */ @GET @Path("/{assetType}/{uuid}/metadata") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Fetch metadata of asset by uuid", httpMethod = "GET", notes = "Returns metadata of asset", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Assets Fetched"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response getAssetListByUuid(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "Detailed metadata of asset by uuid", httpMethod = "GET", notes = "Returns detailed metadata of an asset by uuid") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = AssetMetadata.class, responseContainer="List"), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response getAssetSpecificMetadataByUuidExternal( + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The requested asset uuid", required = true)@PathParam("uuid") final String uuid) { Response response = null; ResponseFormat responseFormat = null; @@ -252,7 +238,7 @@ public class AssetsDataServlet extends AbstractValidationsServlet { String url = request.getMethod() + " " + requestURI; log.debug("Start handle request of {}", url); - EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + EnumMap<AuditingFieldsKeysEnum, Object> additionalParam = new EnumMap<>(AuditingFieldsKeysEnum.class); ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); @@ -306,21 +292,33 @@ public class AssetsDataServlet extends AbstractValidationsServlet { /** * - * @param uuid - * @param assetType - * @param authorization + * @param requestId * @param instanceIdHeader + * @param accept + * @param authorization + * @param assetType + * @param uuid * @return */ @GET @Path("/{assetType}/{uuid}/toscaModel") @Produces(MediaType.APPLICATION_OCTET_STREAM) - @ApiOperation(value = "Fetch asset csar", httpMethod = "GET", notes = "Returns asset csar", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Asset Model Fetched"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 404, message = "Asset not found") }) - public Response getToscaModel(@PathParam("uuid") final String uuid, - @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, - @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { + @ApiOperation(value = "Fetch assets CSAR", httpMethod = "GET", notes = "Returns asset csar", response = String.class) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned", response = String.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")}) + public Response getToscaModelExternal( + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + @ApiParam(value = "The requested asset uuid", required = true)@PathParam("uuid") final String uuid) { String url = request.getRequestURI(); log.debug("Start handle request of {} {}", request.getMethod(), url); @@ -372,443 +370,4 @@ public class AssetsDataServlet extends AbstractValidationsServlet { return response; } } - - /** - * Creates a new Resource - * - * @param assetType - * @param data - * @param userId - * @param instanceIdHeader - * @return - */ - @POST - @Path("/{assetType}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "creates a resource", httpMethod = "POST", notes = "creates a resource", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact uploaded"), - @ApiResponse(code = 401, message = "Authorization required"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Resource already exist") }) - public Response createResource(@PathParam("assetType") final String assetType, - @ApiParam(value = "json describe the artifact", required = true) String data, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, - @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader) { - - init(log); - - Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("Start handle request of {}", url); - Resource resource = null; - User modifier = null; - EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); - ServletContext context = request.getSession().getServletContext(); - ResourceBusinessLogic resourceBL = getResourceBL(context); - try { - // Validate X-ECOMP-InstanceID Header - if (responseWrapper.isEmpty()) { - validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); - } - // Validate USER_ID Header - if (responseWrapper.isEmpty()) { - validateHttpCspUserIdHeader(userId, responseWrapper); - } - // Validate assetType - if (responseWrapper.isEmpty()) { - if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) ){ - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); - } - } - //Validate resource type - if(responseWrapper.isEmpty()){ - JSONParser parser = new JSONParser(); - JSONObject jsonObj = (JSONObject) parser.parse(data); - String resourceType = (String) jsonObj.get(FilterKeyEnum.RESOURCE_TYPE.getName()); - if( StringUtils.isEmpty(resourceType) || !ResourceTypeEnum.containsName(resourceType) ){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, (String) jsonObj.get("name")); - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - } - // Convert the user json to a resource - if (responseWrapper.isEmpty()) { - modifier = new User(); - modifier.setUserId(userId); - Either<Resource, ResponseFormat> eitherResource = getComponentsUtils() - .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, - null, ComponentTypeEnum.RESOURCE); - if( eitherResource.isRight() ){ - responseWrapper.setInnerElement(eitherResource.right().value()); - } - else{ - resource = eitherResource.left().value(); - } - - } - //validate name exist - if(responseWrapper.isEmpty()){ - if( Strings.isEmpty(resource.getName())){ - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( - ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue())); - - } - } - - if(responseWrapper.isEmpty()){ - resource.setDerivedFrom(Arrays.asList("tosca.nodes.Root")); - resource.setSystemName(ValidationUtils.convertToSystemName(resource.getName())); - resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VFCMT.name(), - resource.getSystemName())); - handleCategories(context, data, resource, responseWrapper); - } - // Create the resource in the dataModel - if (responseWrapper.isEmpty()) { - Either<Resource, ResponseFormat> eitherCreateResponse = resourceBL.createResource(resource, null, - modifier, null, null); - if (eitherCreateResponse.isRight()) { - responseWrapper.setInnerElement(eitherCreateResponse.right().value()); - } else { - resource = eitherCreateResponse.left().value(); - } - } - Response response; - //Build Response and store it in the response Wrapper - if (responseWrapper.isEmpty()) { - response = buildCreatedResourceResponse(resource, context, responseWrapper); - } - else{ - response = buildErrorResponse(responseWrapper.getInnerElement()); - } - return response; - - } catch (Exception e) { - final String message = "failed to create vfc monitoring template resource"; - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); - log.debug(message, e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - finally{ - prepareAdditionalAudit(resource, additionalParams); - - getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), - ComponentTypeEnum.RESOURCE.getValue(), AuditingActionEnum.CREATE_RESOURCE_BY_API.getName(), request, - additionalParams); - } - } - - /** - * Changing the lifecycle of an asset - * @param jsonChangeInfo The description - request body - * @param assetType The requested asset type.Valid values are: resources / services (for VFCMT – use "resources") - * @param uuid The uuid of the desired resource to be changed - * @param lifecycleTransition The lifecycle operation to be performed on the asset.Valid values are:Checkin / Checkout / CERTIFICATION_REQUEST - * @param userId - * @return - */ - @POST - @Path("/{assetType}/{uuid}/lifecycleState/{lifecycleOperation}") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST", response = Response.class) - @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource state changed"), @ApiResponse(code = 403, message = "Asset is already checked-out by another user")}) - public Response changeResourceState(@ApiParam(value = "LifecycleChangeInfo - relevant for checkin", required = false) String jsonChangeInfo, - @ApiParam(value = "validValues: resources / services ", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam(value = "assetType") final String assetType, - @ApiParam(value = "id of component to be changed") @PathParam(value = "uuid") final String uuid, - @ApiParam(allowableValues = "checkout, checkin", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) { - - Response response = null; - EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); - - init(log); - - String requestURI = request.getRequestURI(); - String url = request.getMethod() + " " + requestURI; - log.debug("Start handle request of {}", url); - - //get the business logic - ServletContext context = request.getSession().getServletContext(); - LifecycleBusinessLogic businessLogic = getLifecycleBL(context); - - Wrapper<ResponseFormat> responseWrapper = runValidations(assetType); - ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); - Component component = null; - Component responseObject = null; - User modifier = null; - - try{ - if (responseWrapper.isEmpty()) { - //get user - Either<User, ResponseFormat> eitherGetUser = getUser(request, userId); - if (eitherGetUser.isRight()) { - ResponseFormat responseFormat = eitherGetUser.right().value(); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } - modifier = eitherGetUser.left().value(); - - //get the component id from the uuid - Either<Component, ResponseFormat> latestVersion = businessLogic.getLatestComponentByUuid(componentType, uuid); - if (latestVersion.isRight()) { - ResponseFormat responseFormat = latestVersion.right().value(); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } - component = latestVersion.left().value(); - String componentId = component.getUniqueId(); - - //validate the transition is valid - Either<LifeCycleTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(lifecycleTransition, modifier); - if (validateEnum.isRight()) { - ResponseFormat responseFormat = validateEnum.right().value(); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } - LifeCycleTransitionEnum transitionEnum = validateEnum.left().value(); - - //create changeInfo - LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(); - try { - if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) { - ObjectMapper mapper = new ObjectMapper(); - changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks()); - } - } - catch (Exception e) { - BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); - BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); - log.debug("failed to convert from json {}", jsonChangeInfo, e); - ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(modifier, AuditingActionEnum.CHECKOUT_RESOURCE); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } - - //execute business logic - Either<? extends Component, ResponseFormat> actionResponse = businessLogic.changeComponentState(componentType, componentId, modifier, transitionEnum, changeInfo, false, true); - if (actionResponse.isRight()) { - log.info("failed to change resource state"); - ResponseFormat responseFormat = actionResponse.right().value(); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } - - log.debug("change state successful !!!"); - responseObject = actionResponse.left().value(); - response = buildCreatedResourceResponse(responseObject, context, responseWrapper); - } else { - response = buildErrorResponse(responseWrapper.getInnerElement()); - } - - return response; - } catch (Exception e) { - BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Change Lifecycle State"); - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State"); - log.debug("change lifecycle state failed with exception", e); - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); - responseWrapper.setInnerElement(responseFormat); - return buildErrorResponse(responseFormat); - } finally{ - auditChnageLifecycleAction(additionalParams, responseWrapper, componentType, component, responseObject, modifier, userId); - } - } - - private void prepareAdditionalAudit(Resource resource, EnumMap<AuditingFieldsKeysEnum, Object> additionalParams) { - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, StringUtils.EMPTY); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, StringUtils.EMPTY); - - if( resource != null ){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, resource.getUUID()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, resource.getInvariantUUID()); - } else { - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, StringUtils.EMPTY); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, StringUtils.EMPTY); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, StringUtils.EMPTY); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, StringUtils.EMPTY); - } - } - - private Response buildCreatedResourceResponse(Component resource, ServletContext context, - Wrapper<ResponseFormat> responseWrapper) throws IOException, JsonGenerationException, JsonMappingException { - ResponseFormat responseFormat; - Response response; - AssetMetadataConverter assetMetadataUtils = getAssetUtils(context); - Either<? extends AssetMetadata, ResponseFormat> resMetadata = assetMetadataUtils - .convertToSingleAssetMetadata(resource, request.getRequestURL().toString(), - true); - if (resMetadata.isRight()) { - log.debug("Asset conversion Failed"); - responseFormat = resMetadata.right().value(); - responseWrapper.setInnerElement(responseFormat); - response = buildErrorResponse(responseFormat); - }else{ - final AssetMetadata assetData = resMetadata.left().value(); - assetData.setToscaModelURL(null); - - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED)); - Object representation = RepresentationUtils.toRepresentation(assetData); - response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); - } - return response; - } - - private void handleCategories(ServletContext context, String data, Resource resource, - Wrapper<ResponseFormat> responseWrapper) { - try { - JSONParser parser = new JSONParser(); - JSONObject jsonObj = (JSONObject) parser.parse(data); - String category = (String) jsonObj.get(CategoryTypeEnum.CATEGORY.getValue()); - String subcategory = (String) jsonObj.get(CategoryTypeEnum.SUBCATEGORY.getValue()); - if (Strings.isEmpty(category)) { - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( - ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); - } - else if (Strings.isEmpty(subcategory)) { - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( - ActionStatus.COMPONENT_MISSING_SUBCATEGORY)); - } - if (responseWrapper.isEmpty()) { - ElementBusinessLogic elementLogic = getElementBL(context); - // get All Categories - Either<List<CategoryDefinition>, ActionStatus> allResourceCategories = elementLogic - .getAllResourceCategories(); - // Error fetching categories - if (allResourceCategories.isRight()) { - responseWrapper.setInnerElement( - getComponentsUtils().getResponseFormat(allResourceCategories.right().value())); - } else { - addCategories(resource, category, subcategory, allResourceCategories, responseWrapper); - } - } - } catch (Exception e) { - log.debug("Exception occured in addCategories: {}", e.getMessage(), e); - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - - } - - private void addCategories(Resource resource, String category, String subcategory, - Either<List<CategoryDefinition>, ActionStatus> allResourceCategories, - Wrapper<ResponseFormat> responseWrapper) { - Optional<CategoryDefinition> optionalCategory = - // Stream of all the categories - allResourceCategories.left().value().stream() - // filter in only relevant category - .filter(e -> e.getName().equals(category)) - // get the result - .findAny(); - if (!optionalCategory.isPresent()) { - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( - ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); - } else { - CategoryDefinition categoryDefinition = optionalCategory.get(); - - List<SubCategoryDefinition> subCaregories = - // Stream of all sub-categories of the relevant - // category - categoryDefinition.getSubcategories().stream() - // filter in only relevant sub-category - .filter(e -> e.getName().equals(subcategory)) - // get the result - .collect(Collectors.toList()); - - if( subCaregories.isEmpty() ){ - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( - ActionStatus.COMPONENT_INVALID_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue())); - } - else{ - categoryDefinition.setSubcategories(subCaregories); - resource.setCategories(Arrays.asList(categoryDefinition)); - } - - } - } - - - - - private void auditChnageLifecycleAction(EnumMap<AuditingFieldsKeysEnum, Object> additionalParams, - Wrapper<ResponseFormat> responseWrapper, ComponentTypeEnum componentType, Component component, - Component responseObject, User modifier, String userId) { - if (modifier!=null){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFullName()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); - } else { - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, userId); - } - - if (component!=null){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, component.getVersion()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, component.getLifecycleState().name()); - } else { - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, ""); - } - - if (responseObject!=null){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, responseObject.getVersion()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, responseObject.getUUID()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, responseObject.getInvariantUUID()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,responseObject.getLifecycleState().name()); - } else { - if (component!=null){ - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, component.getVersion()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, component.getUUID()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, component.getInvariantUUID()); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,component.getLifecycleState().name()); - } else { - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); - additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,""); - } - } - - getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), - componentType.getValue(), AuditingActionEnum.CHANGE_LIFECYCLE_BY_API.getName(), request, - additionalParams); - } - - private Wrapper<ResponseFormat> runValidations(final String assetType) { - Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); - - // Validate X-ECOMP-InstanceID Header - if (responseWrapper.isEmpty()) { - String instanceId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); - validateXECOMPInstanceIDHeader(instanceId,responseWrapper); - } - // Validate USER_ID Header - if (responseWrapper.isEmpty()) { - validateHttpCspUserIdHeader(request.getHeader(Constants.USER_ID_HEADER),responseWrapper); - } - // Validate assetType - if (responseWrapper.isEmpty()) { - if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) && !AssetTypeEnum.SERVICES.getValue().equals(assetType)){ - responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); - } - } - - return responseWrapper; - } - - private Either<LifeCycleTransitionEnum, ResponseFormat> validateTransitionEnum(final String lifecycleTransition, User user) { - LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT; - try { - transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition); - } catch (IllegalArgumentException e) { - log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString()); - ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, AuditingActionEnum.CHECKOUT_RESOURCE); - return Either.right(error); - } - return Either.left(transitionEnum); - } - } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java new file mode 100644 index 0000000000..b88fa903b1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java @@ -0,0 +1,569 @@ +package org.openecomp.sdc.be.externalapi.servlet; + +import java.io.IOException; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.StringUtils; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.elasticsearch.common.Strings; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter; +import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.AbstractValidationsServlet; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; + +import fj.data.Either; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "CRUD External Servlet", description = "This Servlet serves external users for creating assets and changing their lifecycle state") +@Singleton +public class CrudExternalServlet extends AbstractValidationsServlet { + + @Context + private HttpServletRequest request; + + private static Logger log = LoggerFactory.getLogger(CrudExternalServlet.class.getName()); + + /** + * Creates a new Resource + * + * @param assetType + * @param data + * @param userId + * @param instanceIdHeader + * @return + */ + @POST + @Path("/{assetType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "creates a resource", httpMethod = "POST", notes = "Creates a resource") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "ECOMP component is authenticated and Asset created", response = Resource.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "The name provided for the newly created resource is already in use for another resource in SDC - SVC4050"), + @ApiResponse(code = 400, message = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"), + @ApiResponse(code = 400, message = "Missing request body. The post request did not contain the expected body - SVC4500"), + @ApiResponse(code = 400, message = "The resource name is missing in the request body - SVC4062"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format - SVC4064"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT description has wrong format (exceeds limit) - SVC4065"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT tags exceeds character limit - SVC4066"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name exceeds character limit - SVC4067"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release exceeds character limit - SVC4068"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT ATT Contact has wrong format - SVC4069"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT name has wrong format - SVC4070"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor name has wrong format - SVC4071"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT vendor release has wrong format - SVC4072"), + @ApiResponse(code = 400, message = "Create VFCMT request: VFCMT name exceeds character limit - SVC4073")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.Resource", paramType = "body", value = "json describe the created resource")}) + public Response createResourceExternal( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType, + String data) { + + init(log); + + Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + Resource resource = null; + User modifier = null; + EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + ServletContext context = request.getSession().getServletContext(); + ResourceBusinessLogic resourceBL = getResourceBL(context); + try { + // Validate X-ECOMP-InstanceID Header + if (responseWrapper.isEmpty()) { + validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); + } + // Validate USER_ID Header + if (responseWrapper.isEmpty()) { + validateHttpCspUserIdHeader(userId, responseWrapper); + } + // Validate assetType + if (responseWrapper.isEmpty()) { + if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) ){ + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + } + //Validate resource type + if(responseWrapper.isEmpty()){ + JSONParser parser = new JSONParser(); + JSONObject jsonObj = (JSONObject) parser.parse(data); + String resourceType = (String) jsonObj.get(FilterKeyEnum.RESOURCE_TYPE.getName()); + if( StringUtils.isEmpty(resourceType) || !ResourceTypeEnum.containsName(resourceType) ){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, (String) jsonObj.get("name")); + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + // Convert the user json to a resource + if (responseWrapper.isEmpty()) { + modifier = new User(); + modifier.setUserId(userId); + Either<Resource, ResponseFormat> eitherResource = getComponentsUtils() + .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, + null, ComponentTypeEnum.RESOURCE); + if( eitherResource.isRight() ){ + responseWrapper.setInnerElement(eitherResource.right().value()); + } + else{ + resource = eitherResource.left().value(); + } + + } + //validate name exist + if(responseWrapper.isEmpty()){ + if( Strings.isEmpty(resource.getName())){ + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( + ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue())); + + } + } + + if(responseWrapper.isEmpty()){ + resource.setDerivedFrom(Arrays.asList("tosca.nodes.Root")); + resource.setSystemName(ValidationUtils.convertToSystemName(resource.getName())); + resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VFCMT.name(), + resource.getSystemName())); + handleCategories(context, data, resource, responseWrapper); + } + // Create the resource in the dataModel + if (responseWrapper.isEmpty()) { + Either<Resource, ResponseFormat> eitherCreateResponse = resourceBL.createResource(resource, null, + modifier, null, null); + if (eitherCreateResponse.isRight()) { + responseWrapper.setInnerElement(eitherCreateResponse.right().value()); + } else { + resource = eitherCreateResponse.left().value(); + } + } + Response response; + //Build Response and store it in the response Wrapper + if (responseWrapper.isEmpty()) { + response = buildCreatedResourceResponse(resource, context, responseWrapper); + } + else{ + response = buildErrorResponse(responseWrapper.getInnerElement()); + } + return response; + + } catch (Exception e) { + final String message = "failed to create vfc monitoring template resource"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + finally{ + prepareAdditionalAudit(resource, additionalParams); + + getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), + ComponentTypeEnum.RESOURCE.getValue(), AuditingActionEnum.CREATE_RESOURCE_BY_API.getName(), request, + additionalParams); + } + } + + /** + * Changing the lifecycle of an asset + * @param jsonChangeInfo The description - request body + * @param assetType The requested asset type.Valid values are: resources / services (for VFCMT – use "resources") + * @param uuid The uuid of the desired resource to be changed + * @param lifecycleTransition The lifecycle operation to be performed on the asset.Valid values are:Checkin / Checkout / CERTIFICATION_REQUEST + * @param userId + * @return + */ + @POST + @Path("/{assetType}/{uuid}/lifecycleState/{lifecycleOperation}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Resource state changed", response = AssetMetadata.class), + @ApiResponse(code = 400, message = "Missing “X-ECOMP-InstanceID” HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Error: Requested '%1' (uuid) resource was not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 403, message = "Asset is already checked-out by another user - SVC4085"), + @ApiResponse(code = 403, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4080")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction", paramType = "body", value = "userRemarks - Short description (free text) about the asset version being changed")}) + public Response changeResourceStateExternal( + @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType, + @ApiParam(value = "The user id", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(allowableValues = "checkout, checkin", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, + @ApiParam(value = "id of component to be changed") @PathParam(value = "uuid") final String uuid, + @ApiParam(value = "validValues: resources / services ", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam(value = "assetType") final String assetType, + String jsonChangeInfo) { + + Response response = null; + EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + init(log); + + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + //get the business logic + ServletContext context = request.getSession().getServletContext(); + LifecycleBusinessLogic businessLogic = getLifecycleBL(context); + + Wrapper<ResponseFormat> responseWrapper = runValidations(assetType); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + Component component = null; + Component responseObject = null; + User modifier = null; + + try{ + // Validate X-ECOMP-InstanceID Header + if (responseWrapper.isEmpty()) { + validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper); + } + + if (responseWrapper.isEmpty()) { + //get user + Either<User, ResponseFormat> eitherGetUser = getUser(request, userId); + if (eitherGetUser.isRight()) { + ResponseFormat responseFormat = eitherGetUser.right().value(); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } + modifier = eitherGetUser.left().value(); + + //get the component id from the uuid + Either<Component, ResponseFormat> latestVersion = businessLogic.getLatestComponentByUuid(componentType, uuid); + if (latestVersion.isRight()) { + ResponseFormat responseFormat = latestVersion.right().value(); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } + component = latestVersion.left().value(); + String componentId = component.getUniqueId(); + + //validate the transition is valid + Either<LifeCycleTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(lifecycleTransition, modifier); + if (validateEnum.isRight()) { + ResponseFormat responseFormat = validateEnum.right().value(); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } + LifeCycleTransitionEnum transitionEnum = validateEnum.left().value(); + + //create changeInfo + LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(); + try { + if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) { + ObjectMapper mapper = new ObjectMapper(); + changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks()); + } + } + catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", jsonChangeInfo, e); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(modifier, AuditingActionEnum.CHECKOUT_RESOURCE); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } + + //execute business logic + Either<? extends Component, ResponseFormat> actionResponse = businessLogic.changeComponentState(componentType, componentId, modifier, transitionEnum, changeInfo, false, true); + if (actionResponse.isRight()) { + log.info("failed to change resource state"); + ResponseFormat responseFormat = actionResponse.right().value(); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } + + log.debug("change state successful !!!"); + responseObject = actionResponse.left().value(); + response = buildCreatedResourceResponse(responseObject, context, responseWrapper); + } else { + response = buildErrorResponse(responseWrapper.getInnerElement()); + } + + return response; + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Change Lifecycle State"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State"); + log.debug("change lifecycle state failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(responseFormat); + return buildErrorResponse(responseFormat); + } finally{ + auditChnageLifecycleAction(additionalParams, responseWrapper, componentType, component, responseObject, modifier, userId); + } + } + + private void prepareAdditionalAudit(Resource resource, EnumMap<AuditingFieldsKeysEnum, Object> additionalParams) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, StringUtils.EMPTY); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, StringUtils.EMPTY); + + if( resource != null ){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ImportUtils.Constants.FIRST_NON_CERTIFIED_VERSION); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, resource.getUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, resource.getInvariantUUID()); + } else { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, StringUtils.EMPTY); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, StringUtils.EMPTY); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, StringUtils.EMPTY); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, StringUtils.EMPTY); + } + } + + private Response buildCreatedResourceResponse(Component resource, ServletContext context, + Wrapper<ResponseFormat> responseWrapper) throws IOException, JsonGenerationException, JsonMappingException { + ResponseFormat responseFormat; + Response response; + AssetMetadataConverter assetMetadataUtils = getAssetUtils(context); + Either<? extends AssetMetadata, ResponseFormat> resMetadata = assetMetadataUtils + .convertToSingleAssetMetadata(resource, request.getRequestURL().toString(), + true); + if (resMetadata.isRight()) { + log.debug("Asset conversion Failed"); + responseFormat = resMetadata.right().value(); + responseWrapper.setInnerElement(responseFormat); + response = buildErrorResponse(responseFormat); + }else{ + final AssetMetadata assetData = resMetadata.left().value(); + assetData.setToscaModelURL(null); + + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED)); + Object representation = RepresentationUtils.toRepresentation(assetData); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); + } + return response; + } + + private void handleCategories(ServletContext context, String data, Resource resource, + Wrapper<ResponseFormat> responseWrapper) { + try { + JSONParser parser = new JSONParser(); + JSONObject jsonObj = (JSONObject) parser.parse(data); + String category = (String) jsonObj.get(CategoryTypeEnum.CATEGORY.getValue()); + String subcategory = (String) jsonObj.get(CategoryTypeEnum.SUBCATEGORY.getValue()); + if (Strings.isEmpty(category)) { + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( + ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); + } + else if (Strings.isEmpty(subcategory)) { + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( + ActionStatus.COMPONENT_MISSING_SUBCATEGORY)); + } + if (responseWrapper.isEmpty()) { + ElementBusinessLogic elementLogic = getElementBL(context); + // get All Categories + Either<List<CategoryDefinition>, ActionStatus> allResourceCategories = elementLogic + .getAllResourceCategories(); + // Error fetching categories + if (allResourceCategories.isRight()) { + responseWrapper.setInnerElement( + getComponentsUtils().getResponseFormat(allResourceCategories.right().value())); + } else { + addCategories(resource, category, subcategory, allResourceCategories, responseWrapper); + } + } + } catch (Exception e) { + log.debug("Exception occured in addCategories: {}", e.getMessage(), e); + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + private void addCategories(Resource resource, String category, String subcategory, + Either<List<CategoryDefinition>, ActionStatus> allResourceCategories, + Wrapper<ResponseFormat> responseWrapper) { + Optional<CategoryDefinition> optionalCategory = + // Stream of all the categories + allResourceCategories.left().value().stream() + // filter in only relevant category + .filter(e -> e.getName().equals(category)) + // get the result + .findAny(); + if (!optionalCategory.isPresent()) { + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( + ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); + } else { + CategoryDefinition categoryDefinition = optionalCategory.get(); + + List<SubCategoryDefinition> subCaregories = + // Stream of all sub-categories of the relevant + // category + categoryDefinition.getSubcategories().stream() + // filter in only relevant sub-category + .filter(e -> e.getName().equals(subcategory)) + // get the result + .collect(Collectors.toList()); + + if( subCaregories.isEmpty() ){ + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat( + ActionStatus.COMPONENT_INVALID_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue())); + } + else{ + categoryDefinition.setSubcategories(subCaregories); + resource.setCategories(Arrays.asList(categoryDefinition)); + } + + } + } + + + + + private void auditChnageLifecycleAction(EnumMap<AuditingFieldsKeysEnum, Object> additionalParams, + Wrapper<ResponseFormat> responseWrapper, ComponentTypeEnum componentType, Component component, + Component responseObject, User modifier, String userId) { + if (modifier!=null){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFullName()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } else { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, userId); + } + + if (component!=null){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, component.getVersion()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, component.getLifecycleState().name()); + } else { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, ""); + } + + if (responseObject!=null){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, responseObject.getVersion()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, responseObject.getUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, responseObject.getInvariantUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,responseObject.getLifecycleState().name()); + } else { + if (component!=null){ + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, component.getVersion()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, component.getUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, component.getInvariantUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,component.getLifecycleState().name()); + } else { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE,""); + } + } + + getComponentsUtils().auditExternalCrudApi(responseWrapper.getInnerElement(), + componentType.getValue(), AuditingActionEnum.CHANGE_LIFECYCLE_BY_API.getName(), request, + additionalParams); + } + + private Wrapper<ResponseFormat> runValidations(final String assetType) { + Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); + + // Validate X-ECOMP-InstanceID Header + if (responseWrapper.isEmpty()) { + String instanceId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + validateXECOMPInstanceIDHeader(instanceId,responseWrapper); + } + // Validate USER_ID Header + if (responseWrapper.isEmpty()) { + validateHttpCspUserIdHeader(request.getHeader(Constants.USER_ID_HEADER),responseWrapper); + } + // Validate assetType + if (responseWrapper.isEmpty()) { + if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) && !AssetTypeEnum.SERVICES.getValue().equals(assetType)){ + responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + } + + return responseWrapper; + } + + private Either<LifeCycleTransitionEnum, ResponseFormat> validateTransitionEnum(final String lifecycleTransition, User user) { + LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT; + try { + transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition); + } catch (IllegalArgumentException e) { + log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString()); + ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, AuditingActionEnum.CHECKOUT_RESOURCE); + return Either.right(error); + } + return Either.left(transitionEnum); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index a7eac1b8da..65e4266d6d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -42,22 +42,7 @@ import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.model.ArtifactDefinition; -import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.ComponentInstance; -import org.openecomp.sdc.be.model.ComponentInstanceInput; -import org.openecomp.sdc.be.model.ComponentInstanceProperty; -import org.openecomp.sdc.be.model.DataTypeDefinition; -import org.openecomp.sdc.be.model.GroupDefinition; -import org.openecomp.sdc.be.model.GroupInstance; -import org.openecomp.sdc.be.model.GroupProperty; -import org.openecomp.sdc.be.model.InputDefinition; -import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; -import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; -import org.openecomp.sdc.be.model.RequirementDefinition; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.*; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; @@ -106,7 +91,7 @@ public class ToscaExportHandler { private CapabiltyRequirementConvertor capabiltyRequirementConvertor = CapabiltyRequirementConvertor.getInstance(); private PropertyConvertor propertyConvertor = PropertyConvertor.getInstance(); - + private static Logger log = LoggerFactory.getLogger(ToscaExportHandler.class.getName()); public static final String TOSCA_VERSION = "tosca_simple_yaml_1_0"; @@ -121,16 +106,16 @@ public class ToscaExportHandler { public static final String VF_MODULE_TYPE_BASE = "Base"; public static final String VF_MODULE_TYPE_EXPANSION = "Expansion"; public static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultImports(); - - - + + + public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) { Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertToToscaTemplate(component); if (toscaTemplateRes.isRight()) { return Either.right(toscaTemplateRes.right().value()); } - + ToscaTemplate toscaTemplate = toscaTemplateRes.left().value(); ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate); return Either.left(toscaRepresentation); @@ -141,15 +126,15 @@ public class ToscaExportHandler { log.debug("convertToToscaTemplate - failed to get Default Imports section from configuration"); return Either.right(ToscaError.GENERAL_ERROR); } - + ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION); toscaTemplate.setImports(new ArrayList<>(DEFAULT_IMPORTS)); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertInterfaceNodeType(component, toscaTemplate, nodeTypes); if (toscaTemplateRes.isRight()) { return Either.right(toscaTemplateRes.right().value()); - } - + } + toscaTemplate = toscaTemplateRes.left().value(); ToscaRepresentation toscaRepresentation = this.createToscaRepresentation(toscaTemplate); return Either.left(toscaRepresentation); @@ -179,10 +164,10 @@ public class ToscaExportHandler { ToscaRepresentation toscaRepresentation = new ToscaRepresentation(); toscaRepresentation.setMainYaml(sb.toString()); toscaRepresentation.setDependencies(toscaTemplate.getDependencies()); - + return toscaRepresentation; } - + public Either<ToscaTemplate, ToscaError> getDependencies(Component component) { ToscaTemplate toscaTemplate = new ToscaTemplate(null); Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports = fillImports(component, @@ -198,7 +183,7 @@ public class ToscaExportHandler { log.debug("convertToToscaTemplate - failed to get Default Imports section from configuration"); return Either.right(ToscaError.GENERAL_ERROR); } - + log.trace("start tosca export for {}", component.getUniqueId()); ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION); @@ -353,10 +338,10 @@ public class ToscaExportHandler { case SERVICE: toscaMetadata.setType(component.getComponentType().getValue()); if (!isInstance) { - // DE268546 + // DE268546 toscaMetadata.setServiceEcompNaming(((Service)component).isEcompGeneratedNaming()); toscaMetadata.setEcompGeneratedNaming(((Service)component).isEcompGeneratedNaming()); - toscaMetadata.setNamingPolicy(((Service)component).getNamingPolicy()); + toscaMetadata.setNamingPolicy(((Service)component).getNamingPolicy()); } break; default: @@ -367,26 +352,26 @@ public class ToscaExportHandler { private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) { - + if(null == DEFAULT_IMPORTS) { log.debug("convertToToscaTemplate - failed to get Default Imports section from configuration"); return Either.right(ToscaError.GENERAL_ERROR); } - + Map<String, Component> componentCache = new HashMap<>(); if (!ToscaUtils.isAtomicType(component)) { List<ComponentInstance> componentInstances = component.getComponentInstances(); if (componentInstances != null && !componentInstances.isEmpty()) { - - List<Map<String, Map<String, String>>> additionalImports = + + List<Map<String, Map<String, String>>> additionalImports = toscaTemplate.getImports() == null ? new ArrayList<>(DEFAULT_IMPORTS) : new ArrayList<>(toscaTemplate.getImports()); - + List<Triple<String, String, Component>> dependecies = new ArrayList<>(); Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); - + Map<String, Map<String, String>> importsListMember = new HashMap<>(); Map<String, String> interfaceFiles = new HashMap<>(); interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName())); @@ -397,7 +382,7 @@ public class ToscaExportHandler { keyNameBuilder.append("-interface"); importsListMember.put(keyNameBuilder.toString(), interfaceFiles); additionalImports.add(importsListMember); - + componentInstances.forEach(ci -> { createDependency(componentCache, additionalImports, dependecies, ci); }); @@ -406,7 +391,7 @@ public class ToscaExportHandler { } } else { log.debug("currently imports supported for VF and service only"); - } + } return Either.left(new ImmutablePair<ToscaTemplate, Map<String, Component>>(toscaTemplate, componentCache)); } @@ -440,7 +425,7 @@ public class ToscaExportHandler { imports.add(importsListMember); dependecies.add(new ImmutableTriple<String, String, Component>(artifactName, artifactDefinition.getEsId(), fetchedComponent)); - + if(!ToscaUtils.isAtomicType(componentRI)) { importsListMember = new HashMap<>(); Map<String, String> interfaceFiles = new HashMap<>(); @@ -481,7 +466,7 @@ public class ToscaExportHandler { //Extracted to method for code reuse return convertReqCapAndTypeName(component, toscaNode, nodeTypes, toscaNodeType, dataTypes); } - + private Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Component component, ToscaTemplate toscaNode, Map<String, ToscaNodeType> nodeTypes) { log.debug("start convert node type for {}", component.getUniqueId()); @@ -494,7 +479,7 @@ public class ToscaExportHandler { } Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value(); - + List<InputDefinition> inputDef = component.getInputs(); Map<String, ToscaProperty> inputs = new HashMap<>(); @@ -530,7 +515,7 @@ public class ToscaExportHandler { toscaNodeType = requirements.left().value(); log.debug("Requirements converted for {}", component.getUniqueId()); - + String toscaResourceName; switch (component.getComponentType()) { case RESOURCE: @@ -570,7 +555,7 @@ public class ToscaExportHandler { nodeTemplate.setType(componentInstance.getToscaComponentName()); Either<ToscaNodeTemplate, ToscaError> requirements = convertComponentInstanceRequirements(component, - componentInstance, component.getComponentInstancesRelations(), nodeTemplate); + componentInstance, component.getComponentInstancesRelations(), nodeTemplate, componentCache.get(componentInstance.getComponentUid())); if (requirements.isRight()) { convertNodeTemplatesRes = Either.right(requirements.right().value()); break; @@ -583,15 +568,15 @@ public class ToscaExportHandler { Component componentOfInstance = componentCache.get(componentInstance.getComponentUid()); nodeTemplate.setMetadata(convertMetadata(componentOfInstance, true, componentInstance)); - Either<ToscaNodeTemplate, ToscaError> capabilties = capabiltyRequirementConvertor + Either<ToscaNodeTemplate, ToscaError> capabilities = capabiltyRequirementConvertor .convertComponentInstanceCapabilties(componentInstance, dataTypes, nodeTemplate); - if (capabilties.isRight()) { + if (capabilities.isRight()) { convertNodeTemplatesRes = Either.right(requirements.right().value()); break; } - log.debug("Component instance Capabilties converted for instance {}", instanceUniqueId); + log.debug("Component instance Capabilities converted for instance {}", instanceUniqueId); - nodeTemplate = capabilties.left().value(); + nodeTemplate = capabilities.left().value(); Map<String, Object> props = new HashMap<>(); if (componentOfInstance.getComponentType() == ComponentTypeEnum.RESOURCE) { @@ -786,7 +771,7 @@ public class ToscaExportHandler { } else { Object value = null; String type = gp.getType(); - + switch (type) { case "integer": if (gp.getValue() != null) { @@ -798,7 +783,7 @@ public class ToscaExportHandler { value = Boolean.valueOf(gp.getValue()); } break; - + default: value = gp.getValue(); break; @@ -818,46 +803,46 @@ public class ToscaExportHandler { } toscaNodeType.setDescription(component.getDescription()); // or name?? } else { - String derivedFrom = null != component.getDerivedFromGenericType()? component.getDerivedFromGenericType() : "tosca.nodes.Root"; + String derivedFrom = null != component.getDerivedFromGenericType()? component.getDerivedFromGenericType() : "tosca.nodes.Root"; toscaNodeType.setDerived_from(derivedFrom); } return toscaNodeType; } - + + //TODO save the capability(type or name) info on relation data private Either<ToscaNodeTemplate, ToscaError> convertComponentInstanceRequirements(Component component, - ComponentInstance componentInstance, List<RequirementCapabilityRelDef> relations, - ToscaNodeTemplate nodeTypeTemplate) { + ComponentInstance componentInstance, List<RequirementCapabilityRelDef> relations, + ToscaNodeTemplate nodeTypeTemplate, Component originComponent) { List<ComponentInstance> instancesList = component.getComponentInstances(); List<Map<String, ToscaTemplateRequirement>> toscaRequirements = new ArrayList<>(); - Map<String, List<RequirementDefinition>> reqMap = componentInstance.getRequirements(); + Map<String, List<RequirementDefinition>> reqMap = originComponent.getRequirements(); - relations.stream().filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).forEach(req -> { + relations.stream().filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).forEach(rel -> { ComponentInstance toComponentInstance = instancesList.stream() - .filter(i -> req.getToNode().equals(i.getUniqueId())).findFirst().orElse(null); + .filter(i -> rel.getToNode().equals(i.getUniqueId())).findFirst().orElse(null); if (toComponentInstance == null) { - log.debug("Faild to create relation between node {} to node {}", componentInstance.getName(), - req.getToNode()); + log.debug("Failed to find relation between node {} to node {}", componentInstance.getName(), + rel.getToNode()); return; - } - RequirementAndRelationshipPair reqAndRelationshopPair = req.getRelationships().get(0); + RequirementAndRelationshipPair reqAndRelationshipPair = rel.getRelationships().get(0); ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement(); - toscaRequirement.setRelationship(reqAndRelationshopPair.getRelationship().getType()); toscaRequirement.setNode(toComponentInstance.getName()); Optional<RequirementDefinition> findAny = reqMap.values().stream().flatMap(e -> e.stream()) - .filter(e -> e.getName().equals(reqAndRelationshopPair.getRequirement())).findAny(); + .filter(e -> e.getName().equals(reqAndRelationshipPair.getRequirement())).findAny(); if (findAny.isPresent()) { - RequirementDefinition regDefinition = findAny.get(); - toscaRequirement.setCapability(regDefinition.getCapability()); + RequirementDefinition reqDefinition = findAny.get(); + toscaRequirement.setCapability(reqDefinition.getCapability()); + toscaRequirement.setRelationship(reqDefinition.getRelationship()); } else { - log.debug("Faild to find relation between node {} to node {}", componentInstance.getName(), - req.getToNode()); + // reqMap represents calculated requirements! if not found there, export data directly from the relation definition + log.debug("Failed to find requirement {} definition for node {}", reqAndRelationshipPair.getRequirement(), componentInstance.getName()); return; } - Map<String, ToscaTemplateRequirement> reqmap = new HashMap<String, ToscaTemplateRequirement>(); - reqmap.put(reqAndRelationshopPair.getRequirement(), toscaRequirement); - toscaRequirements.add(reqmap); + Map<String, ToscaTemplateRequirement> toscaReqMap = new HashMap<>(); + toscaReqMap.put(reqAndRelationshipPair.getRequirement(), toscaRequirement); + toscaRequirements.add(toscaReqMap); }); @@ -868,9 +853,10 @@ public class ToscaExportHandler { return Either.left(nodeTypeTemplate); } + private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component, SubstitutionMapping substitutionMapping, Map<String, DataTypeDefinition> dataTypes) { Map<String, String[]> toscaCapabilities = capabiltyRequirementConvertor.convertSubstitutionMappingCapabilities(component, dataTypes); - + if (!toscaCapabilities.isEmpty()) { substitutionMapping.setCapabilities(toscaCapabilities); } |