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