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.artifact.ArtifactOperationInfo;
53 import org.openecomp.sdc.be.config.BeEcompErrorManager;
54 import org.openecomp.sdc.be.dao.api.ActionStatus;
55 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
56 import org.openecomp.sdc.be.impl.ComponentsUtils;
57 import org.openecomp.sdc.be.model.ArtifactDefinition;
58 import org.openecomp.sdc.be.model.ArtifactUiDownloadData;
59 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
60 import org.openecomp.sdc.common.api.Constants;
61 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
62 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
63 import org.openecomp.sdc.common.log.enums.StatusCode;
64 import org.openecomp.sdc.common.log.wrappers.Logger;
65 import org.openecomp.sdc.exception.ResponseFormat;
66 import org.springframework.stereotype.Controller;
69 * Root resource (exposed at "/" path)
71 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
73 @Tags({@Tag(name = "SDCE-2 APIs")})
74 @Servers({@Server(url = "/sdc2/rest")})
76 public class ArtifactServlet extends BeGenericServlet {
78 private static final Logger log = Logger.getLogger(ArtifactServlet.class);
79 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ArtifactServlet.class.getName());
80 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
81 private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64 = "downloadResourceInstanceArtifactBase64";
82 private static final String DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION = "downloadResourceInstanceArtifactBase64 unexpected exception";
83 private final ArtifactsBusinessLogic artifactsBusinessLogic;
86 public ArtifactServlet(ComponentsUtils componentsUtils, ArtifactsBusinessLogic artifactsBusinessLogic) {
87 super(componentsUtils);
88 this.artifactsBusinessLogic = artifactsBusinessLogic;
91 // *************** Resources
93 @Path("/resources/{resourceId}/artifacts")
94 @Consumes(MediaType.APPLICATION_JSON)
95 @Produces(MediaType.APPLICATION_JSON)
96 @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
97 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
98 @ApiResponse(responseCode = "201", description = "Resource created"),
99 @ApiResponse(responseCode = "403", description = "Restricted operation"),
100 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
101 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
102 public Response loadArtifact(@PathParam("resourceId") final String resourceId,
103 @Parameter(description = "json describe the artifact", required = true) String data,
104 @Context final HttpServletRequest request) {
105 String url = request.getMethod() + " " + request.getRequestURI();
106 log.debug(START_HANDLE_REQUEST_OF, url);
107 return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE);
111 @Path("/resources/{resourceId}/artifacts/{artifactId}")
112 @Consumes(MediaType.APPLICATION_JSON)
113 @Produces(MediaType.APPLICATION_JSON)
114 @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
115 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
116 @ApiResponse(responseCode = "201", description = "Resource created"),
117 @ApiResponse(responseCode = "403", description = "Restricted operation"),
118 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
119 public Response updateArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
120 @Parameter(description = "json describe the artifact", required = true) String data,
121 @Context final HttpServletRequest request) {
122 String url = request.getMethod() + " " + request.getRequestURI();
123 log.debug(START_HANDLE_REQUEST_OF, url);
125 return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE);
126 } catch (Exception e) {
127 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact");
128 log.debug("updateArtifact unexpected exception", e);
134 @Path("/resources/{resourceId}/artifacts/{artifactId}")
135 @Consumes(MediaType.APPLICATION_JSON)
136 @Produces(MediaType.APPLICATION_JSON)
137 @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
138 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
139 @ApiResponse(responseCode = "201", description = "Resource created"),
140 @ApiResponse(responseCode = "403", description = "Restricted operation"),
141 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
142 public Response deleteArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
143 @Context final HttpServletRequest request) {
144 String url = request.getMethod() + " " + request.getRequestURI();
145 log.debug(START_HANDLE_REQUEST_OF, url);
147 return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null);
148 } catch (Exception e) {
149 log.debug("deleteArtifact unexpected exception", e);
154 // *************** Services
156 @Path("/services/{serviceId}/artifacts")
157 @Consumes(MediaType.APPLICATION_JSON)
158 @Produces(MediaType.APPLICATION_JSON)
159 @Operation(description = "Create Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
160 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
161 @ApiResponse(responseCode = "201", description = "Resource created"),
162 @ApiResponse(responseCode = "403", description = "Restricted operation"),
163 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
164 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
165 public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId,
166 @Parameter(description = "json describe the artifact", required = true) String data,
167 @Context final HttpServletRequest request) {
168 String url = request.getMethod() + " " + request.getRequestURI();
169 log.debug(START_HANDLE_REQUEST_OF, url);
171 return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE);
172 } catch (Exception e) {
173 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact");
174 log.debug("loadInformationArtifact unexpected exception", e);
180 @Path("/services/{serviceId}/artifacts/{artifactId}")
181 @Consumes(MediaType.APPLICATION_JSON)
182 @Produces(MediaType.APPLICATION_JSON)
183 @Operation(description = "Update Artifact", method = "POST", summary = "Returns updated artifact", responses = {
184 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
185 @ApiResponse(responseCode = "201", description = "Service artifact created"),
186 @ApiResponse(responseCode = "403", description = "Restricted operation"),
187 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
188 public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
189 @Parameter(description = "json describe the artifact", required = true) String data,
190 @Context final HttpServletRequest request) {
191 String url = request.getMethod() + " " + request.getRequestURI();
192 log.debug(START_HANDLE_REQUEST_OF, url);
194 return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
195 } catch (Exception e) {
196 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact");
197 log.debug("updateInformationArtifact unexpected exception", e);
202 // *************** Services api artifacts
204 @Path("/services/{serviceId}/artifacts/api/{artifactId}")
205 @Consumes(MediaType.APPLICATION_JSON)
206 @Produces(MediaType.APPLICATION_JSON)
207 @Operation(description = "Update Api Artifact", method = "POST", summary = "Returns created ArtifactDefinition", responses = {
208 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
209 @ApiResponse(responseCode = "200", description = "Api Artifact Updated"),
210 @ApiResponse(responseCode = "403", description = "Restricted operation"),
211 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
212 public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
213 @Parameter(description = "json describe the artifact", required = true) String data,
214 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
215 @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
216 String url = request.getMethod() + " " + request.getRequestURI();
217 log.debug(START_HANDLE_REQUEST_OF, url);
219 return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE);
220 } catch (Exception e) {
221 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact");
222 log.debug("updateApiArtifact unexpected exception", e);
228 @Path("/services/{serviceId}/artifacts/api/{artifactId}")
229 @Consumes(MediaType.APPLICATION_JSON)
230 @Produces(MediaType.APPLICATION_JSON)
231 @Operation(description = "Delete Api Artifact", method = "DELETE", summary = "Returns Deleted ArtifactDefinition", responses = {
232 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
233 @ApiResponse(responseCode = "204", description = "Api Artifact deleted"),
234 @ApiResponse(responseCode = "403", description = "Restricted operation")})
235 public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
236 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
237 @HeaderParam(value = Constants.MD5_HEADER) String origMd5) {
238 String url = request.getMethod() + " " + request.getRequestURI();
239 log.debug(START_HANDLE_REQUEST_OF, url);
241 return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
242 } catch (Exception e) {
243 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact");
244 log.debug("deleteApiArtifact unexpected exception", e);
250 @Path("/services/{serviceId}/artifacts/{artifactId}")
251 @Consumes(MediaType.APPLICATION_JSON)
252 @Produces(MediaType.APPLICATION_JSON)
253 @Operation(description = "Delete Artifact", method = "DELETE", summary = "Returns delete artifact", responses = {
254 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
255 @ApiResponse(responseCode = "201", description = "Service artifact deleted"),
256 @ApiResponse(responseCode = "403", description = "Restricted operation"),
257 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
258 public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
259 @Context final HttpServletRequest request) {
260 String url = request.getMethod() + " " + request.getRequestURI();
261 log.debug(START_HANDLE_REQUEST_OF, url);
263 return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null);
264 } catch (Exception e) {
265 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact");
266 log.debug("deleteInformationalArtifact unexpected exception", e);
272 * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href)
275 @Path("/services/{serviceId}/artifacts/{artifactId}")
276 @Consumes(MediaType.APPLICATION_JSON)
277 @Produces(MediaType.APPLICATION_JSON)
278 @Operation(description = "Download service Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
279 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
280 @ApiResponse(responseCode = "200", description = "Service artifact downloaded"),
281 @ApiResponse(responseCode = "404", description = "Service/Artifact not found")})
282 public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId,
283 @Context final HttpServletRequest request) {
284 String url = request.getMethod() + " " + request.getRequestURI();
286 log.debug(START_HANDLE_REQUEST_OF, url);
288 response = handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null);
289 } catch (Exception e) {
290 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64");
291 log.debug("downloadServiceArtifactBase64 unexpected exception", e);
294 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE, "Ended download Service Artifact ");
300 @Path("/resources/{resourceId}/artifacts/{artifactId}")
301 @Consumes(MediaType.APPLICATION_JSON)
302 @Produces(MediaType.APPLICATION_JSON)
303 @Operation(description = "Download resource Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
304 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
305 @ApiResponse(responseCode = "200", description = "Resource artifact downloaded"),
306 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
307 public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId,
308 @Context final HttpServletRequest request) {
309 String url = request.getMethod() + " " + request.getRequestURI();
310 log.debug(START_HANDLE_REQUEST_OF, url);
313 response = handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null);
314 } catch (Exception e) {
315 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64");
316 log.debug("downloadResourceArtifactBase64 unexpected exception", e);
320 .log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, null, StatusCode.COMPLETE, "Ended download artifact {}", artifactId);
326 @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}")
327 @Consumes(MediaType.APPLICATION_JSON)
328 @Produces(MediaType.APPLICATION_JSON)
329 @Operation(description = "Download component Artifact in Base64", method = "GET", summary = "Returns downloaded artifact", responses = {
330 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
331 @ApiResponse(responseCode = "200", description = "ResourceInstance artifact downloaded"),
332 @ApiResponse(responseCode = "404", description = "ResourceInstance/Artifact not found")})
333 public Response downloadResourceInstanceArtifactBase64(
334 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
335 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
336 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
337 @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
339 String url = request.getMethod() + " " + request.getRequestURI();
340 log.debug(START_HANDLE_REQUEST_OF, url);
341 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.STARTED,
342 " Starting to download Resource Instance Artifact for component {} ", componentId);
344 response = handleDownloadRequest(request, componentInstanceId, artifactId, componentId, ComponentTypeEnum.RESOURCE_INSTANCE,
345 containerComponentType);
346 } catch (Exception e) {
347 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
348 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
351 loggerSupportability.log(LoggerSupportabilityActions.DOWNLOAD_ARTIFACTS, StatusCode.COMPLETE,
352 "Ended download Resource Instance Artifact for component {} ", componentId);
357 // *************** Resource lifecycle ( interfces )
359 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts")
360 @Consumes(MediaType.APPLICATION_JSON)
361 @Produces(MediaType.APPLICATION_JSON)
362 @Operation(description = "Create Artifact and Attach to interface", method = "POST", summary = "Returns created resource", responses = {
363 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
364 @ApiResponse(responseCode = "201", description = "Resource created"),
365 @ApiResponse(responseCode = "403", description = "Restricted operation"),
366 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
367 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
368 public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType,
369 @PathParam("operation") final String operation,
370 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
371 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
372 @Parameter(description = "json describe the artifact", required = true) String data,
373 @Context final HttpServletRequest request) {
374 String url = request.getMethod() + " " + request.getRequestURI();
375 log.debug(START_HANDLE_REQUEST_OF, url);
377 return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, ComponentTypeEnum.RESOURCE,
378 ArtifactOperationEnum.CREATE, null, null, false);
379 } catch (Exception e) {
380 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface");
381 log.debug("loadArtifactToInterface unexpected exception", e);
387 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
388 @Consumes(MediaType.APPLICATION_JSON)
389 @Produces(MediaType.APPLICATION_JSON)
390 @Operation(description = "delete Artifact from interface", method = "delete", summary = "delete matching artifact from interface", responses = {
391 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
392 @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
393 @ApiResponse(responseCode = "403", description = "Restricted operation"),
394 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
395 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
396 public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId,
397 @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
398 @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) {
399 String url = request.getMethod() + " " + request.getRequestURI();
400 log.debug(START_HANDLE_REQUEST_OF, url);
402 return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, operation);
403 } catch (Exception e) {
404 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface");
405 log.debug("deleteArtifactToInterface unexpected exception", e);
411 @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}")
412 @Consumes(MediaType.APPLICATION_JSON)
413 @Produces(MediaType.APPLICATION_JSON)
414 @Operation(description = "update Artifact Attach to interface", method = "post", summary = "updates artifact by interface", responses = {
415 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
416 @ApiResponse(responseCode = "201", description = "delete artifact under interface deleted"),
417 @ApiResponse(responseCode = "403", description = "Restricted operation"),
418 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
419 @ApiResponse(responseCode = "409", description = "Artifact already exist")})
420 public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId,
421 @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation,
422 @PathParam("artifactId") final String artifactId,
423 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
424 @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request,
425 @Parameter(description = "json describe the artifact", required = true) String data) {
426 String url = request.getMethod() + " " + request.getRequestURI();
427 log.debug(START_HANDLE_REQUEST_OF, url);
429 return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, ComponentTypeEnum.RESOURCE,
430 ArtifactOperationEnum.UPDATE, null, null, false);
431 } catch (Exception e) {
432 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface");
433 log.debug("updateArtifactToInterface unexpected exception", e);
439 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams")
440 @Consumes(MediaType.APPLICATION_JSON)
441 @Produces(MediaType.APPLICATION_JSON)
442 @Operation(description = "Update Resource Instance HEAT_ENV parameters", method = "POST", summary = "Returns updated artifact", responses = {
443 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
444 @ApiResponse(responseCode = "200", description = "Artifact updated"),
445 @ApiResponse(responseCode = "403", description = "Restricted operation"),
446 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
447 public Response updateRIArtifact(
448 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
449 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
450 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
451 @PathParam("artifactId") final String artifactId, @Parameter(description = "json describe the artifact", required = true) String data,
452 @Context final HttpServletRequest request) {
453 String url = request.getMethod() + " " + request.getRequestURI();
454 log.debug(START_HANDLE_REQUEST_OF, url);
455 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.STARTED, "Starting update RI Artifact {}", artifactId);
458 response = handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
459 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, false);
460 } catch (Exception e) {
461 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact");
462 log.debug("updateRIArtifact unexpected exception", e);
465 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_HEAT, StatusCode.COMPLETE, "Ending update RI Artifact {}", artifactId);
471 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
472 @Consumes(MediaType.APPLICATION_JSON)
473 @Produces(MediaType.APPLICATION_JSON)
474 @Operation(description = "Update Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
475 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
476 @ApiResponse(responseCode = "200", description = "Artifact updated"),
477 @ApiResponse(responseCode = "403", description = "Restricted operation"),
478 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
479 public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
480 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
481 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
482 ComponentTypeEnum.RESOURCE_PARAM_NAME,
483 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
484 @PathParam("componentId") final String componentId,
485 @PathParam("componentInstanceId") final String componentInstanceId,
486 @PathParam("artifactId") final String artifactId,
487 @Parameter(description = "json describe the artifact", required = true) String data,
488 @Context final HttpServletRequest request) {
489 String url = request.getMethod() + " " + request.getRequestURI();
490 log.debug(START_HANDLE_REQUEST_OF, url);
492 return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE,
493 ArtifactOperationEnum.UPDATE, componentId, containerComponentType, true);
494 } catch (Exception e) {
495 log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
501 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts")
502 @Consumes(MediaType.APPLICATION_JSON)
503 @Produces(MediaType.APPLICATION_JSON)
504 @Operation(description = "Load Resource Instance artifact payload", method = "POST", summary = "Returns updated artifact", responses = {
505 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
506 @ApiResponse(responseCode = "200", description = "Artifact updated"),
507 @ApiResponse(responseCode = "403", description = "Restricted operation"),
508 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
509 public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
510 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
511 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
512 ComponentTypeEnum.RESOURCE_PARAM_NAME,
513 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
514 @PathParam("componentId") final String componentId,
515 @PathParam("componentInstanceId") final String componentInstanceId,
516 @Parameter(description = "json describe the artifact", required = true) String data,
517 @Context final HttpServletRequest request) {
518 String url = request.getMethod() + " " + request.getRequestURI();
519 log.debug(START_HANDLE_REQUEST_OF, url);
521 return handleArtifactRequest(data, request, componentInstanceId, null, null, null, ComponentTypeEnum.RESOURCE_INSTANCE,
522 ArtifactOperationEnum.CREATE, componentId, containerComponentType, false);
523 } catch (Exception e) {
524 log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e);
530 @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}")
531 @Consumes(MediaType.APPLICATION_JSON)
532 @Produces(MediaType.APPLICATION_JSON)
533 @Operation(description = "Delete Resource Instance artifact", method = "POST", summary = "Returns deleted artifact", responses = {
534 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
535 @ApiResponse(responseCode = "200", description = "Artifact updated"),
536 @ApiResponse(responseCode = "403", description = "Restricted operation"),
537 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
538 public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId,
539 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
540 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {
541 ComponentTypeEnum.RESOURCE_PARAM_NAME,
542 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
543 @PathParam("componentId") final String componentId,
544 @PathParam("componentInstanceId") final String componentInstanceId,
545 @PathParam("artifactId") final String artifactId,
546 @Parameter(description = "json describe the artifact", required = true) String data,
547 @Context final HttpServletRequest request) {
548 String url = request.getMethod() + " " + request.getRequestURI();
549 log.debug(START_HANDLE_REQUEST_OF, url);
550 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.STARTED,
551 "Starting delete component instance artifact {}", artifactId);
554 response = handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, null, null, componentId);
555 } catch (Exception e) {
556 log.debug("deleteArtifact unexpected exception", e);
559 loggerSupportability.log(LoggerSupportabilityActions.DELETE_COMPONENT_INSTANCE_ARTIFACT, null, StatusCode.COMPLETE,
560 "Ending delete component instance artifact {}", artifactId);
566 @Path("/{containerComponentType}/{componentId}/artifactsByType/{artifactGroupType}")
567 @Consumes(MediaType.APPLICATION_JSON)
568 @Produces(MediaType.APPLICATION_JSON)
569 @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
570 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
571 @ApiResponse(responseCode = "200", description = "Component artifacts"),
572 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
573 public Response getComponentArtifacts(
574 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
575 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
576 @PathParam("componentId") final String componentId, @PathParam("artifactGroupType") final String artifactGroupType,
577 @Context final HttpServletRequest request) {
578 String url = request.getMethod() + " " + request.getRequestURI();
579 log.debug(START_HANDLE_REQUEST_OF, url);
581 return handleGetArtifactsRequest(request, componentId, null, artifactGroupType, containerComponentType);
582 } catch (Exception e) {
583 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
584 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
590 @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifactsByType/{artifactGroupType}")
591 @Consumes(MediaType.APPLICATION_JSON)
592 @Produces(MediaType.APPLICATION_JSON)
593 @Operation(description = "Get component Artifacts", method = "GET", summary = "Returns artifacts", responses = {
594 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
595 @ApiResponse(responseCode = "200", description = "Component artifacts"),
596 @ApiResponse(responseCode = "404", description = "Resource/Artifact not found")})
597 public Response getComponentInstanceArtifacts(
598 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
599 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("containerComponentType") final String containerComponentType,
600 @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId,
601 @PathParam("artifactGroupType") final String artifactGroupType, @Context final HttpServletRequest request) {
602 String url = request.getMethod() + " " + request.getRequestURI();
603 log.debug(START_HANDLE_REQUEST_OF, url);
605 return handleGetArtifactsRequest(request, componentInstanceId, componentId, artifactGroupType, containerComponentType);
606 } catch (Exception e) {
607 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64);
608 log.debug(DOWNLOAD_RESOURCE_INSTANCE_ARTIFACT_BASE64_EXCEPTION, e);
614 @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}")
615 @Consumes(MediaType.APPLICATION_JSON)
616 @Produces(MediaType.APPLICATION_JSON)
617 @Operation(description = "uploads of artifact to component operation workflow", method = "POST", summary = "uploads of artifact to component operation workflow", responses = {
618 @ApiResponse(responseCode = "200", description = "Artifact uploaded", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ArtifactDefinition.class)))),
619 @ApiResponse(responseCode = "404", description = "Specified resource is not found - SVC4063"),
620 @ApiResponse(responseCode = "400", description = "Invalid artifactType was defined as input - SVC4122"),
621 @ApiResponse(responseCode = "400", description = "Artifact type (mandatory field) is missing in request - SVC4124"),
622 @ApiResponse(responseCode = "400", description = "Artifact name given in input already exists in the context of the asset - SVC4125"),
623 @ApiResponse(responseCode = "400", description = "Artifact name is missing in input - SVC4128"),
624 @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"),
625 @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")})
626 public Response uploadInterfaceOperationArtifact(@Parameter(description = "Asset type") @PathParam("assetType") String assetType,
627 @Parameter(description = "The uuid of the asset as published in the metadata", required = true) @PathParam("uuid") final String uuid,
628 @Parameter(description = "The uuid of the interface", required = true) @PathParam("interfaceUUID") final String interfaceUUID,
629 @Parameter(description = "The uuid of the operation", required = true) @PathParam("operationUUID") final String operationUUID,
630 @Parameter(description = "The uuid of the artifact", required = true) @PathParam("artifactUUID") final String artifactUUID,
631 @Parameter(hidden = true) String data,
632 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
633 @HeaderParam(value = Constants.MD5_HEADER) String origMd5,
634 @Context final HttpServletRequest request) {
635 String url = request.getMethod() + " " + request.getRequestURI();
636 log.debug("Start handle request of {}", url);
638 Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsBusinessLogic
639 .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum.findByParamName(assetType), uuid, interfaceUUID,
640 operationUUID, artifactUUID, new ResourceCommonInfo(assetType),
641 new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
642 if (uploadArtifactEither.isRight()) {
643 log.debug("failed to update artifact");
644 return buildErrorResponse(uploadArtifactEither.right().value());
646 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), uploadArtifactEither.left().value());
647 } catch (Exception e) {
648 final String message = "failed to update artifact on a resource or service";
649 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
650 log.debug(message, e);
651 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
654 // ////////// API END ///////////////////////////
656 // ************ private *********************
657 private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) {
658 return handleArtifactRequest(data, componentId, null, componentType, ArtifactOperationEnum.CREATE);
661 private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId,
662 ComponentTypeEnum componentType) {
663 return handleArtifactRequest(data, componentId, artifactId, componentType, ArtifactOperationEnum.UPDATE);
666 private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId,
667 ComponentTypeEnum componentType, String containerComponentType) {
668 String userId = request.getHeader(Constants.USER_ID_HEADER);
669 ImmutablePair<String, byte[]> actionResult = artifactsBusinessLogic
670 .handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType);
672 byte[] file = actionResult.getRight();
673 String base64Contents = new String(Base64.encodeBase64(file));
674 String artifactName = actionResult.getLeft();
675 ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
676 ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData();
677 artifactUiDownloadData.setArtifactName(artifactName);
678 artifactUiDownloadData.setBase64Contents(base64Contents);
679 response = buildOkResponse(responseFormat, artifactUiDownloadData);
683 private Response handleGetArtifactsRequest(HttpServletRequest request, String componentId, String parentId, String artifactGroupType,
684 String containerComponentType) {
685 String userId = request.getHeader(Constants.USER_ID_HEADER);
686 ComponentTypeEnum componentTypeEnum =
687 parentId == null || parentId.isEmpty() ? ComponentTypeEnum.findByParamName(containerComponentType) : ComponentTypeEnum.RESOURCE_INSTANCE;
688 Map<String, ArtifactDefinition> actionResult = artifactsBusinessLogic
689 .handleGetArtifactsByType(containerComponentType, parentId, componentTypeEnum, componentId, artifactGroupType, userId);
690 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResult);
693 private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
694 String interfaceType, String operationName) {
695 return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null);
698 private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType,
699 String interfaceType, String operationName, String parentId) {
700 String userId = request.getHeader(Constants.USER_ID_HEADER);
701 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> actionResult = artifactsBusinessLogic
702 .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DELETE),
703 artifactId, null, null, null, interfaceType, operationName, parentId, null);
705 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = actionResult;
706 if (result.isLeft()) {
707 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
709 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
714 private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName,
715 String artifactId, ComponentTypeEnum componentType, ArtifactOperationEnum operationEnum, String parentId,
716 String containerComponentType, boolean validateTimeout) {
717 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.STARTED, "Starting to update artifact {} ",
718 artifactId + " for component " + componentId);
719 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, validateTimeout);
720 String origMd5 = request.getHeader(Constants.MD5_HEADER);
721 String userId = request.getHeader(Constants.USER_ID_HEADER);
722 Either<ArtifactDefinition, org.openecomp.sdc.be.model.Operation> result = artifactsBusinessLogic
723 .handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, operationEnum), artifactId,
724 artifactInfo, origMd5, data, interfaceName, operationName, parentId, containerComponentType);
726 if (result.isLeft()) {
727 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value());
729 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value());
731 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_ARTIFACT, StatusCode.COMPLETE, "Ended update artifact {} ",
732 artifactId + " for component " + componentId);
736 private Response handleArtifactRequest(String data, String componentId, String artifactId, ComponentTypeEnum componentType,
737 ArtifactOperationEnum operation) {
738 return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null, false);