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