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