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