Revert "Delete workflow artifact
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / externalapi / servlet / ArtifactExternalServlet.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.externalapi.servlet;
22
23 import com.jcabi.aspects.Loggable;
24 import fj.data.Either;
25 import io.swagger.annotations.Api;
26 import io.swagger.annotations.ApiImplicitParam;
27 import io.swagger.annotations.ApiImplicitParams;
28 import io.swagger.annotations.ApiOperation;
29 import io.swagger.annotations.ApiParam;
30 import io.swagger.annotations.ApiResponse;
31 import io.swagger.annotations.ApiResponses;
32 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
33 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
34 import org.openecomp.sdc.be.config.BeEcompErrorManager;
35 import org.openecomp.sdc.be.dao.api.ActionStatus;
36 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
37 import org.openecomp.sdc.be.model.ArtifactDefinition;
38 import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
39 import org.openecomp.sdc.be.servlets.RepresentationUtils;
40 import org.openecomp.sdc.common.api.Constants;
41 import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum;
42 import org.openecomp.sdc.common.datastructure.Wrapper;
43 import org.openecomp.sdc.common.util.GeneralUtility;
44 import org.openecomp.sdc.exception.ResponseFormat;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import javax.inject.Singleton;
49 import javax.servlet.ServletContext;
50 import javax.servlet.http.HttpServletRequest;
51 import javax.ws.rs.DELETE;
52 import javax.ws.rs.GET;
53 import javax.ws.rs.HeaderParam;
54 import javax.ws.rs.POST;
55 import javax.ws.rs.Path;
56 import javax.ws.rs.PathParam;
57 import javax.ws.rs.Produces;
58 import javax.ws.rs.core.Context;
59 import javax.ws.rs.core.MediaType;
60 import javax.ws.rs.core.Response;
61 import java.io.ByteArrayInputStream;
62 import java.io.InputStream;
63 import java.util.EnumMap;
64 import java.util.HashMap;
65 import java.util.Map;
66 /**
67  * This Servlet serves external users operations on artifacts.
68  * 
69  * @author mshitrit
70  *
71  */
72 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
73 @Path("/v1/catalog")
74 @Api(value = "Artifact External Servlet", description = "Servlet serves external users operations on artifacts.")
75 @Singleton
76 public class ArtifactExternalServlet extends AbstractValidationsServlet {
77
78     @Context
79     private HttpServletRequest request;
80
81     private static final Logger log = LoggerFactory.getLogger(ArtifactExternalServlet.class);
82
83     private static String startLog = "Start handle request of ";
84
85     /**
86      * Uploads an artifact to resource or service
87      *
88      * @param contenType
89      * @param checksum
90      * @param userId
91      * @param requestId
92      * @param instanceIdHeader
93      * @param accept
94      * @param authorization
95      * @param assetType
96      * @param uuid
97      * @param data
98      * @return
99      */
100     @POST
101     @Path("/{assetType}/{uuid}/artifacts")
102     @Produces(MediaType.APPLICATION_JSON)
103     @ApiOperation(value = "uploads of artifact to a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service")
104     @ApiResponses(value = {
105             @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class),
106             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
107             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
108             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
109             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
110             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
111             @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"),
112             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
113             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
114             @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"),
115             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
116             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
117             @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"),
118             @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")})
119     @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")})
120     public Response uploadArtifact(
121             @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType,
122             @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum,
123             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
124             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
125             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
126             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
127             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
128             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
129             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
130             String data) {
131
132         init(log);
133
134         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
135         String requestURI = request.getRequestURI();
136         String url = request.getMethod() + " " + requestURI;
137         log.debug("{} {}", startLog, url);
138         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
139         String componentTypeValue = componentType == null ? null : componentType.getValue();
140         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
141
142         if (componentType == null) {
143             log.debug("uploadArtifact: assetType parameter {} is not valid", assetType);
144             responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
145         }
146         if (responseWrapper.isEmpty()) {
147             validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
148         }
149         if (responseWrapper.isEmpty() ) {
150             validateHttpCspUserIdHeader(userId, responseWrapper);
151         }
152         Response response = null;
153         try {
154             if (responseWrapper.isEmpty()) {
155                 ServletContext context = request.getSession().getServletContext();
156                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
157                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.uploadArtifactToComponentByUUID(data, request, componentType, uuid,
158                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE));
159                 if (uploadArtifactEither.isRight()) {
160                     log.debug("failed to upload artifact");
161                     responseWrapper.setInnerElement(uploadArtifactEither.right().value());
162                 } else {
163                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
164                     Map<String, String> headers = new HashMap<>();
165                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
166                     responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.OK));
167                     response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers);
168                 }
169             }
170             if( response == null ){
171                 response = buildErrorResponse(responseWrapper.getInnerElement());
172             }
173             return response;
174         } catch (Exception e) {
175             final String message = "failed to upload artifact to a resource or service";
176             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
177             log.debug(message, e);
178             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
179         } finally {
180             getComponentsUtils().auditExternalUploadArtifact(responseWrapper.getInnerElement(), componentTypeValue, request, additionalParams);
181         }
182     }
183
184     /**
185      * Uploads an artifact to resource instance
186      *
187      * @param assetType
188      * @param uuid
189      * @param resourceInstanceName
190      * @return
191      */
192     @POST
193     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts")
194     @Produces(MediaType.APPLICATION_JSON)
195     @ApiOperation(value = "uploads an artifact to a resource instance", httpMethod = "POST", notes = "uploads an artifact to a resource instance")
196     @ApiResponses(value = {
197             @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class),
198             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
199             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
200             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
201             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
202             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
203             @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"),
204             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
205             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
206             @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"),
207             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
208             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
209             @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"),
210             @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")})
211     @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")})
212     public Response uploadArtifactToInstance(
213             @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType,
214             @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum,
215             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
216             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
217             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
218             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
219             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
220             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
221             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
222             @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName,
223             String data) {
224
225         Wrapper<Response> responseWrapper = new Wrapper<>();
226         ResponseFormat responseFormat = null;
227         String requestURI = request.getRequestURI();
228         String url = request.getMethod() + " " + requestURI;
229         log.debug("{} {}", startLog, url);
230         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
231         String componentTypeValue = componentType == null ? null : componentType.getValue();
232         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
233         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName);
234         if (componentType == null) {
235             log.debug("uploadArtifact: assetType parameter {} is not valid", assetType);
236             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
237             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
238         }
239         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
240             log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header");
241             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
242             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
243         }
244         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
245             log.debug("uploadArtifact: Missing USER_ID header");
246             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
247             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
248         }
249         try {
250             if (responseWrapper.isEmpty()) {
251                 ServletContext context = request.getSession().getServletContext();
252                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
253                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.uploadArtifactToRiByUUID(data, request, componentType, uuid, resourceInstanceName,
254                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.CREATE));
255                 if (uploadArtifactEither.isRight()) {
256                     log.debug("failed to upload artifact");
257                     responseFormat = uploadArtifactEither.right().value();
258                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
259                 } else {
260                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
261                     Map<String, String> headers = new HashMap<>();
262                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
263                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
264                     responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
265                 }
266             }
267         }catch (Exception e) {
268             final String message = "failed to upload artifact to a resource instance";
269             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
270             log.debug(message, e);
271             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
272         } finally {
273             getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentTypeValue, request, additionalParams);
274         }
275         return responseWrapper.getInnerElement();
276     }
277
278     /**
279      *
280      * @param contenType
281      * @param checksum
282      * @param userId
283      * @param requestId
284      * @param instanceIdHeader
285      * @param accept
286      * @param authorization
287      * @param assetType
288      * @param uuid
289      * @param artifactUUID
290      * @param data
291      * @return
292      */
293     @POST
294     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
295     @Produces(MediaType.APPLICATION_JSON)
296     @ApiOperation(value = "updates an artifact on a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service")
297     @ApiResponses(value = {
298             @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class),
299             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
300             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
301             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
302             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
303             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
304             @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"),
305             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
306             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
307             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
308             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
309             @ApiResponse(code = 403, 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"),
310             @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
311     @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")})
312     public Response updateArtifact(
313             @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType,
314             @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum,
315             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
316             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
317             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
318             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
319             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
320             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
321             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
322             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID,
323             String data) {
324
325         Wrapper<Response> responseWrapper = new Wrapper<>();
326         ResponseFormat responseFormat = null;
327         String requestURI = request.getRequestURI();
328         String url = request.getMethod() + " " + requestURI;
329         log.debug("{} {}", startLog, url);
330         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
331         String componentTypeValue = componentType == null ? null : componentType.getValue();
332         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
333         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
334         if (componentType == null) {
335             log.debug("updateArtifact: assetType parameter {} is not valid", assetType);
336             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
337             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
338         }
339         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
340             log.debug("updateArtifact: Missing X-ECOMP-InstanceID header");
341             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
342             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
343         }
344         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
345             log.debug("updateArtifact: Missing USER_ID");
346             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
347             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
348         }
349         try {
350             if (responseWrapper.isEmpty()) {
351                 ServletContext context = request.getSession().getServletContext();
352                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
353                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.updateArtifactOnComponentByUUID(data, request, componentType, uuid, artifactUUID,
354                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
355                 if (uploadArtifactEither.isRight()) {
356                     log.debug("failed to update artifact");
357                     responseFormat = uploadArtifactEither.right().value();
358                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
359                 } else {
360                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
361                     Map<String, String> headers = new HashMap<>();
362                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
363                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
364                     responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
365                 }
366             }
367         } catch (Exception e) {
368             final String message = "failed to update artifact on a resource or service";
369             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
370             log.debug(message, e);
371             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
372         } finally {
373             getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentTypeValue, request, additionalParams);
374         }
375         return responseWrapper.getInnerElement();
376     }
377
378     /**
379      * updates an artifact on a resource instance
380      *
381      * @param assetType
382      * @param uuid
383      * @param resourceInstanceName
384      * @param artifactUUID
385      * @return
386      */
387     @POST
388     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
389     @Produces(MediaType.APPLICATION_JSON)
390     @ApiOperation(value = "updates an artifact on a resource instance", httpMethod = "POST", notes = "uploads of artifact to a resource or service")
391     @ApiResponses(value = {
392             @ApiResponse(code = 200, message = "Artifact updated", response = ArtifactDefinition.class),
393             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
394             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
395             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
396             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
397             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
398             @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"),
399             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
400             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
401             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
402             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
403             @ApiResponse(code = 403, 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"),
404             @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
405     @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")})
406     public Response updateArtifactOnResourceInstance(
407             @ApiParam(value = "Determines the format of the body of the request", required = true)@HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contenType,
408             @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true)@HeaderParam(value = Constants.MD5_HEADER) String checksum,
409             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
410             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
411             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
412             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
413             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
414             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
415             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
416             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID,
417             @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName,
418             String data) {
419
420         Wrapper<Response> responseWrapper = new Wrapper<>();
421         ResponseFormat responseFormat = null;
422         String requestURI = request.getRequestURI();
423         String url = request.getMethod() + " " + requestURI;
424         log.debug("{} {}", startLog, url);
425         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
426         String componentTypeValue = componentType == null ? null : componentType.getValue();
427         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
428         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName);
429         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
430         if (componentType == null) {
431             log.debug("updateArtifactOnResourceInstance: assetType parameter {} is not valid", assetType);
432             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
433             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
434         }
435         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
436             log.debug("updateArtifactOnResourceInstance: Missing X-ECOMP-InstanceID header");
437             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
438             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
439         }
440         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
441             log.debug("updateArtifactOnResourceInstance: Missing USER_ID header");
442             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
443             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
444         }
445         try {
446             if (responseWrapper.isEmpty()) {
447                 ServletContext context = request.getSession().getServletContext();
448                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
449                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.updateArtifactOnRiByUUID(data, request, componentType, uuid, resourceInstanceName, artifactUUID,
450                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
451                 if (uploadArtifactEither.isRight()) {
452                     log.debug("failed to update artifact");
453                     responseFormat = uploadArtifactEither.right().value();
454                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
455                 } else {
456                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
457                     Map<String, String> headers = new HashMap<>();
458                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
459                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
460                     responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
461                 }
462             }
463         } catch (Exception e) {
464             final String message = "failed to update artifact on resource instance";
465             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
466             log.debug(message, e);
467             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
468         } finally {
469             getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentTypeValue, request, additionalParams);
470         }
471         return responseWrapper.getInnerElement();
472     }
473
474     /**
475      * deletes an artifact of a resource or service
476      *
477      * @param assetType
478      * @param uuid
479      * @param artifactUUID
480      * @return
481      */
482     @DELETE
483     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
484     @Produces(MediaType.APPLICATION_JSON)
485     @ApiOperation(value = "deletes an artifact of a resource or service", httpMethod = "DELETE", notes = "deletes an artifact of a resource or service", response = Response.class)
486     /*@ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"),
487             @ApiResponse(code = 404, message = "Asset not found") })*/
488     @ApiResponses(value = {
489             @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class),
490             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
491             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
492             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
493             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
494             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
495             @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"),
496             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
497             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
498             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
499             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
500             @ApiResponse(code = 403, 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"),
501             @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
502     public Response deleteArtifact(
503             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
504             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
505             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
506             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
507             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
508             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
509             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
510             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) {
511
512         Wrapper<Response> responseWrapper = new Wrapper<>();
513         ResponseFormat responseFormat = null;
514         String requestURI = request.getRequestURI();
515         String url = request.getMethod() + " " + requestURI;
516         log.debug("{} {}", startLog, url);
517         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
518         String componentTypeValue = componentType == null ? null : componentType.getValue();
519         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
520         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
521         if (componentType == null) {
522             log.debug("deleteArtifact: assetType parameter {} is not valid", assetType);
523             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
524             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
525         }
526         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
527             log.debug("deleteArtifact: Missing X-ECOMP-InstanceID header");
528             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
529             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
530         }
531         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
532             log.debug("deleteArtifact: Missing USER_ID header");
533             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
534             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
535         }
536         try {
537             if (responseWrapper.isEmpty()) {
538                 ServletContext context = request.getSession().getServletContext();
539                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
540                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.deleteArtifactOnComponentByUUID(request, componentType, uuid, artifactUUID,
541                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE));
542                 if (uploadArtifactEither.isRight()) {
543                     log.debug("failed to delete artifact");
544                     responseFormat = uploadArtifactEither.right().value();
545                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
546                 } else {
547                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
548                     Map<String, String> headers = new HashMap<>();
549                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
550                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
551                     responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
552                 }
553             }
554         } catch (Exception e) {
555             final String message = "failed to delete an artifact of a resource or service";
556             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
557             log.debug(message, e);
558             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
559         } finally {
560             getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentTypeValue, request, additionalParams);
561         }
562         return responseWrapper.getInnerElement();
563     }
564
565     /**
566      * deletes an artifact of a resource instance
567      *
568      * @param assetType
569      * @param uuid
570      * @param resourceInstanceName
571      * @return
572      */
573     @DELETE
574     @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
575     @Produces(MediaType.APPLICATION_JSON)
576     @ApiOperation(value = "deletes an artifact of a resource insatnce", httpMethod = "DELETE", notes = "deletes an artifact of a resource insatnce", response = Response.class)
577     @ApiResponses(value = {
578             @ApiResponse(code = 200, message = "Artifact deleted", response = ArtifactDefinition.class),
579             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
580             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
581             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
582             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
583             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
584             @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"),
585             @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"),
586             @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"),
587             @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"),
588             @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"),
589             @ApiResponse(code = 403, 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"),
590             @ApiResponse(code = 409, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
591     public Response deleteArtifactOnResourceInstance(
592             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
593             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
594             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
595             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
596             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
597             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
598             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
599             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID,
600             @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) {
601
602         Wrapper<Response> responseWrapper = new Wrapper<>();
603         ResponseFormat responseFormat = null;
604         String requestURI = request.getRequestURI();
605         String url = request.getMethod() + " " + requestURI;
606         log.debug("{} {}", startLog, url);
607         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
608         String componentTypeValue = componentType == null ? null : componentType.getValue();
609         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
610         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName);
611         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
612         if (componentType == null) {
613             log.debug("deleteArtifactOnResourceInsatnce: assetType parameter {} is not valid", assetType);
614             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
615             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
616         }
617         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
618             log.debug("deleteArtifactOnResourceInsatnce: Missing X-ECOMP-InstanceID header");
619             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
620             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
621         }
622         if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) {
623             log.debug("deleteArtifactOnResourceInsatnce: Missing USER_ID header");
624             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID);
625             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
626         }
627         try {
628             if (responseWrapper.isEmpty()) {
629                 ServletContext context = request.getSession().getServletContext();
630                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
631                 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.deleteArtifactOnRiByUUID(request, componentType, uuid, resourceInstanceName, artifactUUID,
632                         additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.DELETE));
633                 if (uploadArtifactEither.isRight()) {
634                     log.debug("failed to delete artifact");
635                     responseFormat = uploadArtifactEither.right().value();
636                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
637                 } else {
638                     Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value());
639                     Map<String, String> headers = new HashMap<>();
640                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation));
641                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
642                     responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers));
643                 }
644             }
645         } catch (Exception e) {
646             final String message = "failed to delete an artifact of a resource instance";
647             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
648             log.debug(message, e);
649             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
650         } finally {
651             getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentTypeValue, request, additionalParams);
652         }
653         return responseWrapper.getInnerElement();
654     }
655
656     /**
657      * downloads an artifact of a component (either a service or a resource) by artifactUUID
658      *
659      * @param assetType
660      * @param uuid
661      * @param artifactUUID
662      * @return
663      */
664     @GET
665     @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}")
666     @Produces(MediaType.APPLICATION_OCTET_STREAM)
667     @ApiOperation(value = "Download component artifact", httpMethod = "GET", notes = "Returns downloaded artifact")
668     @ApiResponses(value = {
669             @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class),
670             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
671             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
672             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
673             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
674             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
675             @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"),
676             @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")})
677     public Response downloadComponentArtifact(
678             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
679             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
680             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
681             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
682             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
683             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
684             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
685             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID) {
686
687         Wrapper<Response> responseWrapper = new Wrapper<>();
688         ResponseFormat responseFormat = null;
689         String requestURI = request.getRequestURI();
690         String url = request.getMethod() + " " + requestURI;
691         log.debug("{} {}", startLog, url);
692         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
693         String componentTypeValue = componentType == null ? null : componentType.getValue();
694         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
695         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
696         if (componentType == null) {
697             log.debug("downloadComponentArtifact: assetType parameter {} is not valid", assetType);
698             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
699             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
700         }
701         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
702             log.debug("downloadComponentArtifact: Missing X-ECOMP-InstanceID header");
703             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
704             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
705         }
706         try {
707             if (responseWrapper.isEmpty()) {
708                 ServletContext context = request.getSession().getServletContext();
709                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
710                 Either<byte[], ResponseFormat> downloadComponentArtifactEither = artifactsLogic.downloadComponentArtifactByUUIDs(componentType, uuid, artifactUUID, additionalParams);
711                 if (downloadComponentArtifactEither.isRight()) {
712                     responseFormat = downloadComponentArtifactEither.right().value();
713                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
714                 } else {
715                     byte[] value = downloadComponentArtifactEither.left().value();
716                     InputStream is = new ByteArrayInputStream(value);
717                     Map<String, String> headers = new HashMap<>();
718                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value));
719                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
720                     responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers));
721                 }
722             }
723         } catch (Exception e) {
724             final String message = "failed to download an artifact of a resource or service";
725             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
726             log.debug(message, e);
727             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
728         } finally {
729             getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentTypeValue, request, additionalParams);
730         }
731         return responseWrapper.getInnerElement();
732     }
733
734     /**
735      * downloads an artifact of a resource instance of a component (either a service or a resource) by artifactUUID
736      *
737      * @param assetType
738      * @param uuid
739      * @param resourceInstanceName
740      * @param artifactUUID
741      * @return
742      */
743     @GET
744     @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}")
745     @Produces(MediaType.APPLICATION_OCTET_STREAM)
746     @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class)
747     @ApiResponses(value = {
748             @ApiResponse(code = 200, message = "Artifact downloaded", response = String.class),
749             @ApiResponse(code = 400, message = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
750             @ApiResponse(code = 401, message = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic  Authentication credentials - POL5002"),
751             @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"),
752             @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"),
753             @ApiResponse(code = 405, message = "Method  Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"),
754             @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"),
755             @ApiResponse(code = 404, message = "Artifact was not found - SVC4505")})
756     public Response downloadResourceInstanceArtifact(
757             @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true)@HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
758             @ApiParam(value = "X-ECOMP-RequestID header", required = false)@HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
759             @ApiParam(value = "X-ECOMP-InstanceID header", required = true)@HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
760             @ApiParam(value = "Determines the format of the body of the response", required = false)@HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
761             @ApiParam(value = "The username and password", required = true)@HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
762             @ApiParam(value = "The requested asset type", required = true, allowableValues = "resources, services")@PathParam("assetType") final String assetType,
763             @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid,
764             @ApiParam(value = "The uuid of the artifact as published in the asset detailed metadata or in the response of the upload / update operation", required = true)@PathParam("artifactUUID") final String artifactUUID,
765             @ApiParam(value = "The component instance name (as publishedin the response of the detailed query)", required = true)@PathParam("resourceInstanceName") final String resourceInstanceName) {
766
767         Wrapper<Response> responseWrapper = new Wrapper<>();
768         ResponseFormat responseFormat = null;
769         String requestURI = request.getRequestURI();
770         String url = request.getMethod() + " " + requestURI;
771         log.debug("{} {}", startLog, url);
772         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
773         String componentTypeValue = componentType == null ? null : componentType.getValue();
774         EnumMap<AuditingFieldsKeysEnum, Object> additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class);
775         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName);
776         additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID);
777         if (componentType == null) {
778             log.debug("downloadResourceInstanceArtifact: assetType parameter {} is not valid", assetType);
779             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
780             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
781         }
782         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
783             log.debug("downloadResourceInstanceArtifact: Missing X-ECOMP-InstanceID header");
784             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
785             responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
786         }
787         try {
788             if (responseWrapper.isEmpty()) {
789                 ServletContext context = request.getSession().getServletContext();
790                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
791                 Either<byte[], ResponseFormat> downloadResourceArtifactEither = artifactsLogic.downloadResourceInstanceArtifactByUUIDs(componentType, uuid, resourceInstanceName, artifactUUID, additionalParams);
792                 if (downloadResourceArtifactEither.isRight()) {
793                     responseFormat = downloadResourceArtifactEither.right().value();
794                     responseWrapper.setInnerElement(buildErrorResponse(responseFormat));
795                 } else {
796                     byte[] value = downloadResourceArtifactEither.left().value();
797                     InputStream is = new ByteArrayInputStream(value);
798                     Map<String, String> headers = new HashMap<>();
799                     headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByByteArray(value));
800                     responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
801                     responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers));
802                 }
803             }
804         } catch (Exception e) {
805             final String message = "failed to download an artifact of a resource instance";
806             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
807             log.debug(message, e);
808             responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
809         } finally {
810             getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentTypeValue, request, additionalParams);
811         }
812         return responseWrapper.getInnerElement();
813     }
814 }