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