9f37586ce414340a6f54d6f5a43a4891ba4aada3
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / externalapi / servlet / ArtifactExternalServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.externalapi.servlet;
21
22 import com.jcabi.aspects.Loggable;
23 import fj.data.Either;
24 import io.swagger.v3.oas.annotations.Operation;
25 import io.swagger.v3.oas.annotations.Parameter;
26 import io.swagger.v3.oas.annotations.media.ArraySchema;
27 import io.swagger.v3.oas.annotations.media.Content;
28 import io.swagger.v3.oas.annotations.media.Schema;
29 import io.swagger.v3.oas.annotations.responses.ApiResponse;
30 import io.swagger.v3.oas.annotations.servers.Server;
31 import io.swagger.v3.oas.annotations.tags.Tag;
32 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.util.HashMap;
36 import java.util.Map;
37 import javax.inject.Inject;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.ws.rs.DELETE;
40 import javax.ws.rs.GET;
41 import javax.ws.rs.HeaderParam;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.Path;
44 import javax.ws.rs.PathParam;
45 import javax.ws.rs.Produces;
46 import javax.ws.rs.core.Context;
47 import javax.ws.rs.core.HttpHeaders;
48 import javax.ws.rs.core.MediaType;
49 import javax.ws.rs.core.Response;
50 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
52 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
53 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
54 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
55 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
56 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
57 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
58 import org.openecomp.sdc.be.config.BeEcompErrorManager;
59 import org.openecomp.sdc.be.dao.api.ActionStatus;
60 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
61 import org.openecomp.sdc.be.impl.ComponentsUtils;
62 import org.openecomp.sdc.be.impl.ServletUtils;
63 import org.openecomp.sdc.be.model.ArtifactDefinition;
64 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
65 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
66 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
67 import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
68 import org.openecomp.sdc.be.servlets.RepresentationUtils;
69 import org.openecomp.sdc.common.api.Constants;
70 import org.openecomp.sdc.common.datastructure.Wrapper;
71 import org.openecomp.sdc.common.log.wrappers.Logger;
72 import org.openecomp.sdc.common.util.GeneralUtility;
73 import org.openecomp.sdc.exception.ResponseFormat;
74 import org.springframework.stereotype.Controller;
75
76 /**
77  * This Servlet serves external users operations on artifacts.
78  *
79  * @author mshitrit
80  */
81 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
82 @Path("/v1/catalog")
83 @Tag(name = "SDCE-7 APIs")
84 @Server(url = "/sdc")
85 @Controller
86 public class ArtifactExternalServlet extends AbstractValidationsServlet {
87
88     private static final String FAILED_TO_UPDATE_ARTIFACT = "failed to update artifact";
89     private static final String DOUBLE_CURLY_BRACKETS = "{} {}";
90     private static final Logger log = Logger.getLogger(ArtifactExternalServlet.class);
91     private static String startLog = "Start handle request of ";
92     private final ArtifactsBusinessLogic artifactsBusinessLogic;
93     @Context
94     private HttpServletRequest request;
95
96     @Inject
97     public ArtifactExternalServlet(ComponentInstanceBusinessLogic componentInstanceBL,
98                                    ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager,
99                                    ArtifactsBusinessLogic artifactsBusinessLogic) {
100         super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
101         this.artifactsBusinessLogic = artifactsBusinessLogic;
102     }
103
104     @POST
105     @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}")
106     @Produces(MediaType.APPLICATION_JSON)
107     @Operation(parameters = {
108         @Parameter(required = true, schema = @Schema(implementation = org.openecomp.sdc.be.model.ArtifactDefinition.class))}, description = "uploads of artifact to VF operation workflow", method = "POST", summary = "uploads of artifact to VF operation workflow", responses = {
109         @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
110         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
111         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
112         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
113         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
114         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
115         @ApiResponse(responseCode = "500", description = "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"),
116         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
117         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
118         @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
119         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
120         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
121         @ApiResponse(responseCode = "400", description = "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"),
122         @ApiResponse(responseCode = "400", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
123     public Response uploadInterfaceOperationArtifact(
124         @Parameter(description = "Determines the format of the body of the request", required = true) @HeaderParam(value = HttpHeaders.CONTENT_TYPE) String contentType,
125         @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum,
126         @Parameter(description = "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,
127         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
128         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
129         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
130         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
131         @Parameter(description = "Asset type") @PathParam("assetType") String assetType,
132         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
133         @Parameter(description = "The uuid of the interface", required = true) @PathParam("interfaceUUID") final String interfaceUUID,
134         @Parameter(description = "The uuid of the operation", required = true) @PathParam("operationUUID") final String operationUUID,
135         @Parameter(description = "The uuid of the artifact", required = true) @PathParam("artifactUUID") final String artifactUUID,
136         @Parameter(hidden = true) String data) {
137         Wrapper<Response> responseWrapper = new Wrapper<>();
138         ResponseFormat responseFormat = null;
139         String requestURI = request.getRequestURI();
140         String url = request.getMethod() + " " + requestURI;
141         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
142         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(assetType);
143         ArtifactDefinition artifactDefinition = null;
144         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
145             log.debug("updateArtifact: Missing X-ECOMP-InstanceID header");
146             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
147             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
148         }
149         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
150             log.debug("updateArtifact: Missing USER_ID");
151             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
152             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
153         }
154         try {
155             if (responseWrapper.isEmpty()) {
156                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsBusinessLogic
157                     .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum.findByParamName(assetType), uuid,
158                         interfaceUUID, operationUUID, artifactUUID, resourceCommonInfo,
159                         new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
160                 if (uploadArtifactEither.isRight()) {
161                     log.debug(FAILED_TO_UPDATE_ARTIFACT);
162                     responseFormat = uploadArtifactEither.right().value();
163                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
164                 } else {
165                     artifactDefinition = uploadArtifactEither.left().value();
166                     Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
167                     Map<String, String> headers = new HashMap<>();
168                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
169                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
170                     responseWrapper
171                         .setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
172                 }
173             }
174         } catch (Exception e) {
175             final String message = "failed to update artifact on a resource or service";
176             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
177             log.debug(message, e);
178             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
179         } finally {
180             getComponentsUtils()
181                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, resourceCommonInfo, request, artifactDefinition,
182                     null);
183         }
184         return responseWrapper.getInnerElement();
185     }
186
187     /**
188      * Uploads an artifact to resource or service
189      */
190     @POST
191     @Path("/{assetType}/{uuid}/artifacts")
192     @Produces(MediaType.APPLICATION_JSON)
193     @Operation(parameters = {
194         @Parameter(required = true, schema = @Schema(implementation = org.openecomp.sdc.be.model.ArtifactDefinition.class))}, description = "uploads of artifact to a resource or service", method = "POST", summary = "uploads of artifact to a resource or service", responses = {
195         @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
196         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
197         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
198         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
199         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
200         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
201         @ApiResponse(responseCode = "500", description = "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"),
202         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
203         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
204         @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
205         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
206         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
207         @ApiResponse(responseCode = "400", description = "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"),
208         @ApiResponse(responseCode = "400", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
209     @PermissionAllowed({AafPermission.PermNames.WRITE_VALUE})
210     public Response uploadArtifact(
211         @Parameter(description = "Determines the format of the body of the request", required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
212         @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum,
213         @Parameter(description = "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,
214         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
215         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
216         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
217         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
218         @Parameter(schema = @Schema(allowableValues = {
219             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
220         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
221         @Parameter(hidden = true) String data) {
222         init();
223         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
224         String requestURI = request.getRequestURI();
225         String url = request.getMethod() + " " + requestURI;
226         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
227         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
228         String componentTypeValue = componentType == null ? null : componentType.getValue();
229         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue);
230         if (componentType == null) {
231             log.debug("uploadArtifact: assetType parameter {} is not valid", assetType);
232             responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
233         }
234         if (responseWrapper.isEmpty()) {
235             validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
236         }
237         if (responseWrapper.isEmpty()) {
238             validateHttpCspUserIdHeader(userId, responseWrapper);
239         }
240         Response response = null;
241         ArtifactDefinition artifactDefinition = null;
242         try {
243             if (responseWrapper.isEmpty()) {
244                 artifactDefinition = artifactsBusinessLogic.uploadArtifactToComponentByUUID(data, request, componentType, uuid, resourceCommonInfo,
245                     new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE));
246                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
247                 Map<String, String> headers = new HashMap<>();
248                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
249                 responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.OK));
250                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers);
251             }
252         } catch (IOException e) {
253             final String message = "failed to upload artifact to a resource or service";
254             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
255             log.debug(message, e);
256             responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
257             response = buildErrorResponse(responseWrapper.getInnerElement());
258         } catch (ComponentException e) {
259             responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(e));
260         } finally {
261             if (response == null) {
262                 response = buildErrorResponse(responseWrapper.getInnerElement());
263             }
264             getComponentsUtils()
265                 .auditExternalCrudApi(responseWrapper.getInnerElement(), AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, resourceCommonInfo, request,
266                     artifactDefinition, null);
267         }
268         return response;
269     }
270
271     /**
272      * Uploads an artifact to resource instance
273      */
274     @POST
275     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts")
276     @Produces(MediaType.APPLICATION_JSON)
277     @Operation(parameters = {
278         @Parameter(required = true, schema = @Schema(implementation = org.openecomp.sdc.be.model.ArtifactDefinition.class), description = "json describe the artifact")}, description = "uploads an artifact to a resource instance", method = "POST", summary = "uploads an artifact to a resource instance", responses = {
279         @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
280         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
281         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
282         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
283         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
284         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
285         @ApiResponse(responseCode = "500", description = "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"),
286         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
287         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
288         @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
289         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
290         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
291         @ApiResponse(responseCode = "400", description = "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"),
292         @ApiResponse(responseCode = "400", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
293     @PermissionAllowed(AafPermission.PermNames.WRITE_VALUE)
294     public Response uploadArtifactToInstance(
295         @Parameter(description = "Determines the format of the body of the request", required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
296         @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum,
297         @Parameter(description = "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,
298         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
299         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
300         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
301         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
302         @Parameter(schema = @Schema(allowableValues = {
303             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
304         @Parameter(schema = @Schema(allowableValues = {
305             "resources,services"}), description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
306         @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", required = true) @PathParam("resourceInstanceName") final String resourceInstanceName,
307         @Parameter(hidden = true) String data) {
308         Wrapper<Response> responseWrapper = new Wrapper<>();
309         ResponseFormat responseFormat = null;
310         String requestURI = request.getRequestURI();
311         String url = request.getMethod() + " " + requestURI;
312         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
313         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
314         String componentTypeValue = componentType == null ? null : componentType.getValue();
315         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue);
316         ArtifactDefinition artifactDefinition = null;
317         if (componentType == null) {
318             log.debug("uploadArtifact: assetType parameter {} is not valid", assetType);
319             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
320             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
321         }
322         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
323             log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header");
324             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
325             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
326         }
327         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
328             log.debug("uploadArtifact: Missing USER_ID header");
329             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
330             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
331         }
332         try {
333             if (responseWrapper.isEmpty()) {
334                 artifactDefinition = artifactsBusinessLogic.uploadArtifactToRiByUUID(data, request, componentType, uuid, resourceInstanceName,
335                     new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE));
336                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
337                 Map<String, String> headers = new HashMap<>();
338                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
339                 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
340                 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
341             }
342         } catch (IOException e) {
343             final String message = "failed to upload artifact to a resource instance";
344             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
345             log.debug(message, e);
346             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
347             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
348         } catch (ComponentException e) {
349             responseFormat = getComponentsUtils().getResponseFormat(e);
350             throw e;
351         } finally {
352             getComponentsUtils()
353                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API, resourceCommonInfo, request, artifactDefinition,
354                     null);
355         }
356         return responseWrapper.getInnerElement();
357     }
358
359     @POST
360     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
361     @Produces(MediaType.APPLICATION_JSON)
362     @Operation(parameters = {
363         @Parameter(required = true, schema = @Schema(implementation = org.openecomp.sdc.be.model.ArtifactDefinition.class), description = "json describe the artifact")}, description = "updates an artifact on a resource or service", method = "POST", summary = "uploads of artifact to a resource or service", responses = {
364         @ApiResponse(responseCode = "200", description = "Artifact updated", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
365         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
366         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
367         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
368         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
369         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
370         @ApiResponse(responseCode = "500", description = "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"),
371         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
372         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
373         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
374         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
375         @ApiResponse(responseCode = "403", description = "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"),
376         @ApiResponse(responseCode = "409", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
377     @PermissionAllowed(AafPermission.PermNames.WRITE_VALUE)
378     public Response updateArtifact(
379         @Parameter(description = "Determines the format of the body of the request", required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
380         @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum,
381         @Parameter(description = "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,
382         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
383         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
384         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
385         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
386         @Parameter(schema = @Schema(allowableValues = {
387             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
388         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
389         @Parameter(description = "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,
390         @Parameter(hidden = true) String data) {
391         Wrapper<Response> responseWrapper = new Wrapper<>();
392         ResponseFormat responseFormat = null;
393         String requestURI = request.getRequestURI();
394         String url = request.getMethod() + " " + requestURI;
395         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
396         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
397         String componentTypeValue = componentType == null ? null : componentType.getValue();
398         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue);
399         if (componentType == null) {
400             log.debug("updateArtifact: assetType parameter {} is not valid", assetType);
401             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
402             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
403         }
404         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
405             log.debug("updateArtifact: Missing X-ECOMP-InstanceID header");
406             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
407             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
408         }
409         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
410             log.debug("updateArtifact: Missing USER_ID");
411             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
412             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
413         }
414         ArtifactDefinition artifactDefinition = null;
415         try {
416             if (responseWrapper.isEmpty()) {
417                 artifactDefinition = artifactsBusinessLogic
418                     .updateArtifactOnComponentByUUID(data, request, componentType, uuid, artifactUUID, resourceCommonInfo,
419                         new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
420                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
421                 Map<String, String> headers = new HashMap<>();
422                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
423                 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
424                 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
425             }
426         } catch (IOException e) {
427             final String message = "failed to update artifact on a resource or service";
428             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
429             log.debug(message, e);
430             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
431             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
432         } catch (ComponentException e) {
433             responseFormat = getComponentsUtils().getResponseFormat(e);
434             throw e;
435         } finally {
436             getComponentsUtils()
437                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, resourceCommonInfo, request, artifactDefinition,
438                     artifactUUID);
439         }
440         return responseWrapper.getInnerElement();
441     }
442
443     /**
444      * updates an artifact on a resource instance
445      */
446     @POST
447     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
448     @Produces(MediaType.APPLICATION_JSON)
449     @Operation(parameters = {
450         @Parameter(required = true, schema = @Schema(implementation = org.openecomp.sdc.be.model.ArtifactDefinition.class), description = "json describe the artifact")}, description = "updates an artifact on a resource instance", method = "POST", summary = "uploads of artifact to a resource or service", responses = {
451         @ApiResponse(responseCode = "200", description = "Artifact updated", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
452         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
453         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
454         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
455         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
456         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
457         @ApiResponse(responseCode = "500", description = "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"),
458         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
459         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
460         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
461         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
462         @ApiResponse(responseCode = "403", description = "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"),
463         @ApiResponse(responseCode = "409", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
464     @PermissionAllowed(AafPermission.PermNames.WRITE_VALUE)
465     public Response updateArtifactOnResourceInstance(
466         @Parameter(description = "Determines the format of the body of the request", required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
467         @Parameter(description = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum,
468         @Parameter(description = "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,
469         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
470         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
471         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
472         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
473         @Parameter(schema = @Schema(allowableValues = {
474             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
475         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
476         @Parameter(description = "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,
477         @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", required = true) @PathParam("resourceInstanceName") final String resourceInstanceName,
478         @Parameter(hidden = true) String data) {
479         Wrapper<Response> responseWrapper = new Wrapper<>();
480         ResponseFormat responseFormat = null;
481         String requestURI = request.getRequestURI();
482         String url = request.getMethod() + " " + requestURI;
483         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
484         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
485         String componentTypeValue = componentType == null ? null : componentType.getValue();
486         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue);
487         if (componentType == null) {
488             log.debug("updateArtifactOnResourceInstance: assetType parameter {} is not valid", assetType);
489             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
490             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
491         }
492         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
493             log.debug("updateArtifactOnResourceInstance: Missing X-ECOMP-InstanceID header");
494             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
495             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
496         }
497         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
498             log.debug("updateArtifactOnResourceInstance: Missing USER_ID header");
499             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
500             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
501         }
502         ArtifactDefinition artifactDefinition = null;
503         try {
504             if (responseWrapper.isEmpty()) {
505                 artifactDefinition = artifactsBusinessLogic
506                     .updateArtifactOnRiByUUID(data, request, componentType, uuid, resourceInstanceName, artifactUUID,
507                         new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
508                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
509                 Map<String, String> headers = new HashMap<>();
510                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
511                 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
512                 responseWrapper.setInnerElement(buildOkResponse(responseFormat, representation, headers));
513             }
514         } catch (IOException e) {
515             final String message = "failed to update artifact on resource instance";
516             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
517             log.debug(message, e);
518             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
519             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
520         } catch (ComponentException e) {
521             responseFormat = getComponentsUtils().getResponseFormat(e);
522             throw e;
523         } finally {
524             getComponentsUtils()
525                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_UPDATE_BY_API, resourceCommonInfo, request, artifactDefinition,
526                     artifactUUID);
527         }
528         return responseWrapper.getInnerElement();
529     }
530
531     /**
532      * deletes an artifact of a resource or service
533      */
534     @DELETE
535     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
536     @Produces(MediaType.APPLICATION_JSON)
537     @Operation(description = "deletes an artifact of a resource or service", method = "DELETE", summary = "deletes an artifact of a resource or service", responses = {
538         @ApiResponse(description = "default response", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
539         @ApiResponse(responseCode = "200", description = "Artifact deleted", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
540         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
541         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
542         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
543         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
544         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
545         @ApiResponse(responseCode = "500", description = "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"),
546         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
547         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
548         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
549         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
550         @ApiResponse(responseCode = "403", description = "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"),
551         @ApiResponse(responseCode = "409", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
552     @PermissionAllowed(AafPermission.PermNames.DELETE_VALUE)
553     public Response deleteArtifact(
554         @Parameter(description = "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,
555         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
556         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
557         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
558         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
559         @Parameter(schema = @Schema(allowableValues = {
560             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
561         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
562         @Parameter(description = "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) {
563         Wrapper<Response> responseWrapper = new Wrapper<>();
564         ResponseFormat responseFormat = null;
565         String requestURI = request.getRequestURI();
566         String url = request.getMethod() + " " + requestURI;
567         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
568         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
569         String componentTypeValue = componentType == null ? null : componentType.getValue();
570         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue);
571         ArtifactDefinition artifactDefinition = null;
572         if (componentType == null) {
573             log.debug("deleteArtifact: assetType parameter {} is not valid", assetType);
574             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
575             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
576         }
577         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
578             log.debug("deleteArtifact: Missing X-ECOMP-InstanceID header");
579             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
580             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
581         }
582         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
583             log.debug("deleteArtifact: Missing USER_ID header");
584             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
585             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
586         }
587         try {
588             if (responseWrapper.isEmpty()) {
589                 artifactDefinition = artifactsBusinessLogic
590                     .deleteArtifactOnComponentByUUID(request, componentType, uuid, artifactUUID, resourceCommonInfo,
591                         new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE));
592                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
593                 Map<String, String> headers = new HashMap<>();
594                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
595                 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
596                 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
597             }
598         } catch (IOException e) {
599             final String message = "failed to delete an artifact of a resource or service";
600             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
601             log.debug(message, e);
602             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
603             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
604         } catch (ComponentException e) {
605             responseFormat = getComponentsUtils().getResponseFormat(e);
606             throw e;
607         } finally {
608             getComponentsUtils()
609                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, resourceCommonInfo, request, artifactDefinition,
610                     artifactUUID);
611         }
612         return responseWrapper.getInnerElement();
613     }
614
615     /**
616      * deletes an artifact of a resource instance
617      */
618     @DELETE
619     @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
620     @Produces(MediaType.APPLICATION_JSON)
621     @Operation(description = "deletes an artifact of a resource insatnce", method = "DELETE", summary = "deletes an artifact of a resource insatnce", responses = {
622         @ApiResponse(description = "default response", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
623         @ApiResponse(responseCode = "200", description = "Artifact deleted", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
624         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
625         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
626         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
627         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
628         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
629         @ApiResponse(responseCode = "500", description = "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"),
630         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
631         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
632         @ApiResponse(responseCode = "400", description = "Invalid MD5 header - SVC4127"),
633         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
634         @ApiResponse(responseCode = "403", description = "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"),
635         @ApiResponse(responseCode = "409", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
636     @PermissionAllowed(AafPermission.PermNames.DELETE_VALUE)
637     public Response deleteArtifactOnResourceInstance(
638         @Parameter(description = "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,
639         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
640         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
641         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
642         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
643         @Parameter(schema = @Schema(allowableValues = {
644             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
645         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
646         @Parameter(description = "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,
647         @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", required = true) @PathParam("resourceInstanceName") final String resourceInstanceName) {
648         Wrapper<Response> responseWrapper = new Wrapper<>();
649         ResponseFormat responseFormat = null;
650         String requestURI = request.getRequestURI();
651         String url = request.getMethod() + " " + requestURI;
652         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
653         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
654         String componentTypeValue = componentType == null ? null : componentType.getValue();
655         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(resourceInstanceName, componentTypeValue);
656         if (componentType == null) {
657             log.debug("deleteArtifactOnResourceInsatnce: assetType parameter {} is not valid", assetType);
658             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
659             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
660         }
661         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
662             log.debug("deleteArtifactOnResourceInsatnce: Missing X-ECOMP-InstanceID header");
663             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
664             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
665         }
666         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
667             log.debug("deleteArtifactOnResourceInsatnce: Missing USER_ID header");
668             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
669             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
670         }
671         ArtifactDefinition artifactDefinition = null;
672         try {
673             if (responseWrapper.isEmpty()) {
674                 artifactDefinition = artifactsBusinessLogic.deleteArtifactOnRiByUUID(request, componentType, uuid, resourceInstanceName, artifactUUID,
675                     new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE));
676                 Object representation = RepresentationUtils.toRepresentation(artifactDefinition);
677                 Map<String, String> headers = new HashMap<>();
678                 headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
679                 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
680                 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
681             }
682         } catch (IOException e) {
683             final String message = "failed to delete an artifact of a resource instance";
684             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
685             log.debug(message, e);
686             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
687             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
688         } catch (ComponentException e) {
689             responseFormat = getComponentsUtils().getResponseFormat(e);
690             throw e;
691         } finally {
692             getComponentsUtils()
693                 .auditExternalCrudApi(responseFormat, AuditingActionEnum.ARTIFACT_DELETE_BY_API, resourceCommonInfo, request, artifactDefinition,
694                     artifactUUID);
695         }
696         return responseWrapper.getInnerElement();
697     }
698
699     /**
700      * downloads an artifact of a component (either a service or a resource) by artifactUUID
701      */
702     @GET
703     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
704     @Produces(MediaType.APPLICATION_OCTET_STREAM)
705     @Operation(description = "Download component artifact", method = "GET", summary = "Returns downloaded artifact", responses = {
706         @ApiResponse(responseCode = "200", description = "Artifact downloaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class)))),
707         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
708         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
709         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
710         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
711         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
712         @ApiResponse(responseCode = "500", description = "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"),
713         @ApiResponse(responseCode = "404", description = "Artifact was not found - SVC4505")})
714     @PermissionAllowed(AafPermission.PermNames.DELETE_VALUE)
715     public Response downloadComponentArtifact(
716         @Parameter(description = "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,
717         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
718         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
719         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
720         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
721         @Parameter(schema = @Schema(allowableValues = {
722             "resources,services"}), description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
723         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
724         @Parameter(description = "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) {
725         Wrapper<Response> responseWrapper = new Wrapper<>();
726         ResponseFormat responseFormat = null;
727         String requestURI = request.getRequestURI();
728         String url = request.getMethod() + " " + requestURI;
729         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
730         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
731         String componentTypeValue = componentType == null ? null : componentType.getValue();
732         if (componentType == null) {
733             log.debug("downloadComponentArtifact: assetType parameter {} is not valid", assetType);
734             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
735             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
736         }
737         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
738             log.debug("downloadComponentArtifact: Missing X-ECOMP-InstanceID header");
739             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
740             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
741         }
742         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue);
743         if (!responseWrapper.isEmpty()) {
744             getComponentsUtils().auditExternalDownloadArtifact(responseFormat,
745                 resourceCommonInfo, new DistributionData(instanceIdHeader, requestURI),
746                 requestId, artifactUUID, userId);
747             return responseWrapper.getInnerElement();
748         }
749         byte[] value = artifactsBusinessLogic.downloadComponentArtifactByUUIDs(componentType, uuid, artifactUUID, resourceCommonInfo);
750         try (InputStream is = new ByteArrayInputStream(value)) {
751             Map<String, String> headers = new HashMap<>();
752             headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value));
753             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
754             responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers));
755         } catch (ComponentException e) {
756             responseFormat = getComponentsUtils().getResponseFormat(e);
757             throw e;
758         } catch (IOException e) {
759             log.debug("close ByteArrayInputStream error");
760         } finally {
761             getComponentsUtils()
762                 .auditExternalDownloadArtifact(responseFormat, resourceCommonInfo, new DistributionData(instanceIdHeader, requestURI), requestId,
763                     artifactUUID, userId);
764         }
765         return responseWrapper.getInnerElement();
766     }
767
768     /**
769      * downloads an artifact of a resource instance of a component (either a service or a resource) by artifactUUID
770      */
771     @GET
772     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
773     @Produces(MediaType.APPLICATION_OCTET_STREAM)
774     @Operation(description = "Download resource instance artifact", method = "GET", summary = "Returns downloaded artifact", responses = {
775         @ApiResponse(description = "default response", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
776         @ApiResponse(responseCode = "200", description = "Artifact downloaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = String.class)))),
777         @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
778         @ApiResponse(responseCode = "401", description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
779         @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
780         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
781         @ApiResponse(responseCode = "405", description = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
782         @ApiResponse(responseCode = "500", description = "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"),
783         @ApiResponse(responseCode = "404", description = "Artifact was not found - SVC4505")})
784     @PermissionAllowed(AafPermission.PermNames.READ_VALUE)
785     public Response downloadResourceInstanceArtifact(
786         @Parameter(description = "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,
787         @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
788         @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
789         @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
790         @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
791         @Parameter(description = "The requested asset type", required = true) @PathParam("assetType") final String assetType,
792         @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
793         @Parameter(description = "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,
794         @Parameter(description = "The component instance name (as publishedin the response of the detailed query)", required = true) @PathParam("resourceInstanceName") final String resourceInstanceName) {
795         Wrapper<Response> responseWrapper = new Wrapper<>();
796         ResponseFormat responseFormat = null;
797         String requestURI = request.getRequestURI();
798         String url = request.getMethod() + " " + requestURI;
799         log.debug(DOUBLE_CURLY_BRACKETS, startLog, url);
800         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
801         String componentTypeValue = componentType == null ? null : componentType.getValue();
802         if (componentType == null) {
803             log.debug("downloadResourceInstanceArtifact: assetType parameter {} is not valid", assetType);
804             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
805             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
806         }
807         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
808             log.debug("downloadResourceInstanceArtifact: Missing X-ECOMP-InstanceID header");
809             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
810             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
811         }
812         if (!responseWrapper.isEmpty()) {
813             getComponentsUtils().auditExternalDownloadArtifact(responseFormat, new ResourceCommonInfo(resourceInstanceName, componentTypeValue),
814                 new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId);
815             return responseWrapper.getInnerElement();
816         }
817         byte[] value = artifactsBusinessLogic
818             .downloadResourceInstanceArtifactByUUIDs(componentType, uuid, resourceInstanceName, artifactUUID);
819         try (InputStream is = new ByteArrayInputStream(value)) {
820             Map<String, String> headers = new HashMap<>();
821             headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value));
822             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
823             responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers));
824         } catch (ComponentException e) {
825             responseFormat = getComponentsUtils().getResponseFormat(e);
826             throw e;
827         } catch (IOException e) {
828             log.debug("close ByteArrayInputStream error");
829         } finally {
830             getComponentsUtils().auditExternalDownloadArtifact(responseFormat, new ResourceCommonInfo(resourceInstanceName, componentTypeValue),
831                 new DistributionData(instanceIdHeader, requestURI), requestId, artifactUUID, userId);
832         }
833         return responseWrapper.getInnerElement();
834     }
835 }