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