f751ea09e7706e81a5a4b708d150075f02314852
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ArtifactServlet.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.servlets;
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.servers.Servers;
32 import io.swagger.v3.oas.annotations.tags.Tag;
33 import io.swagger.v3.oas.annotations.tags.Tags;
34 import java.util.Map;
35 import javax.inject.Inject;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.ws.rs.Consumes;
38 import javax.ws.rs.DELETE;
39 import javax.ws.rs.GET;
40 import javax.ws.rs.HeaderParam;
41 import javax.ws.rs.POST;
42 import javax.ws.rs.Path;
43 import javax.ws.rs.PathParam;
44 import javax.ws.rs.Produces;
45 import javax.ws.rs.core.Context;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import org.apache.commons.codec.binary.Base64;
49 import org.apache.commons.lang3.tuple.ImmutablePair;
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.aaf.AafPermission;
53 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
54 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
55 import org.openecomp.sdc.be.config.BeEcompErrorManager;
56 import org.openecomp.sdc.be.dao.api.ActionStatus;
57 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
58 import org.openecomp.sdc.be.impl.ComponentsUtils;
59 import org.openecomp.sdc.be.model.ArtifactDefinition;
60 import org.openecomp.sdc.be.model.ArtifactUiDownloadData;
61 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
62 import org.openecomp.sdc.common.api.Constants;
63 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
64 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
65 import org.openecomp.sdc.common.log.enums.StatusCode;
66 import org.openecomp.sdc.common.log.wrappers.Logger;
67 import org.openecomp.sdc.exception.ResponseFormat;
68 import org.springframework.stereotype.Controller;
69
70 /**
71  * Root resource (exposed at "/" path)
72  */
73 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
74 @Path("/v1/catalog")
75 @Tags({@Tag(name = "SDCE-2 APIs")})
76 @Servers({@Server(url = "/sdc2/rest")})
77 @Controller
78 public class ArtifactServlet extends BeGenericServlet {
79
80     private static final Logger log = Logger.getLogger(ArtifactServlet.class);
81     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ArtifactServlet.class.getName());
82     private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
83     private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64 = "downloadResourceInstanceArtifactBase64";
84     private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION = "downloadResourceInstanceArtifactBase64 unexpected exception";
85     private final ArtifactsBusinessLogic artifactsBusinessLogic;
86
87     @Inject
88     public ArtifactServlet(ComponentsUtils componentsUtils, ArtifactsBusinessLogic artifactsBusinessLogic) {
89         super(componentsUtils);
90         this.artifactsBusinessLogic = artifactsBusinessLogic;
91     }
92
93     // *************** Resources
94     @POST
95     @Path("/resources/{resourceId}/artifacts")
96     @Consumes(MediaType.APPLICATION_JSON)
97     @Produces(MediaType.APPLICATION_JSON)
98     @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
99         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
100         @ApiResponse(responseCode = "201", description = "Resource created"),
101         @ApiResponse(responseCode = "403", description = "Restricted operation"),
102         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
103         @ApiResponse(responseCode = "409", description = "Artifact already exist")})
104     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
105     public Response loadArtifact(@PathParam("resourceId") final String resourceId,
106                                  @Parameter(description = "json describe the artifact", required = true) String data,
107                                  @Context final HttpServletRequest request) {
108         String url = request.getMethod() + " " + request.getRequestURI();
109         log.debug(START_HANDLE_REQUEST_OF, url);
110         return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE);
111     }
112
113     @POST
114     @Path("/resources/{resourceId}/artifacts/{artifactId}")
115     @Consumes(MediaType.APPLICATION_JSON)
116     @Produces(MediaType.APPLICATION_JSON)
117     @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
118         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
119         @ApiResponse(responseCode = "201", description = "Resource created"),
120         @ApiResponse(responseCode = "403", description = "Restricted operation"),
121         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
122     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
123     public Response updateArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
124                                    @Parameter(description = "json describe the artifact", required = true) String data,
125                                    @Context final HttpServletRequest request) {
126         String url = request.getMethod() + " " + request.getRequestURI();
127         log.debug(START_HANDLE_REQUEST_OF, url);
128         try {
129             return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE);
130         } catch (Exception e) {
131             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact");
132             log.debug("updateArtifact unexpected exception", e);
133             throw e;
134         }
135     }
136
137     @DELETE
138     @Path("/resources/{resourceId}/artifacts/{artifactId}")
139     @Consumes(MediaType.APPLICATION_JSON)
140     @Produces(MediaType.APPLICATION_JSON)
141     @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
142         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
143         @ApiResponse(responseCode = "201", description = "Resource created"),
144         @ApiResponse(responseCode = "403", description = "Restricted operation"),
145         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
146     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
147     public Response deleteArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
148                                    @Context final HttpServletRequest request) {
149         String url = request.getMethod() + " " + request.getRequestURI();
150         log.debug(START_HANDLE_REQUEST_OF, url);
151         try {
152             return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null);
153         } catch (Exception e) {
154             log.debug("deleteArtifact unexpected exception", e);
155             throw e;
156         }
157     }
158
159     // *************** Services
160     @POST
161     @Path("/services/{serviceId}/artifacts")
162     @Consumes(MediaType.APPLICATION_JSON)
163     @Produces(MediaType.APPLICATION_JSON)
164     @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
165         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
166         @ApiResponse(responseCode = "201", description = "Resource created"),
167         @ApiResponse(responseCode = "403", description = "Restricted operation"),
168         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
169         @ApiResponse(responseCode = "409", description = "Artifact already exist")})
170     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
171     public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId,
172                                             @Parameter(description = "json describe the artifact", required = true) String data,
173                                             @Context final HttpServletRequest request) {
174         String url = request.getMethod() + " " + request.getRequestURI();
175         log.debug(START_HANDLE_REQUEST_OF, url);
176         try {
177             return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE);
178         } catch (Exception e) {
179             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact");
180             log.debug("loadInformationArtifact unexpected exception", e);
181             throw e;
182         }
183     }
184
185     @POST
186     @Path("/services/{serviceId}/artifacts/{artifactId}")
187     @Consumes(MediaType.APPLICATION_JSON)
188     @Produces(MediaType.APPLICATION_JSON)
189     @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
190         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
191         @ApiResponse(responseCode = "201", description = "Service artifact created"),
192         @ApiResponse(responseCode = "403", description = "Restricted operation"),
193         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
194     public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
195                                               @Parameter(description = "json describe the artifact", required = true) String data,
196                                               @Context final HttpServletRequest request) {
197         String url = request.getMethod() + " " + request.getRequestURI();
198         log.debug(START_HANDLE_REQUEST_OF, url);
199         try {
200             return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
201         } catch (Exception e) {
202             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact");
203             log.debug("updateInformationArtifact unexpected exception", e);
204             throw e;
205         }
206     }
207
208     // *************** Services api artifacts
209     @POST
210     @Path("/services/{serviceId}/artifacts/api/{artifactId}")
211     @Consumes(MediaType.APPLICATION_JSON)
212     @Produces(MediaType.APPLICATION_JSON)
213     @Operation(description = "Update Api Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
214         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
215         @ApiResponse(responseCode = "200", description = "Api Artifact Updated"),
216         @ApiResponse(responseCode = "403", description = "Restricted operation"),
217         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
218     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
219     public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
220                                       @Parameter(description = "json describe the artifact", required = true) String data,
221                                       @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
222                                       @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
223         String url = request.getMethod() + " " + request.getRequestURI();
224         log.debug(START_HANDLE_REQUEST_OF, url);
225         try {
226             return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
227         } catch (Exception e) {
228             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact");
229             log.debug("updateApiArtifact unexpected exception", e);
230             throw e;
231         }
232     }
233
234     @DELETE
235     @Path("/services/{serviceId}/artifacts/api/{artifactId}")
236     @Consumes(MediaType.APPLICATION_JSON)
237     @Produces(MediaType.APPLICATION_JSON)
238     @Operation(description = "Delete Api Artifact", method = "DELETE", summary = "Returns Deleted ArtifactDefinition", responses = {
239         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
240         @ApiResponse(responseCode = "204", description = "Api Artifact deleted"),
241         @ApiResponse(responseCode = "403", description = "Restricted operation")})
242     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
243     public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
244                                       @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
245                                       @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
246         String url = request.getMethod() + " " + request.getRequestURI();
247         log.debug(START_HANDLE_REQUEST_OF, url);
248         try {
249             return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
250         } catch (Exception e) {
251             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact");
252             log.debug("deleteApiArtifact unexpected exception", e);
253             throw e;
254         }
255     }
256
257     @DELETE
258     @Path("/services/{serviceId}/artifacts/{artifactId}")
259     @Consumes(MediaType.APPLICATION_JSON)
260     @Produces(MediaType.APPLICATION_JSON)
261     @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
262         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
263         @ApiResponse(responseCode = "201", description = "Service artifact deleted"),
264         @ApiResponse(responseCode = "403", description = "Restricted operation"),
265         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
266     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
267     public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
268                                                 @Context final HttpServletRequest request) {
269         String url = request.getMethod() + " " + request.getRequestURI();
270         log.debug(START_HANDLE_REQUEST_OF, url);
271         try {
272             return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
273         } catch (Exception e) {
274             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact");
275             log.debug("deleteInformationalArtifact unexpected exception", e);
276             throw e;
277         }
278     }
279
280     /*
281      * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href)
282      */
283     @GET
284     @Path("/services/{serviceId}/artifacts/{artifactId}")
285     @Consumes(MediaType.APPLICATION_JSON)
286     @Produces(MediaType.APPLICATION_JSON)
287     @Operation(description = "Download service Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
288         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
289         @ApiResponse(responseCode = "200", description = "Service artifact downloaded"),
290         @ApiResponse(responseCode = "404", description = "Service/Artifact not found")})
291     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
292     public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
293                                                   @Context final HttpServletRequest request) {
294         String url = request.getMethod() + " " + request.getRequestURI();
295         Response response;
296         log.debug(START_HANDLE_REQUEST_OF, url);
297         try {
298             response = handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null);
299         } catch (Exception e) {
300             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64");
301             log.debug("downloadServiceArtifactBase64 unexpected exception", e);
302             throw e;
303         } finally {
304             loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE, "Ended download Service Artifact ");
305         }
306         return response;
307     }
308
309     @GET
310     @Path("/resources/{resourceId}/artifacts/{artifactId}")
311     @Consumes(MediaType.APPLICATION_JSON)
312     @Produces(MediaType.APPLICATION_JSON)
313     @Operation(description = "Download resource Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
314         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
315         @ApiResponse(responseCode = "200", description = "Resource artifact downloaded"),
316         @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
317     public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
318                                                    @Context final HttpServletRequest request) {
319         String url = request.getMethod() + " " + request.getRequestURI();
320         log.debug(START_HANDLE_REQUEST_OF, url);
321         Response response;
322         try {
323             response = handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null);
324         } catch (Exception e) {
325             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64");
326             log.debug("downloadResourceArtifactBase64 unexpected exception", e);
327             throw e;
328         } finally {
329             loggerSupportability
330                 .log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, null, StatusCode.COMPLETE, "Ended download artifact {}", artifactId);
331         }
332         return response;
333     }
334
335     @GET
336     @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}")
337     @Consumes(MediaType.APPLICATION_JSON)
338     @Produces(MediaType.APPLICATION_JSON)
339     @Operation(description = "Download component Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
340         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
341         @ApiResponse(responseCode = "200", description = "ResourceInstance artifact downloaded"),
342         @ApiResponse(responseCode = "404", description = "ResourceInstance/Artifact not found")})
343     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
344     public Response downloadResourceInstanceArtifactBase64(
345         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
346             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
347         @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
348         @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
349         Response response;
350         String url = request.getMethod() + " " + request.getRequestURI();
351         log.debug(START_HANDLE_REQUEST_OF, url);
352         loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.STARTED,
353             " Starting to download Resource Instance Artifact for component {} ", componentId);
354         try {
355             response = handleDownloadRequest(request, componentInstanceId, artifactId, componentId, ComponentTypeEnum.RESOURCE_INSTANCE,
356                 containerComponentType);
357         } catch (Exception e) {
358             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
359             log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
360             throw e;
361         } finally {
362             loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE,
363                 "Ended download Resource Instance Artifact for component {} ", componentId);
364         }
365         return response;
366     }
367
368     // *************** Resource lifecycle ( interfces )
369     @POST
370     @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts")
371     @Consumes(MediaType.APPLICATION_JSON)
372     @Produces(MediaType.APPLICATION_JSON)
373     @Operation(description = "Create Artifact and Attach to interface", method = "POST", summary = "Returns created resource", responses = {
374         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
375         @ApiResponse(responseCode = "201", description = "Resource created"),
376         @ApiResponse(responseCode = "403", description = "Restricted operation"),
377         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
378         @ApiResponse(responseCode = "409", description = "Artifact already exist")})
379     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
380     public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType,
381                                             @PathParam("operation") final String operation,
382                                             @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
383                                             @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
384                                             @Parameter(description = "json describe the artifact", required = true) String data,
385                                             @Context final HttpServletRequest request) {
386         String url = request.getMethod() + " " + request.getRequestURI();
387         log.debug(START_HANDLE_REQUEST_OF, url);
388         try {
389             return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, ComponentTypeEnum.RESOURCE,
390                 ArtifactOperationEnum.CREATE, null, null, false);
391         } catch (Exception e) {
392             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface");
393             log.debug("loadArtifactToInterface unexpected exception", e);
394             throw e;
395         }
396     }
397
398     @DELETE
399     @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
400     @Consumes(MediaType.APPLICATION_JSON)
401     @Produces(MediaType.APPLICATION_JSON)
402     @Operation(description = "delete Artifact from interface", method = "delete", summary = "delete matching artifact from interface", responses = {
403         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
404         @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
405         @ApiResponse(responseCode = "403", description = "Restricted operation"),
406         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
407         @ApiResponse(responseCode = "409", description = "Artifact already exist")})
408     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
409     public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId,
410                                               @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
411                                               @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
412         String url = request.getMethod() + " " + request.getRequestURI();
413         log.debug(START_HANDLE_REQUEST_OF, url);
414         try {
415             return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, operation);
416         } catch (Exception e) {
417             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface");
418             log.debug("deleteArtifactToInterface unexpected exception", e);
419             throw e;
420         }
421     }
422
423     @POST
424     @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
425     @Consumes(MediaType.APPLICATION_JSON)
426     @Produces(MediaType.APPLICATION_JSON)
427     @Operation(description = "update Artifact  Attach to interface", method = "post", summary = "updates artifact by interface", responses = {
428         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
429         @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
430         @ApiResponse(responseCode = "403", description = "Restricted operation"),
431         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
432         @ApiResponse(responseCode = "409", description = "Artifact already exist")})
433     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
434     public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId,
435                                               @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
436                                               @PathParam("artifactId") final String artifactId,
437                                               @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
438                                               @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request,
439                                               @Parameter(description = "json describe the artifact", required = true) String data) {
440         String url = request.getMethod() + " " + request.getRequestURI();
441         log.debug(START_HANDLE_REQUEST_OF, url);
442         try {
443             return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, ComponentTypeEnum.RESOURCE,
444                 ArtifactOperationEnum.UPDATE, null, null, false);
445         } catch (Exception e) {
446             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface");
447             log.debug("updateArtifactToInterface unexpected exception", e);
448             throw e;
449         }
450     }
451
452     @POST
453     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams")
454     @Consumes(MediaType.APPLICATION_JSON)
455     @Produces(MediaType.APPLICATION_JSON)
456     @Operation(description = "Update Resource Instance HEAT_ENV parameters", method = "POST", summary = "Returns updated artifact", responses = {
457         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
458         @ApiResponse(responseCode = "200", description = "Artifact updated"),
459         @ApiResponse(responseCode = "403", description = "Restricted operation"),
460         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
461     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
462     public Response updateRIArtifact(
463         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
464             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
465         @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
466         @PathParam("artifactId") final String artifactId, @Parameter(description = "json describe the artifact", required = true) String data,
467         @Context final HttpServletRequest request) {
468         String url = request.getMethod() + " " + request.getRequestURI();
469         log.debug(START_HANDLE_REQUEST_OF, url);
470         loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.STARTED, "Starting update RI Artifact {}", artifactId);
471         Response response;
472         try {
473             response = handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
474                 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, false);
475         } catch (Exception e) {
476             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact");
477             log.debug("updateRIArtifact unexpected exception", e);
478             throw e;
479         } finally {
480             loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.COMPLETE, "Ending update RI Artifact {}", artifactId);
481         }
482         return response;
483     }
484
485     @POST
486     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
487     @Consumes(MediaType.APPLICATION_JSON)
488     @Produces(MediaType.APPLICATION_JSON)
489     @Operation(description = "Update Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
490         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
491         @ApiResponse(responseCode = "200", description = "Artifact updated"),
492         @ApiResponse(responseCode = "403", description = "Restricted operation"),
493         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
494     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
495     public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
496                                                     @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
497                                                     @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
498                                                         ComponentTypeEnum.RESOURCE_PARAM_NAME,
499                                                         ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
500                                                     @PathParam("componentId") final String componentId,
501                                                     @PathParam("componentInstanceId") final String componentInstanceId,
502                                                     @PathParam("artifactId") final String artifactId,
503                                                     @Parameter(description = "json describe the artifact", required = true) String data,
504                                                     @Context final HttpServletRequest request) {
505         String url = request.getMethod() + " " + request.getRequestURI();
506         log.debug(START_HANDLE_REQUEST_OF, url);
507         try {
508             return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
509                 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, true);
510         } catch (Exception e) {
511             log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
512             throw e;
513         }
514     }
515
516     @POST
517     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts")
518     @Consumes(MediaType.APPLICATION_JSON)
519     @Produces(MediaType.APPLICATION_JSON)
520     @Operation(description = "Load Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
521         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
522         @ApiResponse(responseCode = "200", description = "Artifact updated"),
523         @ApiResponse(responseCode = "403", description = "Restricted operation"),
524         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
525     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
526     public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
527                                                   @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
528                                                   @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
529                                                       ComponentTypeEnum.RESOURCE_PARAM_NAME,
530                                                       ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
531                                                   @PathParam("componentId") final String componentId,
532                                                   @PathParam("componentInstanceId") final String componentInstanceId,
533                                                   @Parameter(description = "json describe the artifact", required = true) String data,
534                                                   @Context final HttpServletRequest request) {
535         String url = request.getMethod() + " " + request.getRequestURI();
536         log.debug(START_HANDLE_REQUEST_OF, url);
537         try {
538             return handleArtifactRequest(data, request, componentInstanceId, null, null, null, ComponentTypeEnum.RESOURCE_INSTANCE,
539                 ArtifactOperationEnum.CREATE, componentId, containerComponentType, false);
540         } catch (Exception e) {
541             log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
542             throw e;
543         }
544     }
545
546     @DELETE
547     @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
548     @Consumes(MediaType.APPLICATION_JSON)
549     @Produces(MediaType.APPLICATION_JSON)
550     @Operation(description = "Delete Resource Instance artifact", method = "POST", summary = "Returns deleted artifact", responses = {
551         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
552         @ApiResponse(responseCode = "200", description = "Artifact updated"),
553         @ApiResponse(responseCode = "403", description = "Restricted operation"),
554         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
555     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
556     public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
557                                                     @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
558                                                     @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
559                                                         ComponentTypeEnum.RESOURCE_PARAM_NAME,
560                                                         ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
561                                                     @PathParam("componentId") final String componentId,
562                                                     @PathParam("componentInstanceId") final String componentInstanceId,
563                                                     @PathParam("artifactId") final String artifactId,
564                                                     @Parameter(description = "json describe the artifact", required = true) String data,
565                                                     @Context final HttpServletRequest request) {
566         String url = request.getMethod() + " " + request.getRequestURI();
567         log.debug(START_HANDLE_REQUEST_OF, url);
568         loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.STARTED,
569             "Starting delete component instance artifact {}", artifactId);
570         Response response;
571         try {
572             response = handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, null, null, componentId);
573         } catch (Exception e) {
574             log.debug("deleteArtifact unexpected exception", e);
575             throw e;
576         } finally {
577             loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.COMPLETE,
578                 "Ending delete component instance artifact {}", artifactId);
579         }
580         return response;
581     }
582
583     @GET
584     @Path("/{containerComponentType}/{componentId}/artifactsByType/{artifactGroupType}")
585     @Consumes(MediaType.APPLICATION_JSON)
586     @Produces(MediaType.APPLICATION_JSON)
587     @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
588         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
589         @ApiResponse(responseCode = "200", description = "Component artifacts"),
590         @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
591     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
592     public Response getComponentArtifacts(
593         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
594             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
595         @PathParam("componentId") final String componentId, @PathParam("artifactGroupType") final String artifactGroupType,
596         @Context final HttpServletRequest request) {
597         String url = request.getMethod() + " " + request.getRequestURI();
598         log.debug(START_HANDLE_REQUEST_OF, url);
599         try {
600             return handleGetArtifactsRequest(request, componentId, null, artifactGroupType, containerComponentType);
601         } catch (Exception e) {
602             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
603             log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
604             throw e;
605         }
606     }
607
608     @GET
609     @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifactsByType/{artifactGroupType}")
610     @Consumes(MediaType.APPLICATION_JSON)
611     @Produces(MediaType.APPLICATION_JSON)
612     @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
613         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
614         @ApiResponse(responseCode = "200", description = "Component artifacts"),
615         @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
616     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
617     public Response getComponentInstanceArtifacts(
618         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
619             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
620         @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
621         @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) {
622         String url = request.getMethod() + " " + request.getRequestURI();
623         log.debug(START_HANDLE_REQUEST_OF, url);
624         try {
625             return handleGetArtifactsRequest(request, componentInstanceId, componentId, artifactGroupType, containerComponentType);
626         } catch (Exception e) {
627             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
628             log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
629             throw e;
630         }
631     }
632
633     @POST
634     @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}")
635     @Consumes(MediaType.APPLICATION_JSON)
636     @Produces(MediaType.APPLICATION_JSON)
637     @Operation(description = "uploads of artifact to component operation workflow", method = "POST", summary = "uploads of artifact to component operation workflow", responses = {
638         @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
639         @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
640         @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
641         @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
642         @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
643         @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
644         @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"),
645         @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")})
646     public Response uploadInterfaceOperationArtifact(@Parameter(description = "Asset type") @PathParam("assetType") String assetType,
647                                                      @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
648                                                      @Parameter(description = "The uuid of the interface", required = true) @PathParam("interfaceUUID") final String interfaceUUID,
649                                                      @Parameter(description = "The uuid of the operation", required = true) @PathParam("operationUUID") final String operationUUID,
650                                                      @Parameter(description = "The uuid of the artifact", required = true) @PathParam("artifactUUID") final String artifactUUID,
651                                                      @Parameter(hidden = true) String data,
652                                                      @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
653                                                      @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
654                                                      @Context final HttpServletRequest request) {
655         String url = request.getMethod() + " " + request.getRequestURI();
656         log.debug("Start handle request of {}", url);
657         try {
658             Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsBusinessLogic
659                 .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID,
660                     operationUUID, artifactUUID, new ResourceCommonInfo(assetType),
661                     new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
662             if (uploadArtifactEither.isRight()) {
663                 log.debug("failed to update artifact");
664                 return buildErrorResponse(uploadArtifactEither.right().value());
665             }
666             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uploadArtifactEither.left().value());
667         } catch (Exception e) {
668             final String message = "failed to update artifact on a resource or service";
669             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
670             log.debug(message, e);
671             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
672         }
673     }
674     // ////////// API END ///////////////////////////
675
676     // ************ private *********************
677     private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) {
678         return handleArtifactRequest(data, componentId, null, componentType, ArtifactOperationEnum.CREATE);
679     }
680
681     private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId,
682                                          ComponentTypeEnum componentType) {
683         return handleArtifactRequest(data, componentId, artifactId, componentType, ArtifactOperationEnum.UPDATE);
684     }
685
686     private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId,
687                                            ComponentTypeEnum componentType, String containerComponentType) {
688         String userId = request.getHeader(Constants.USER_ID_HEADER);
689         ImmutablePair<String, byte[]> actionResult = artifactsBusinessLogic
690             .handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType);
691         Response response;
692         byte[] file = actionResult.getRight();
693         String base64Contents = new String(Base64.encodeBase64(file));
694         String artifactName = actionResult.getLeft();
695         ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
696         ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData();
697         artifactUiDownloadData.setArtifactName(artifactName);
698         artifactUiDownloadData.setBase64Contents(base64Contents);
699         response = buildOkResponse(responseFormat, artifactUiDownloadData);
700         return response;
701     }
702
703     private Response handleGetArtifactsRequest(HttpServletRequest request, String componentId, String parentId, String artifactGroupType,
704                                                String containerComponentType) {
705         String userId = request.getHeader(Constants.USER_ID_HEADER);
706         ComponentTypeEnum componentTypeEnum =
707             parentId == null || parentId.isEmpty() ? ComponentTypeEnum.findByParamName(containerComponentType) : ComponentTypeEnum.RESOURCE_INSTANCE;
708         Map<String, ArtifactDefinition> actionResult = artifactsBusinessLogic
709             .handleGetArtifactsByType(containerComponentType, parentId, componentTypeEnum, componentId, artifactGroupType, userId);
710         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResult);
711     }
712
713     private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
714                                          String interfaceType, String operationName) {
715         return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null);
716     }
717
718     private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
719                                          String interfaceType, String operationName, String parentId) {
720         String userId = request.getHeader(Constants.USER_ID_HEADER);
721         Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> actionResult = artifactsBusinessLogic
722             .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DELETE),
723                 artifactId, null, null, null, interfaceType, operationName, parentId, null);
724         Response response;
725         Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = actionResult;
726         if (result.isLeft()) {
727             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
728         } else {
729             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
730         }
731         return response;
732     }
733
734     private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName,
735                                            String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operationEnum, String parentId,
736                                            String containerComponentType, boolean validateTimeout) {
737         loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.STARTED, "Starting to update artifact {} ",
738             artifactId + " for component " + componentId);
739         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, validateTimeout);
740         String origMd5 = request.getHeader(Constants.MD5_HEADER);
741         String userId = request.getHeader(Constants.USER_ID_HEADER);
742         Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = artifactsBusinessLogic
743             .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, operationEnum), artifactId,
744                 artifactInfo, origMd5, data, interfaceName, operationName, parentId, containerComponentType);
745         Response response;
746         if (result.isLeft()) {
747             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
748         } else {
749             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
750         }
751         loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.COMPLETE, "Ended update artifact {} ",
752             artifactId + " for component " + componentId);
753         return response;
754     }
755
756     private Response handleArtifactRequest(String data, String componentId, String artifactId, ComponentTypeEnum componentType,
757                                            ArtifactOperationEnum operation) {
758         return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null, false);
759     }
760 }