ed1bc3eeb88ef8dcb737f317e3fe60bf6c7b00b1
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / distribution / servlet / DistributionCatalogServlet.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.distribution.servlet;
22
23 import com.jcabi.aspects.Loggable;
24 import fj.data.Either;
25 import io.swagger.annotations.*;
26 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
27 import org.openecomp.sdc.be.config.BeEcompErrorManager;
28 import org.openecomp.sdc.be.dao.api.ActionStatus;
29 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
30 import org.openecomp.sdc.be.servlets.BeGenericServlet;
31 import org.openecomp.sdc.common.api.Constants;
32 import org.openecomp.sdc.common.log.wrappers.Logger;
33 import org.openecomp.sdc.exception.ResponseFormat;
34
35 import javax.inject.Singleton;
36 import javax.servlet.ServletContext;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.ws.rs.*;
39 import javax.ws.rs.core.Context;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.Response;
42 import java.io.ByteArrayInputStream;
43 import java.io.InputStream;
44 import java.util.HashMap;
45 import java.util.Map;
46
47 /**
48  * This Servlet serves external users to download artifacts.
49  * 
50  * @author tgitelman
51  *
52  */
53
54 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
55 @Path("/v1/catalog")
56 @Api(value = "Distribution Catalog Servlet", description = "This Servlet serves external users to download artifacts.")
57 @Singleton
58 public class DistributionCatalogServlet extends BeGenericServlet {
59
60     private static final String DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION = "download artifact failed with exception";
61         private static final String MISSING_X_ECOMP_INSTANCE_ID_HEADER = "Missing X-ECOMP-InstanceID header";
62         private static final Logger log = Logger.getLogger(DistributionCatalogServlet.class);
63     @Context
64     private HttpServletRequest request;
65
66     // *******************************************************
67     // Download (GET) artifacts
68     // **********************************************************/
69     /**
70      *
71      * @param requestId
72      * @param instanceIdHeader
73      * @param accept
74      * @param authorization
75      * @param serviceName
76      * @param serviceVersion
77      * @param artifactName
78      * @return
79      */
80     @GET
81     @Path("/services/{serviceName}/{serviceVersion}/artifacts/{artifactName}")
82     @Consumes(MediaType.APPLICATION_JSON)
83     @Produces(MediaType.APPLICATION_OCTET_STREAM)
84     @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
85     @ApiResponses(value = {
86             @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
87             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
88             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
89             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
90             @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
91             @ApiResponse(code = 404, message = "Specified Service Version is  not  found - SVC4504"),
92             @ApiResponse(code = 404, message = "Specified artifact is  not found - SVC4505"),
93             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
94             @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")})
95     public Response downloadServiceArtifact(
96             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
97             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
98             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
99             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
100             @PathParam("serviceName") final String serviceName,
101             @PathParam("serviceVersion") final String serviceVersion,
102             @PathParam("artifactName") final String artifactName) {
103
104         Response response = null;
105         String requestURI = request.getRequestURI();
106         if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
107             log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
108             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
109             getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
110             return buildErrorResponse(responseFormat);
111         }
112
113         try {
114             ServletContext context = request.getSession().getServletContext();
115             ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
116             Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsLogic.downloadServiceArtifactByNames(serviceName, serviceVersion, artifactName);
117             if (downloadRsrcArtifactEither.isRight()) {
118                 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
119                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
120                 response = buildErrorResponse(responseFormat);
121             } else {
122                 byte[] value = downloadRsrcArtifactEither.left().value();
123                 InputStream is = new ByteArrayInputStream(value);
124
125                 Map<String, String> headers = new HashMap<>();
126                 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
127                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
128                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
129                 response = buildOkResponse(responseFormat, is, headers);
130             }
131             return response;
132
133         } catch (Exception e) {
134             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download Murano package artifact for service - external API");
135             log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
136             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
137         }
138     }
139
140     /**
141      *
142      * @param requestId
143      * @param instanceIdHeader
144      * @param accept
145      * @param authorization
146      * @param serviceName
147      * @param serviceVersion
148      * @param resourceName
149      * @param resourceVersion
150      * @param artifactName
151      * @return
152      */
153     @GET
154     @Path("/services/{serviceName}/{serviceVersion}/resources/{resourceName}/{resourceVersion}/artifacts/{artifactName}")
155     @Consumes(MediaType.APPLICATION_JSON)
156     @Produces(MediaType.APPLICATION_OCTET_STREAM)
157     @ApiOperation(value = "Download resource artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
158     @ApiResponses(value = {
159             @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
160             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
161             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
162             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
163             @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
164             @ApiResponse(code = 404, message = "Specified Resource Instance  is not found - SVC4526"),
165             @ApiResponse(code = 404, message = "Specified Service Version is  not  found - SVC4504"),
166             @ApiResponse(code = 404, message = "Specified artifact is  not found - SVC4505"),
167             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
168             @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")})
169     public Response downloadResourceArtifact(
170             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
171             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
172             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
173             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
174             @PathParam("serviceName") final String serviceName,
175             @PathParam("serviceVersion") final String serviceVersion,
176             @PathParam("resourceName") final String resourceName,
177             @PathParam("resourceVersion") final String resourceVersion,
178             @PathParam("artifactName") final String artifactName) {
179
180         Response response = null;
181         String requestURI = request.getRequestURI();
182
183         if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
184             log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
185             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
186             getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
187             return buildErrorResponse(responseFormat);
188         }
189
190         try {
191             ServletContext context = request.getSession().getServletContext();
192             ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
193             Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsLogic.downloadRsrcArtifactByNames(serviceName, serviceVersion, resourceName, resourceVersion, artifactName);
194             if (downloadRsrcArtifactEither.isRight()) {
195                 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
196                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
197                 response = buildErrorResponse(responseFormat);
198             } else {
199                 byte[] value = downloadRsrcArtifactEither.left().value();
200                 // Returning 64-encoded as it was received during upload
201                 InputStream is = new ByteArrayInputStream(value);
202                 Map<String, String> headers = new HashMap<>();
203                 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
204                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
205                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
206                 response = buildOkResponse(responseFormat, is, headers);
207             }
208             return response;
209
210         } catch (Exception e) {
211             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API");
212             log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
213             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
214         }
215     }
216
217     /**
218      *
219      * @param requestId
220      * @param instanceIdHeader
221      * @param accept
222      * @param authorization
223      * @param serviceName
224      * @param serviceVersion
225      * @param resourceInstanceName
226      * @param artifactName
227      * @return
228      */
229     @GET
230     @Path("/services/{serviceName}/{serviceVersion}/resourceInstances/{resourceInstanceName}/artifacts/{artifactName}")
231     @Consumes(MediaType.APPLICATION_JSON)
232     @Produces(MediaType.APPLICATION_OCTET_STREAM)
233     @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
234     @ApiResponses(value = {
235             @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
236             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
237             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
238             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
239             @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
240             @ApiResponse(code = 404, message = "Specified Resource Instance  is not found - SVC4526"),
241             @ApiResponse(code = 404, message = "Specified Service Version is  not  found - SVC4504"),
242             @ApiResponse(code = 404, message = "Specified artifact is  not found - SVC4505"),
243             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
244             @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000")})
245     public Response downloadResourceInstanceArtifactByName(
246             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
247             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
248             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
249             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
250             @PathParam("serviceName") final String serviceName,
251             @PathParam("serviceVersion") final String serviceVersion,
252             @PathParam("resourceInstanceName") final String resourceInstanceName,
253             @PathParam("artifactName") final String artifactName) {
254
255         Response response = null;
256         String requestURI = request.getRequestURI();
257
258         if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
259             log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
260             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
261             getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
262             return buildErrorResponse(responseFormat);
263         }
264
265         try {
266             ServletContext context = request.getSession().getServletContext();
267             ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
268             Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsLogic.downloadRsrcInstArtifactByNames(serviceName, serviceVersion, resourceInstanceName, artifactName);
269             if (downloadRsrcArtifactEither.isRight()) {
270                 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
271                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
272                 response = buildErrorResponse(responseFormat);
273             } else {
274                 byte[] value = downloadRsrcArtifactEither.left().value();
275                 // Returning 64-encoded as it was received during upload
276                 InputStream is = new ByteArrayInputStream(value);
277                 Map<String, String> headers = new HashMap<>();
278                 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
279                 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
280                 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
281                 response = buildOkResponse(responseFormat, is, headers);
282             }
283             return response;
284
285         } catch (Exception e) {
286             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API");
287             log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
288             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
289         }
290     }
291 }