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=========================================================
21 package org.openecomp.sdc.be.servlets;
23 import com.jcabi.aspects.Loggable;
24 import fj.data.Either;
25 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.media.ArraySchema;
28 import io.swagger.v3.oas.annotations.media.Content;
29 import io.swagger.v3.oas.annotations.media.Schema;
30 import io.swagger.v3.oas.annotations.responses.ApiResponse;
31 import io.swagger.v3.oas.annotations.servers.Server;
32 import io.swagger.v3.oas.annotations.servers.Servers;
33 import io.swagger.v3.oas.annotations.tags.Tag;
34 import io.swagger.v3.oas.annotations.tags.Tags;
36 import java.io.IOException;
37 import java.util.List;
39 import javax.inject.Inject;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.ws.rs.Consumes;
43 import javax.ws.rs.DELETE;
44 import javax.ws.rs.GET;
45 import javax.ws.rs.HeaderParam;
46 import javax.ws.rs.POST;
47 import javax.ws.rs.PUT;
48 import javax.ws.rs.Path;
49 import javax.ws.rs.PathParam;
50 import javax.ws.rs.Produces;
51 import javax.ws.rs.QueryParam;
52 import javax.ws.rs.core.Context;
53 import javax.ws.rs.core.MediaType;
54 import javax.ws.rs.core.Response;
55 import org.apache.http.HttpStatus;
56 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
57 import org.glassfish.jersey.media.multipart.FormDataParam;
58 import org.json.JSONException;
59 import org.json.JSONObject;
60 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
61 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
62 import org.openecomp.sdc.be.components.impl.ImportUtils;
63 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
64 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
65 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
66 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
67 import org.openecomp.sdc.be.config.BeEcompErrorManager;
68 import org.openecomp.sdc.be.dao.api.ActionStatus;
69 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
70 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
71 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
72 import org.openecomp.sdc.be.impl.ComponentsUtils;
73 import org.openecomp.sdc.be.impl.ServletUtils;
74 import org.openecomp.sdc.be.model.Resource;
75 import org.openecomp.sdc.be.model.UploadResourceInfo;
76 import org.openecomp.sdc.be.model.User;
77 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
78 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
79 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
80 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
81 import org.openecomp.sdc.be.user.UserBusinessLogic;
82 import org.openecomp.sdc.common.api.Constants;
83 import org.openecomp.sdc.common.datastructure.Wrapper;
84 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
85 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
86 import org.openecomp.sdc.common.log.enums.StatusCode;
87 import org.openecomp.sdc.common.log.wrappers.Logger;
88 import org.openecomp.sdc.common.util.ValidationUtils;
89 import org.openecomp.sdc.common.zip.exception.ZipException;
90 import org.openecomp.sdc.exception.ResponseFormat;
91 import org.springframework.stereotype.Controller;
93 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
95 @Tags({@Tag(name = "SDCE-2 APIs")})
96 @Servers({@Server(url = "/sdc2/rest")})
98 public class ResourcesServlet extends AbstractValidationsServlet {
100 private static final Logger log = Logger.getLogger(ResourcesServlet.class);
101 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourcesServlet.class.getName());
102 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
103 private static final String MODIFIER_ID_IS = "modifier id is {}";
104 private final ResourceBusinessLogic resourceBusinessLogic;
107 public ResourcesServlet(UserBusinessLogic userBusinessLogic,
108 ComponentInstanceBusinessLogic componentInstanceBL,
109 ResourceBusinessLogic resourceBusinessLogic,
110 ComponentsUtils componentsUtils, ServletUtils servletUtils,
111 ResourceImportManager resourceImportManager) {
112 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
113 this.resourceBusinessLogic = resourceBusinessLogic;
118 @Consumes(MediaType.APPLICATION_JSON)
119 @Produces(MediaType.APPLICATION_JSON)
120 @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", responses = {
121 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
122 @ApiResponse(responseCode = "201", description = "Resource created"),
123 @ApiResponse(responseCode = "403", description = "Restricted operation"),
124 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
125 @ApiResponse(responseCode = "409", description = "Resource already exist")})
126 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
127 public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
128 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException, ZipException {
130 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
133 String url = request.getMethod() + " " + request.getRequestURI();
134 log.debug(START_HANDLE_REQUEST_OF, url);
136 User modifier = new User();
137 modifier.setUserId(userId);
138 log.debug(MODIFIER_ID_IS, userId);
139 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED,"Starting to create Resource by user {}",userId);
143 Wrapper<Response> responseWrapper = new Wrapper<>();
145 if (isUIImport(data)) {
146 performUIImport(responseWrapper, data, request, userId, null);
151 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
152 if (convertResponse.isRight()) {
153 log.debug("failed to parse resource");
154 response = buildErrorResponse(convertResponse.right().value());
158 Resource resource = convertResponse.left().value();
159 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
160 Object representation = RepresentationUtils.toRepresentation(createdResource);
161 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
162 responseWrapper.setInnerElement(response);
163 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE,resource.getComponentMetadataForSupportLog() ,StatusCode.COMPLETE,"Resource successfully created user {}",userId);
165 return responseWrapper.getInnerElement();
166 } catch (final IOException | ZipException e) {
167 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
168 log.debug("create resource failed with exception", e);
173 private boolean isUIImport(String data) {
176 JSONObject json = new JSONObject(data);
177 String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
178 isUIImport = payloadName != null && !payloadName.isEmpty();
179 } catch (JSONException e) {
180 log.debug("failed to parse json sent from client, json:{}", data, e);
186 private void performUIImport(final Wrapper<Response> responseWrapper, final String data,
187 final HttpServletRequest request, final String userId,
188 final String resourceUniqueId) throws ZipException {
189 Wrapper<User> userWrapper = new Wrapper<>();
190 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
191 Wrapper<String> yamlStringWrapper = new Wrapper<>();
193 ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
195 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
197 if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
198 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null);
200 // PayLoad Validations
201 commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
203 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum);
205 if (responseWrapper.isEmpty()) {
206 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
210 private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
211 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
214 private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
215 Either<Resource, ResponseFormat> ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
216 if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
217 ret.left().value().setRequirements(null);
218 ret.left().value().setCapabilities(null);
224 @Path("/resources/{resourceId}")
225 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
226 public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) {
228 String url = request.getMethod() + " " + request.getRequestURI();
229 log.debug(START_HANDLE_REQUEST_OF, url);
231 String userId = request.getHeader(Constants.USER_ID_HEADER);
232 User modifier = new User();
233 modifier.setUserId(userId);
234 log.debug(MODIFIER_ID_IS, userId);
235 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.STARTED,"Starting to delete Resource by user {}",userId);
239 String resourceIdLower = resourceId.toLowerCase();
240 ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
242 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
243 log.debug("failed to delete resource");
244 response = buildErrorResponse(actionResponse);
247 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
248 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.COMPLETE,"Ended delete Resource by user {}",userId);
251 } catch (JSONException e) {
252 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
253 log.debug("delete resource failed with exception", e);
259 @Path("/resources/{resourceName}/{version}")
260 @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content",
261 responses = {@ApiResponse(
262 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
263 @ApiResponse(responseCode = "204", description = "Resource deleted"),
264 @ApiResponse(responseCode = "403", description = "Restricted operation"),
265 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
266 @ApiResponse(responseCode = "404", description = "Resource not found")})
267 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
268 public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) {
270 ServletContext context = request.getSession().getServletContext();
272 String url = request.getMethod() + " " + request.getRequestURI();
273 log.debug(START_HANDLE_REQUEST_OF, url);
276 String userId = request.getHeader(Constants.USER_ID_HEADER);
277 User modifier = new User();
278 modifier.setUserId(userId);
279 log.debug(MODIFIER_ID_IS, userId);
282 ResourceBusinessLogic businessLogic = getResourceBL(context);
283 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
285 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
286 log.debug("failed to delete resource");
287 response = buildErrorResponse(actionResponse);
290 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
295 @Path("/resources/{resourceId}")
296 @Consumes(MediaType.APPLICATION_JSON)
297 @Produces(MediaType.APPLICATION_JSON)
298 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId",
299 responses = {@ApiResponse(
300 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
301 @ApiResponse(responseCode = "200", description = "Resource found"),
302 @ApiResponse(responseCode = "403", description = "Restricted operation"),
303 @ApiResponse(responseCode = "404", description = "Resource not found")})
304 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
305 public Response getResourceById(@PathParam("resourceId") final String resourceId,
306 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
308 ServletContext context = request.getSession().getServletContext();
310 String url = request.getMethod() + " " + request.getRequestURI();
311 log.debug(START_HANDLE_REQUEST_OF, url);
314 User modifier = new User();
315 modifier.setUserId(userId);
316 log.debug(MODIFIER_ID_IS, userId);
321 String resourceIdLower = resourceId.toLowerCase();
322 log.trace("get resource with id {}", resourceId);
323 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
325 if (actionResponse.isRight()) {
326 log.debug("failed to get resource");
327 response = buildErrorResponse(actionResponse.right().value());
330 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
331 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
333 } catch (IOException e) {
334 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
335 log.debug("get resource failed with exception", e);
341 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
342 @Consumes(MediaType.APPLICATION_JSON)
343 @Produces(MediaType.APPLICATION_JSON)
344 @Operation(description = "Retrieve Resource by name and version", method = "GET",
345 summary = "Returns resource according to resourceId", responses = {
346 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
347 @ApiResponse(responseCode = "200", description = "Resource found"),
348 @ApiResponse(responseCode = "403", description = "Restricted operation"),
349 @ApiResponse(responseCode = "404", description = "Resource not found")})
350 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
351 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
352 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
353 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
356 User modifier = new User();
357 modifier.setUserId(userId);
358 log.debug(MODIFIER_ID_IS, userId);
361 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId);
362 if (actionResponse.isRight()) {
363 response = buildErrorResponse(actionResponse.right().value());
366 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
367 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
369 } catch (IOException e) {
370 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
371 log.debug("get resource failed with exception", e);
377 @Path("/resources/validate-name/{resourceName}")
378 @Consumes(MediaType.APPLICATION_JSON)
379 @Produces(MediaType.APPLICATION_JSON)
380 @Operation(description = "validate resource name", method = "GET",
381 summary = "checks if the chosen resource name is available ", responses = {
382 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
383 @ApiResponse(responseCode = "200", description = "Resource found"),
384 @ApiResponse(responseCode = "403", description = "Restricted operation")})
385 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
386 public Response validateResourceName(@PathParam("resourceName") final String resourceName,
387 @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request,
388 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
389 String url = request.getMethod() + " " + request.getRequestURI();
390 log.debug(START_HANDLE_REQUEST_OF, url);
393 User modifier = new User();
394 modifier.setUserId(userId);
395 log.debug(MODIFIER_ID_IS, userId);
398 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
399 log.debug("invalid resource type received");
400 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
404 ResourceTypeEnum typeEnum = null;
405 if (resourceType != null) {
406 typeEnum = ResourceTypeEnum.valueOf(resourceType);
408 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId);
410 if (actionResponse.isRight()) {
411 log.debug("failed to validate resource name");
412 response = buildErrorResponse(actionResponse.right().value());
415 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
419 @Path("/resources/certified/abstract")
420 @Consumes(MediaType.APPLICATION_JSON)
421 @Produces(MediaType.APPLICATION_JSON)
422 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
423 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
424 String url = request.getMethod() + " " + request.getRequestURI();
425 log.debug("(get) Start handle request of {}" , url);
427 List<Resource> resources = resourceBusinessLogic
428 .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
429 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
431 } catch (IOException e) {
432 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
433 log.debug("getCertifiedAbstractResources failed with exception", e);
439 @Path("/resources/certified/notabstract")
440 @Consumes(MediaType.APPLICATION_JSON)
441 @Produces(MediaType.APPLICATION_JSON)
442 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
443 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
444 String url = request.getMethod() + " " + request.getRequestURI();
445 log.debug("(get) Start handle request of {}" , url);
447 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
448 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
450 } catch (IOException e) {
451 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
452 log.debug("getCertifiedNotAbstractResources failed with exception", e);
459 @Path("/resources/{resourceId}/metadata")
460 @Consumes(MediaType.APPLICATION_JSON)
461 @Produces(MediaType.APPLICATION_JSON)
462 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata",
463 responses = {@ApiResponse(
464 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
465 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
466 @ApiResponse(responseCode = "403", description = "Restricted operation"),
467 @ApiResponse(responseCode = "400", description = "Invalid content")})
468 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
469 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
470 @Parameter(description = "Resource metadata to be updated", required = true) String data,
471 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
473 String url = request.getMethod() + " " + request.getRequestURI();
474 log.debug(START_HANDLE_REQUEST_OF, url);
477 User modifier = new User();
478 modifier.setUserId(userId);
479 log.debug(MODIFIER_ID_IS, userId);
482 String resourceIdLower = resourceId.toLowerCase();
483 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
484 if (updateInfoResource.isRight()) {
485 log.debug("failed to parse resource metadata");
486 response = buildErrorResponse(updateInfoResource.right().value());
489 Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
490 Object resource = RepresentationUtils.toRepresentation(updatedResource);
491 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
492 } catch (IOException e) {
493 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
494 log.debug("Update Resource Metadata failed with exception", e);
500 @Path("/resources/{resourceId}")
501 @Consumes(MediaType.APPLICATION_JSON)
502 @Produces(MediaType.APPLICATION_JSON)
503 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
504 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
505 @ApiResponse(responseCode = "200", description = "Resource updated"),
506 @ApiResponse(responseCode = "403", description = "Restricted operation"),
507 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
508 @ApiResponse(responseCode = "409", description = "Resource already exist")})
509 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
510 public Response updateResource(
511 @Parameter(description = "Resource object to be updated", required = true) String data,
512 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
513 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
515 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
517 String url = request.getMethod() + " " + request.getRequestURI();
518 log.debug(START_HANDLE_REQUEST_OF, url);
520 User modifier = new User();
521 modifier.setUserId(userId);
522 log.debug(MODIFIER_ID_IS, userId);
523 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,StatusCode.STARTED,"Starting to update a resource by user {}",userId);
526 Wrapper<Response> responseWrapper = new Wrapper<>();
528 if (isUIImport(data)) {
529 performUIImport(responseWrapper, data, request, userId, resourceId);
531 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
532 if (convertResponse.isRight()) {
533 log.debug("failed to parse resource");
534 response = buildErrorResponse(convertResponse.right().value());
537 Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
538 Object representation = RepresentationUtils.toRepresentation(updatedResource);
539 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
540 responseWrapper.setInnerElement(response);
541 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,updatedResource.getComponentMetadataForSupportLog(),StatusCode.COMPLETE,"Ended update a resource by user {}",userId);
544 return responseWrapper.getInnerElement();
545 } catch (final IOException | ZipException e) {
546 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
547 log.debug("update resource failed with exception", e);
553 @Path("/resources/csar/{csaruuid}")
554 @Consumes(MediaType.APPLICATION_JSON)
555 @Produces(MediaType.APPLICATION_JSON)
556 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid",
557 responses = {@ApiResponse(
558 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
559 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
560 @ApiResponse(responseCode = "403", description = "Restricted operation"),
561 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
562 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
563 public Response getResourceFromCsar(@Context final HttpServletRequest request,
564 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
565 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
569 String url = request.getMethod() + " " + request.getRequestURI();
570 log.debug(START_HANDLE_REQUEST_OF, url);
572 // retrieve user details
573 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
574 User user = new User();
575 user.setUserId(userId);
577 log.debug("user id is {}", userId);
583 Either<Resource, ResponseFormat> eitherResource =
584 resourceBusinessLogic.getLatestResourceFromCsarUuid(ValidationUtils.sanitizeInputString(csarUUID), user);
587 if (eitherResource.isRight()) {
588 log.debug("failed to get resource from csarUuid : {}", csarUUID);
589 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT), eitherResource.right().value());
591 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
592 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
597 } catch (IOException e) {
598 log.debug("get resource by csar failed with exception", e);
604 @Path("/resources/importReplaceResource")
605 @Produces(MediaType.APPLICATION_JSON)
606 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
607 @ApiResponse(responseCode = "201", description = "Resource created"),
608 @ApiResponse(responseCode = "403", description = "Restricted operation"),
609 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
610 @ApiResponse(responseCode = "409", description = "Resource already exist")})
611 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
612 public Response importReplaceResource(
613 @Parameter(description = "The user id",
614 required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
615 @Parameter(description = "X-ECOMP-RequestID header",
616 required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
617 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
618 value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
619 @Parameter(description = "Determines the format of the body of the response",
620 required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
621 @Parameter(description = "The username and password",
622 required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
623 @Context final HttpServletRequest request,
624 @Parameter(description = "FileInputStream")
625 @FormDataParam("resourceZip") File file,
626 @Parameter(description = "ContentDisposition")
627 @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
628 @Parameter(description = "resourceMetadata")
629 @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
633 String requestURI = request.getRequestURI();
634 String url = request.getMethod() + " " + requestURI;
635 log.debug("importReplaceResource,Start handle request of {}", url);
638 User modifier = new User();
639 modifier.setUserId(userId);
640 log.debug("importReplaceResource,modifier id is {}", userId);
642 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
645 ResponseFormat responseFormat = null;
646 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
647 String assetType = "resources";
649 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
650 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
651 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
653 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
654 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
655 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
656 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
657 resourceCommonInfo, requestId, null);
658 return buildErrorResponse(responseFormat);
662 Wrapper<Response> responseWrapper = new Wrapper<>();
664 Wrapper<User> userWrapper = new Wrapper<>();
665 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
666 Wrapper<String> yamlStringWrapper = new Wrapper<>();
668 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
670 // PayLoad Validations
671 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
673 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
675 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, serviceAuthorityEnum);
677 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
679 log.debug("importReplaceResource:get ResourceType:{}",
680 uploadResourceInfoWrapper.getInnerElement().getResourceType());
682 if (responseWrapper.isEmpty()) {
683 log.debug("importReplaceService:start handleImport");
684 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
687 return responseWrapper.getInnerElement();
688 } catch (ZipException e) {
689 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
690 log.debug("import resource failed with exception", e);
691 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));