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