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