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