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