2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.servlets;
22 import com.jcabi.aspects.Loggable;
23 import fj.data.Either;
24 import io.swagger.v3.oas.annotations.Operation;
25 import io.swagger.v3.oas.annotations.Parameter;
26 import io.swagger.v3.oas.annotations.media.ArraySchema;
27 import io.swagger.v3.oas.annotations.media.Content;
28 import io.swagger.v3.oas.annotations.media.Schema;
29 import io.swagger.v3.oas.annotations.responses.ApiResponse;
30 import io.swagger.v3.oas.annotations.servers.Server;
31 import io.swagger.v3.oas.annotations.servers.Servers;
32 import io.swagger.v3.oas.annotations.tags.Tag;
33 import io.swagger.v3.oas.annotations.tags.Tags;
35 import javax.inject.Inject;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.ws.rs.Consumes;
38 import javax.ws.rs.DELETE;
39 import javax.ws.rs.GET;
40 import javax.ws.rs.HeaderParam;
41 import javax.ws.rs.POST;
42 import javax.ws.rs.Path;
43 import javax.ws.rs.PathParam;
44 import javax.ws.rs.Produces;
45 import javax.ws.rs.core.Context;
46 import javax.ws.rs.core.MediaType;
47 import javax.ws.rs.core.Response;
48 import org.apache.commons.codec.binary.Base64;
49 import org.apache.commons.lang3.tuple.ImmutablePair;
50 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
52 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
53 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
54 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
55 import org.openecomp.sdc.be.config.BeEcompErrorManager;
56 import org.openecomp.sdc.be.dao.api.ActionStatus;
57 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
58 import org.openecomp.sdc.be.impl.ComponentsUtils;
59 import org.openecomp.sdc.be.model.ArtifactDefinition;
60 import org.openecomp.sdc.be.model.ArtifactUiDownloadData;
61 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
62 import org.openecomp.sdc.common.api.Constants;
63 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
64 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
65 import org.openecomp.sdc.common.log.enums.StatusCode;
66 import org.openecomp.sdc.common.log.wrappers.Logger;
67 import org.openecomp.sdc.exception.ResponseFormat;
68 import org.springframework.stereotype.Controller;
71 * Root resource (exposed at "/" path)
73 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
75 @Tags({@Tag(name = "SDCE-2 APIs")})
76 @Servers({@Server(url = "/sdc2/rest")})
78 public class ArtifactServlet extends BeGenericServlet {
80 private static final Logger log = Logger.getLogger(ArtifactServlet.class);
81 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ArtifactServlet.class.getName());
82 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
83 private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64 = "downloadResourceInstanceArtifactBase64";
84 private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION = "downloadResourceInstanceArtifactBase64 unexpected exception";
85 private final ArtifactsBusinessLogic artifactsBusinessLogic;
88 public ArtifactServlet(ComponentsUtils componentsUtils, ArtifactsBusinessLogic artifactsBusinessLogic) {
89 super(componentsUtils);
90 this.artifactsBusinessLogic = artifactsBusinessLogic;
93 // *************** Resources
95 @Path("/resources/{resourceId}/artifacts")
96 @Consumes(MediaType.APPLICATION_JSON)
97 @Produces(MediaType.APPLICATION_JSON)
98 @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
99 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
100 @ApiResponse(responseCode = "201", description = "Resource created"),
101 @ApiResponse(responseCode = "403", description = "Restricted operation"),
102 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
103 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
104 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
105 public Response loadArtifact(@PathParam("resourceId") final String resourceId,
106 @Parameter(description = "json describe the artifact", required = true) String data,
107 @Context final HttpServletRequest request) {
108 String url = request.getMethod() + " " + request.getRequestURI();
109 log.debug(START_HANDLE_REQUEST_OF, url);
110 return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE);
114 @Path("/resources/{resourceId}/artifacts/{artifactId}")
115 @Consumes(MediaType.APPLICATION_JSON)
116 @Produces(MediaType.APPLICATION_JSON)
117 @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
118 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
119 @ApiResponse(responseCode = "201", description = "Resource created"),
120 @ApiResponse(responseCode = "403", description = "Restricted operation"),
121 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
122 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
123 public Response updateArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
124 @Parameter(description = "json describe the artifact", required = true) String data,
125 @Context final HttpServletRequest request) {
126 String url = request.getMethod() + " " + request.getRequestURI();
127 log.debug(START_HANDLE_REQUEST_OF, url);
129 return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE);
130 } catch (Exception e) {
131 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact");
132 log.debug("updateArtifact unexpected exception", e);
138 @Path("/resources/{resourceId}/artifacts/{artifactId}")
139 @Consumes(MediaType.APPLICATION_JSON)
140 @Produces(MediaType.APPLICATION_JSON)
141 @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
142 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
143 @ApiResponse(responseCode = "201", description = "Resource created"),
144 @ApiResponse(responseCode = "403", description = "Restricted operation"),
145 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
146 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
147 public Response deleteArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
148 @Context final HttpServletRequest request) {
149 String url = request.getMethod() + " " + request.getRequestURI();
150 log.debug(START_HANDLE_REQUEST_OF, url);
152 return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null);
153 } catch (Exception e) {
154 log.debug("deleteArtifact unexpected exception", e);
159 // *************** Services
161 @Path("/services/{serviceId}/artifacts")
162 @Consumes(MediaType.APPLICATION_JSON)
163 @Produces(MediaType.APPLICATION_JSON)
164 @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
165 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
166 @ApiResponse(responseCode = "201", description = "Resource created"),
167 @ApiResponse(responseCode = "403", description = "Restricted operation"),
168 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
169 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
170 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
171 public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId,
172 @Parameter(description = "json describe the artifact", required = true) String data,
173 @Context final HttpServletRequest request) {
174 String url = request.getMethod() + " " + request.getRequestURI();
175 log.debug(START_HANDLE_REQUEST_OF, url);
177 return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE);
178 } catch (Exception e) {
179 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact");
180 log.debug("loadInformationArtifact unexpected exception", e);
186 @Path("/services/{serviceId}/artifacts/{artifactId}")
187 @Consumes(MediaType.APPLICATION_JSON)
188 @Produces(MediaType.APPLICATION_JSON)
189 @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
190 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
191 @ApiResponse(responseCode = "201", description = "Service artifact created"),
192 @ApiResponse(responseCode = "403", description = "Restricted operation"),
193 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
194 public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
195 @Parameter(description = "json describe the artifact", required = true) String data,
196 @Context final HttpServletRequest request) {
197 String url = request.getMethod() + " " + request.getRequestURI();
198 log.debug(START_HANDLE_REQUEST_OF, url);
200 return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
201 } catch (Exception e) {
202 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact");
203 log.debug("updateInformationArtifact unexpected exception", e);
208 // *************** Services api artifacts
210 @Path("/services/{serviceId}/artifacts/api/{artifactId}")
211 @Consumes(MediaType.APPLICATION_JSON)
212 @Produces(MediaType.APPLICATION_JSON)
213 @Operation(description = "Update Api Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
214 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
215 @ApiResponse(responseCode = "200", description = "Api Artifact Updated"),
216 @ApiResponse(responseCode = "403", description = "Restricted operation"),
217 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
218 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
219 public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
220 @Parameter(description = "json describe the artifact", required = true) String data,
221 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
222 @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
223 String url = request.getMethod() + " " + request.getRequestURI();
224 log.debug(START_HANDLE_REQUEST_OF, url);
226 return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
227 } catch (Exception e) {
228 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact");
229 log.debug("updateApiArtifact unexpected exception", e);
235 @Path("/services/{serviceId}/artifacts/api/{artifactId}")
236 @Consumes(MediaType.APPLICATION_JSON)
237 @Produces(MediaType.APPLICATION_JSON)
238 @Operation(description = "Delete Api Artifact", method = "DELETE", summary = "Returns Deleted ArtifactDefinition", responses = {
239 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
240 @ApiResponse(responseCode = "204", description = "Api Artifact deleted"),
241 @ApiResponse(responseCode = "403", description = "Restricted operation")})
242 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
243 public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
244 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
245 @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
246 String url = request.getMethod() + " " + request.getRequestURI();
247 log.debug(START_HANDLE_REQUEST_OF, url);
249 return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
250 } catch (Exception e) {
251 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact");
252 log.debug("deleteApiArtifact unexpected exception", e);
258 @Path("/services/{serviceId}/artifacts/{artifactId}")
259 @Consumes(MediaType.APPLICATION_JSON)
260 @Produces(MediaType.APPLICATION_JSON)
261 @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
262 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
263 @ApiResponse(responseCode = "201", description = "Service artifact deleted"),
264 @ApiResponse(responseCode = "403", description = "Restricted operation"),
265 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
266 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
267 public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
268 @Context final HttpServletRequest request) {
269 String url = request.getMethod() + " " + request.getRequestURI();
270 log.debug(START_HANDLE_REQUEST_OF, url);
272 return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
273 } catch (Exception e) {
274 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact");
275 log.debug("deleteInformationalArtifact unexpected exception", e);
281 * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href)
284 @Path("/services/{serviceId}/artifacts/{artifactId}")
285 @Consumes(MediaType.APPLICATION_JSON)
286 @Produces(MediaType.APPLICATION_JSON)
287 @Operation(description = "Download service Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
288 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
289 @ApiResponse(responseCode = "200", description = "Service artifact downloaded"),
290 @ApiResponse(responseCode = "404", description = "Service/Artifact not found")})
291 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
292 public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
293 @Context final HttpServletRequest request) {
294 String url = request.getMethod() + " " + request.getRequestURI();
296 log.debug(START_HANDLE_REQUEST_OF, url);
298 response = handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null);
299 } catch (Exception e) {
300 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64");
301 log.debug("downloadServiceArtifactBase64 unexpected exception", e);
304 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE, "Ended download Service Artifact ");
310 @Path("/resources/{resourceId}/artifacts/{artifactId}")
311 @Consumes(MediaType.APPLICATION_JSON)
312 @Produces(MediaType.APPLICATION_JSON)
313 @Operation(description = "Download resource Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
314 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
315 @ApiResponse(responseCode = "200", description = "Resource artifact downloaded"),
316 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
317 public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
318 @Context final HttpServletRequest request) {
319 String url = request.getMethod() + " " + request.getRequestURI();
320 log.debug(START_HANDLE_REQUEST_OF, url);
323 response = handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null);
324 } catch (Exception e) {
325 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64");
326 log.debug("downloadResourceArtifactBase64 unexpected exception", e);
330 .log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, null, StatusCode.COMPLETE, "Ended download artifact {}", artifactId);
336 @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}")
337 @Consumes(MediaType.APPLICATION_JSON)
338 @Produces(MediaType.APPLICATION_JSON)
339 @Operation(description = "Download component Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
340 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
341 @ApiResponse(responseCode = "200", description = "ResourceInstance artifact downloaded"),
342 @ApiResponse(responseCode = "404", description = "ResourceInstance/Artifact not found")})
343 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
344 public Response downloadResourceInstanceArtifactBase64(
345 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
346 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
347 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
348 @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
350 String url = request.getMethod() + " " + request.getRequestURI();
351 log.debug(START_HANDLE_REQUEST_OF, url);
352 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.STARTED,
353 " Starting to download Resource Instance Artifact for component {} ", componentId);
355 response = handleDownloadRequest(request, componentInstanceId, artifactId, componentId, ComponentTypeEnum.RESOURCE_INSTANCE,
356 containerComponentType);
357 } catch (Exception e) {
358 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
359 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
362 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE,
363 "Ended download Resource Instance Artifact for component {} ", componentId);
368 // *************** Resource lifecycle ( interfces )
370 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts")
371 @Consumes(MediaType.APPLICATION_JSON)
372 @Produces(MediaType.APPLICATION_JSON)
373 @Operation(description = "Create Artifact and Attach to interface", method = "POST", summary = "Returns created resource", responses = {
374 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
375 @ApiResponse(responseCode = "201", description = "Resource created"),
376 @ApiResponse(responseCode = "403", description = "Restricted operation"),
377 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
378 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
379 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
380 public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType,
381 @PathParam("operation") final String operation,
382 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
383 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
384 @Parameter(description = "json describe the artifact", required = true) String data,
385 @Context final HttpServletRequest request) {
386 String url = request.getMethod() + " " + request.getRequestURI();
387 log.debug(START_HANDLE_REQUEST_OF, url);
389 return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, ComponentTypeEnum.RESOURCE,
390 ArtifactOperationEnum.CREATE, null, null, false);
391 } catch (Exception e) {
392 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface");
393 log.debug("loadArtifactToInterface unexpected exception", e);
399 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
400 @Consumes(MediaType.APPLICATION_JSON)
401 @Produces(MediaType.APPLICATION_JSON)
402 @Operation(description = "delete Artifact from interface", method = "delete", summary = "delete matching artifact from interface", responses = {
403 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
404 @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
405 @ApiResponse(responseCode = "403", description = "Restricted operation"),
406 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
407 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
408 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
409 public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId,
410 @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
411 @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
412 String url = request.getMethod() + " " + request.getRequestURI();
413 log.debug(START_HANDLE_REQUEST_OF, url);
415 return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, operation);
416 } catch (Exception e) {
417 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface");
418 log.debug("deleteArtifactToInterface unexpected exception", e);
424 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
425 @Consumes(MediaType.APPLICATION_JSON)
426 @Produces(MediaType.APPLICATION_JSON)
427 @Operation(description = "update Artifact Attach to interface", method = "post", summary = "updates artifact by interface", responses = {
428 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
429 @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
430 @ApiResponse(responseCode = "403", description = "Restricted operation"),
431 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
432 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
433 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
434 public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId,
435 @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
436 @PathParam("artifactId") final String artifactId,
437 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
438 @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request,
439 @Parameter(description = "json describe the artifact", required = true) String data) {
440 String url = request.getMethod() + " " + request.getRequestURI();
441 log.debug(START_HANDLE_REQUEST_OF, url);
443 return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, ComponentTypeEnum.RESOURCE,
444 ArtifactOperationEnum.UPDATE, null, null, false);
445 } catch (Exception e) {
446 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface");
447 log.debug("updateArtifactToInterface unexpected exception", e);
453 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams")
454 @Consumes(MediaType.APPLICATION_JSON)
455 @Produces(MediaType.APPLICATION_JSON)
456 @Operation(description = "Update Resource Instance HEAT_ENV parameters", method = "POST", summary = "Returns updated artifact", responses = {
457 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
458 @ApiResponse(responseCode = "200", description = "Artifact updated"),
459 @ApiResponse(responseCode = "403", description = "Restricted operation"),
460 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
461 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
462 public Response updateRIArtifact(
463 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
464 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
465 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
466 @PathParam("artifactId") final String artifactId, @Parameter(description = "json describe the artifact", required = true) String data,
467 @Context final HttpServletRequest request) {
468 String url = request.getMethod() + " " + request.getRequestURI();
469 log.debug(START_HANDLE_REQUEST_OF, url);
470 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.STARTED, "Starting update RI Artifact {}", artifactId);
473 response = handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
474 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, false);
475 } catch (Exception e) {
476 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact");
477 log.debug("updateRIArtifact unexpected exception", e);
480 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.COMPLETE, "Ending update RI Artifact {}", artifactId);
486 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
487 @Consumes(MediaType.APPLICATION_JSON)
488 @Produces(MediaType.APPLICATION_JSON)
489 @Operation(description = "Update Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
490 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
491 @ApiResponse(responseCode = "200", description = "Artifact updated"),
492 @ApiResponse(responseCode = "403", description = "Restricted operation"),
493 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
494 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
495 public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
496 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
497 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
498 ComponentTypeEnum.RESOURCE_PARAM_NAME,
499 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
500 @PathParam("componentId") final String componentId,
501 @PathParam("componentInstanceId") final String componentInstanceId,
502 @PathParam("artifactId") final String artifactId,
503 @Parameter(description = "json describe the artifact", required = true) String data,
504 @Context final HttpServletRequest request) {
505 String url = request.getMethod() + " " + request.getRequestURI();
506 log.debug(START_HANDLE_REQUEST_OF, url);
508 return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
509 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, true);
510 } catch (Exception e) {
511 log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
517 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts")
518 @Consumes(MediaType.APPLICATION_JSON)
519 @Produces(MediaType.APPLICATION_JSON)
520 @Operation(description = "Load Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
521 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
522 @ApiResponse(responseCode = "200", description = "Artifact updated"),
523 @ApiResponse(responseCode = "403", description = "Restricted operation"),
524 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
525 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
526 public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
527 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
528 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
529 ComponentTypeEnum.RESOURCE_PARAM_NAME,
530 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
531 @PathParam("componentId") final String componentId,
532 @PathParam("componentInstanceId") final String componentInstanceId,
533 @Parameter(description = "json describe the artifact", required = true) String data,
534 @Context final HttpServletRequest request) {
535 String url = request.getMethod() + " " + request.getRequestURI();
536 log.debug(START_HANDLE_REQUEST_OF, url);
538 return handleArtifactRequest(data, request, componentInstanceId, null, null, null, ComponentTypeEnum.RESOURCE_INSTANCE,
539 ArtifactOperationEnum.CREATE, componentId, containerComponentType, false);
540 } catch (Exception e) {
541 log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
547 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
548 @Consumes(MediaType.APPLICATION_JSON)
549 @Produces(MediaType.APPLICATION_JSON)
550 @Operation(description = "Delete Resource Instance artifact", method = "POST", summary = "Returns deleted artifact", responses = {
551 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
552 @ApiResponse(responseCode = "200", description = "Artifact updated"),
553 @ApiResponse(responseCode = "403", description = "Restricted operation"),
554 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
555 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
556 public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
557 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
558 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
559 ComponentTypeEnum.RESOURCE_PARAM_NAME,
560 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
561 @PathParam("componentId") final String componentId,
562 @PathParam("componentInstanceId") final String componentInstanceId,
563 @PathParam("artifactId") final String artifactId,
564 @Parameter(description = "json describe the artifact", required = true) String data,
565 @Context final HttpServletRequest request) {
566 String url = request.getMethod() + " " + request.getRequestURI();
567 log.debug(START_HANDLE_REQUEST_OF, url);
568 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.STARTED,
569 "Starting delete component instance artifact {}", artifactId);
572 response = handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, null, null, componentId);
573 } catch (Exception e) {
574 log.debug("deleteArtifact unexpected exception", e);
577 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.COMPLETE,
578 "Ending delete component instance artifact {}", artifactId);
584 @Path("/{containerComponentType}/{componentId}/artifactsByType/{artifactGroupType}")
585 @Consumes(MediaType.APPLICATION_JSON)
586 @Produces(MediaType.APPLICATION_JSON)
587 @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
588 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
589 @ApiResponse(responseCode = "200", description = "Component artifacts"),
590 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
591 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
592 public Response getComponentArtifacts(
593 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
594 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
595 @PathParam("componentId") final String componentId, @PathParam("artifactGroupType") final String artifactGroupType,
596 @Context final HttpServletRequest request) {
597 String url = request.getMethod() + " " + request.getRequestURI();
598 log.debug(START_HANDLE_REQUEST_OF, url);
600 return handleGetArtifactsRequest(request, componentId, null, artifactGroupType, containerComponentType);
601 } catch (Exception e) {
602 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
603 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
609 @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifactsByType/{artifactGroupType}")
610 @Consumes(MediaType.APPLICATION_JSON)
611 @Produces(MediaType.APPLICATION_JSON)
612 @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
613 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
614 @ApiResponse(responseCode = "200", description = "Component artifacts"),
615 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
616 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
617 public Response getComponentInstanceArtifacts(
618 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
619 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
620 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
621 @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) {
622 String url = request.getMethod() + " " + request.getRequestURI();
623 log.debug(START_HANDLE_REQUEST_OF, url);
625 return handleGetArtifactsRequest(request, componentInstanceId, componentId, artifactGroupType, containerComponentType);
626 } catch (Exception e) {
627 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
628 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
634 @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}")
635 @Consumes(MediaType.APPLICATION_JSON)
636 @Produces(MediaType.APPLICATION_JSON)
637 @Operation(description = "uploads of artifact to component operation workflow", method = "POST", summary = "uploads of artifact to component operation workflow", responses = {
638 @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
639 @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
640 @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
641 @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
642 @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
643 @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
644 @ApiResponse(responseCode = "400", description = "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"),
645 @ApiResponse(responseCode = "400", description = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")})
646 public Response uploadInterfaceOperationArtifact(@Parameter(description = "Asset type") @PathParam("assetType") String assetType,
647 @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
648 @Parameter(description = "The uuid of the interface", required = true) @PathParam("interfaceUUID") final String interfaceUUID,
649 @Parameter(description = "The uuid of the operation", required = true) @PathParam("operationUUID") final String operationUUID,
650 @Parameter(description = "The uuid of the artifact", required = true) @PathParam("artifactUUID") final String artifactUUID,
651 @Parameter(hidden = true) String data,
652 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
653 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
654 @Context final HttpServletRequest request) {
655 String url = request.getMethod() + " " + request.getRequestURI();
656 log.debug("Start handle request of {}", url);
658 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsBusinessLogic
659 .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID,
660 operationUUID, artifactUUID, new ResourceCommonInfo(assetType),
661 new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
662 if (uploadArtifactEither.isRight()) {
663 log.debug("failed to update artifact");
664 return buildErrorResponse(uploadArtifactEither.right().value());
666 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uploadArtifactEither.left().value());
667 } catch (Exception e) {
668 final String message = "failed to update artifact on a resource or service";
669 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
670 log.debug(message, e);
671 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
674 // ////////// API END ///////////////////////////
676 // ************ private *********************
677 private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) {
678 return handleArtifactRequest(data, componentId, null, componentType, ArtifactOperationEnum.CREATE);
681 private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId,
682 ComponentTypeEnum componentType) {
683 return handleArtifactRequest(data, componentId, artifactId, componentType, ArtifactOperationEnum.UPDATE);
686 private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId,
687 ComponentTypeEnum componentType, String containerComponentType) {
688 String userId = request.getHeader(Constants.USER_ID_HEADER);
689 ImmutablePair<String, byte[]> actionResult = artifactsBusinessLogic
690 .handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType);
692 byte[] file = actionResult.getRight();
693 String base64Contents = new String(Base64.encodeBase64(file));
694 String artifactName = actionResult.getLeft();
695 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
696 ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData();
697 artifactUiDownloadData.setArtifactName(artifactName);
698 artifactUiDownloadData.setBase64Contents(base64Contents);
699 response = buildOkResponse(responseFormat, artifactUiDownloadData);
703 private Response handleGetArtifactsRequest(HttpServletRequest request, String componentId, String parentId, String artifactGroupType,
704 String containerComponentType) {
705 String userId = request.getHeader(Constants.USER_ID_HEADER);
706 ComponentTypeEnum componentTypeEnum =
707 parentId == null || parentId.isEmpty() ? ComponentTypeEnum.findByParamName(containerComponentType) : ComponentTypeEnum.RESOURCE_INSTANCE;
708 Map<String, ArtifactDefinition> actionResult = artifactsBusinessLogic
709 .handleGetArtifactsByType(containerComponentType, parentId, componentTypeEnum, componentId, artifactGroupType, userId);
710 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResult);
713 private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
714 String interfaceType, String operationName) {
715 return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null);
718 private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
719 String interfaceType, String operationName, String parentId) {
720 String userId = request.getHeader(Constants.USER_ID_HEADER);
721 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> actionResult = artifactsBusinessLogic
722 .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DELETE),
723 artifactId, null, null, null, interfaceType, operationName, parentId, null);
725 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = actionResult;
726 if (result.isLeft()) {
727 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
729 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
734 private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName,
735 String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operationEnum, String parentId,
736 String containerComponentType, boolean validateTimeout) {
737 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.STARTED, "Starting to update artifact {} ",
738 artifactId + " for component " + componentId);
739 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, validateTimeout);
740 String origMd5 = request.getHeader(Constants.MD5_HEADER);
741 String userId = request.getHeader(Constants.USER_ID_HEADER);
742 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = artifactsBusinessLogic
743 .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, operationEnum), artifactId,
744 artifactInfo, origMd5, data, interfaceName, operationName, parentId, containerComponentType);
746 if (result.isLeft()) {
747 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
749 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
751 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.COMPLETE, "Ended update artifact {} ",
752 artifactId + " for component " + componentId);
756 private Response handleArtifactRequest(String data, String componentId, String artifactId, ComponentTypeEnum componentType,
757 ArtifactOperationEnum operation) {
758 return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null, false);