2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.distribution.servlet;
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.components.impl.ComponentInstanceBusinessLogic;
28 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
29 import org.openecomp.sdc.be.config.BeEcompErrorManager;
30 import org.openecomp.sdc.be.dao.api.ActionStatus;
31 import org.openecomp.sdc.be.impl.ComponentsUtils;
32 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
33 import org.openecomp.sdc.be.servlets.BeGenericServlet;
34 import org.openecomp.sdc.be.user.UserBusinessLogic;
35 import org.openecomp.sdc.common.api.Constants;
36 import org.openecomp.sdc.common.log.wrappers.Logger;
37 import org.openecomp.sdc.exception.ResponseFormat;
39 import javax.inject.Singleton;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
43 import javax.ws.rs.core.Context;
44 import javax.ws.rs.core.MediaType;
45 import javax.ws.rs.core.Response;
46 import java.io.ByteArrayInputStream;
47 import java.io.InputStream;
48 import java.util.HashMap;
50 import org.springframework.beans.factory.annotation.Autowired;
53 * This Servlet serves external users to download artifacts.
59 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
61 @Api(value = "Distribution Catalog Servlet", description = "This Servlet serves external users to download artifacts.")
63 public class DistributionCatalogServlet extends BeGenericServlet {
65 private static final String DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION = "download artifact failed with exception";
66 private static final String MISSING_X_ECOMP_INSTANCE_ID_HEADER = "Missing X-ECOMP-InstanceID header";
67 private static final Logger log = Logger.getLogger(DistributionCatalogServlet.class);
68 private final ArtifactsBusinessLogic artifactsBusinessLogic;
71 public DistributionCatalogServlet(UserBusinessLogic userBusinessLogic,
72 ComponentsUtils componentsUtils,
73 ArtifactsBusinessLogic artifactsBusinessLogic) {
74 super(userBusinessLogic, componentsUtils);
75 this.artifactsBusinessLogic = artifactsBusinessLogic;
79 private HttpServletRequest request;
81 // *******************************************************
82 // Download (GET) artifacts
83 // **********************************************************/
87 * @param instanceIdHeader
89 * @param authorization
91 * @param serviceVersion
96 @Path("/services/{serviceName}/{serviceVersion}/artifacts/{artifactName}")
97 @Consumes(MediaType.APPLICATION_JSON)
98 @Produces(MediaType.APPLICATION_OCTET_STREAM)
99 @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
100 @ApiResponses(value = {
101 @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
102 @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"),
103 @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
104 @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
105 @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
106 @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"),
107 @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"),
108 @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
109 @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")})
110 public Response downloadServiceArtifact(
111 @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
112 @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
113 @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
114 @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
115 @PathParam("serviceName") final String serviceName,
116 @PathParam("serviceVersion") final String serviceVersion,
117 @PathParam("artifactName") final String artifactName) {
119 Response response = null;
120 String requestURI = request.getRequestURI();
121 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
122 log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
123 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
124 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
125 return buildErrorResponse(responseFormat);
129 Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsBusinessLogic
130 .downloadServiceArtifactByNames(serviceName, serviceVersion, artifactName);
131 if (downloadRsrcArtifactEither.isRight()) {
132 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
133 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
134 response = buildErrorResponse(responseFormat);
136 byte[] value = downloadRsrcArtifactEither.left().value();
137 InputStream is = new ByteArrayInputStream(value);
139 Map<String, String> headers = new HashMap<>();
140 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
141 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
142 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
143 response = buildOkResponse(responseFormat, is, headers);
147 } catch (Exception e) {
148 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download Murano package artifact for service - external API");
149 log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
150 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
157 * @param instanceIdHeader
159 * @param authorization
161 * @param serviceVersion
162 * @param resourceName
163 * @param resourceVersion
164 * @param artifactName
168 @Path("/services/{serviceName}/{serviceVersion}/resources/{resourceName}/{resourceVersion}/artifacts/{artifactName}")
169 @Consumes(MediaType.APPLICATION_JSON)
170 @Produces(MediaType.APPLICATION_OCTET_STREAM)
171 @ApiOperation(value = "Download resource artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
172 @ApiResponses(value = {
173 @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
174 @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"),
175 @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
176 @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
177 @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
178 @ApiResponse(code = 404, message = "Specified Resource Instance is not found - SVC4526"),
179 @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"),
180 @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"),
181 @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
182 @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")})
183 public Response downloadResourceArtifact(
184 @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
185 @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
186 @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
187 @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
188 @PathParam("serviceName") final String serviceName,
189 @PathParam("serviceVersion") final String serviceVersion,
190 @PathParam("resourceName") final String resourceName,
191 @PathParam("resourceVersion") final String resourceVersion,
192 @PathParam("artifactName") final String artifactName) {
194 Response response = null;
195 String requestURI = request.getRequestURI();
197 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
198 log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
199 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
200 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
201 return buildErrorResponse(responseFormat);
205 Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsBusinessLogic
206 .downloadRsrcArtifactByNames(serviceName, serviceVersion, resourceName, resourceVersion, artifactName);
207 if (downloadRsrcArtifactEither.isRight()) {
208 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
209 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
210 response = buildErrorResponse(responseFormat);
212 byte[] value = downloadRsrcArtifactEither.left().value();
213 // Returning 64-encoded as it was received during upload
214 InputStream is = new ByteArrayInputStream(value);
215 Map<String, String> headers = new HashMap<>();
216 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
217 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
218 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
219 response = buildOkResponse(responseFormat, is, headers);
223 } catch (Exception e) {
224 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API");
225 log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
226 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
233 * @param instanceIdHeader
235 * @param authorization
237 * @param serviceVersion
238 * @param resourceInstanceName
239 * @param artifactName
243 @Path("/services/{serviceName}/{serviceVersion}/resourceInstances/{resourceInstanceName}/artifacts/{artifactName}")
244 @Consumes(MediaType.APPLICATION_JSON)
245 @Produces(MediaType.APPLICATION_OCTET_STREAM)
246 @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = String.class)
247 @ApiResponses(value = {
248 @ApiResponse(code = 200, message = "The artifact is found and streamed.", response = String.class),
249 @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"),
250 @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
251 @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
252 @ApiResponse(code = 404, message = "Specified Service is not found - SVC4503"),
253 @ApiResponse(code = 404, message = "Specified Resource Instance is not found - SVC4526"),
254 @ApiResponse(code = 404, message = "Specified Service Version is not found - SVC4504"),
255 @ApiResponse(code = 404, message = "Specified artifact is not found - SVC4505"),
256 @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
257 @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")})
258 public Response downloadResourceInstanceArtifactByName(
259 @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
260 @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
261 @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
262 @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
263 @PathParam("serviceName") final String serviceName,
264 @PathParam("serviceVersion") final String serviceVersion,
265 @PathParam("resourceInstanceName") final String resourceInstanceName,
266 @PathParam("artifactName") final String artifactName) {
268 Response response = null;
269 String requestURI = request.getRequestURI();
271 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
272 log.debug(MISSING_X_ECOMP_INSTANCE_ID_HEADER);
273 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
274 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
275 return buildErrorResponse(responseFormat);
279 Either<byte[], ResponseFormat> downloadRsrcArtifactEither = artifactsBusinessLogic
280 .downloadRsrcInstArtifactByNames(serviceName, serviceVersion, resourceInstanceName, artifactName);
281 if (downloadRsrcArtifactEither.isRight()) {
282 ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value();
283 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
284 response = buildErrorResponse(responseFormat);
286 byte[] value = downloadRsrcArtifactEither.left().value();
287 // Returning 64-encoded as it was received during upload
288 InputStream is = new ByteArrayInputStream(value);
289 Map<String, String> headers = new HashMap<>();
290 headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName));
291 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
292 getComponentsUtils().auditDistributionDownload(responseFormat, new DistributionData(instanceIdHeader, requestURI));
293 response = buildOkResponse(responseFormat, is, headers);
297 } catch (Exception e) {
298 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API");
299 log.debug(DOWNLOAD_ARTIFACT_FAILED_WITH_EXCEPTION, e);
300 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));