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 org.apache.http.HttpStatus;
37 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
38 import org.glassfish.jersey.media.multipart.FormDataParam;
39 import org.json.JSONException;
40 import org.json.JSONObject;
41 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
42 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
43 import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
44 import org.openecomp.sdc.be.components.impl.ImportUtils;
45 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
46 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
47 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
48 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
49 import org.openecomp.sdc.be.config.BeEcompErrorManager;
50 import org.openecomp.sdc.be.dao.api.ActionStatus;
51 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
52 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
53 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
54 import org.openecomp.sdc.be.impl.ComponentsUtils;
55 import org.openecomp.sdc.be.impl.ServletUtils;
56 import org.openecomp.sdc.be.model.Resource;
57 import org.openecomp.sdc.be.model.UploadResourceInfo;
58 import org.openecomp.sdc.be.model.User;
59 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
60 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
61 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
62 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
63 import org.openecomp.sdc.be.user.UserBusinessLogic;
64 import org.openecomp.sdc.common.api.Constants;
65 import org.openecomp.sdc.common.datastructure.Wrapper;
66 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
67 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
68 import org.openecomp.sdc.common.log.enums.StatusCode;
69 import org.openecomp.sdc.common.log.wrappers.Logger;
70 import org.openecomp.sdc.common.zip.exception.ZipException;
71 import org.openecomp.sdc.exception.ResponseFormat;
72 import org.springframework.stereotype.Controller;
74 import javax.inject.Inject;
75 import javax.servlet.ServletContext;
76 import javax.servlet.http.HttpServletRequest;
77 import javax.ws.rs.Consumes;
78 import javax.ws.rs.DELETE;
79 import javax.ws.rs.GET;
80 import javax.ws.rs.HeaderParam;
81 import javax.ws.rs.POST;
82 import javax.ws.rs.PUT;
83 import javax.ws.rs.Path;
84 import javax.ws.rs.PathParam;
85 import javax.ws.rs.Produces;
86 import javax.ws.rs.QueryParam;
87 import javax.ws.rs.core.Context;
88 import javax.ws.rs.core.MediaType;
89 import javax.ws.rs.core.Response;
90 import java.io.IOException;
91 import java.util.List;
94 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
96 @Tags({@Tag(name = "SDC Internal APIs")})
97 @Servers({@Server(url = "/sdc2/rest")})
99 public class ResourcesServlet extends AbstractValidationsServlet {
101 private static final Logger log = Logger.getLogger(ResourcesServlet.class);
102 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourcesServlet.class.getName());
103 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
104 private static final String MODIFIER_ID_IS = "modifier id is {}";
105 private final ResourceBusinessLogic resourceBusinessLogic;
108 public ResourcesServlet(UserBusinessLogic userBusinessLogic,
109 ComponentInstanceBusinessLogic componentInstanceBL,
110 ResourceBusinessLogic resourceBusinessLogic,
111 ComponentsUtils componentsUtils, ServletUtils servletUtils,
112 ResourceImportManager resourceImportManager) {
113 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
114 this.resourceBusinessLogic = resourceBusinessLogic;
119 @Consumes(MediaType.APPLICATION_JSON)
120 @Produces(MediaType.APPLICATION_JSON)
121 @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", responses = {
122 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
123 @ApiResponse(responseCode = "201", description = "Resource created"),
124 @ApiResponse(responseCode = "403", description = "Restricted operation"),
125 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
126 @ApiResponse(responseCode = "409", description = "Resource already exist")})
127 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
128 public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
129 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException, ZipException {
131 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
134 String url = request.getMethod() + " " + request.getRequestURI();
135 log.debug(START_HANDLE_REQUEST_OF, url);
137 User modifier = new User();
138 modifier.setUserId(userId);
139 log.debug(MODIFIER_ID_IS, userId);
140 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED,"Starting to create Resource by user {}",userId);
144 Wrapper<Response> responseWrapper = new Wrapper<>();
146 if (isUIImport(data)) {
147 performUIImport(responseWrapper, data, request, userId, null);
152 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
153 if (convertResponse.isRight()) {
154 log.debug("failed to parse resource");
155 response = buildErrorResponse(convertResponse.right().value());
159 Resource resource = convertResponse.left().value();
160 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
161 Object representation = RepresentationUtils.toRepresentation(createdResource);
162 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
163 responseWrapper.setInnerElement(response);
164 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE,resource.getComponentMetadataForSupportLog() ,StatusCode.COMPLETE,"Resource successfully created user {}",userId);
166 return responseWrapper.getInnerElement();
167 } catch (final IOException | ZipException e) {
168 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
169 log.debug("create resource failed with exception", e);
174 private boolean isUIImport(String data) {
177 JSONObject json = new JSONObject(data);
178 String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
179 isUIImport = payloadName != null && !payloadName.isEmpty();
180 } catch (JSONException e) {
181 log.debug("failed to parse json sent from client, json:{}", data, e);
187 private void performUIImport(final Wrapper<Response> responseWrapper, final String data,
188 final HttpServletRequest request, final String userId,
189 final String resourceUniqueId) throws ZipException {
190 Wrapper<User> userWrapper = new Wrapper<>();
191 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
192 Wrapper<String> yamlStringWrapper = new Wrapper<>();
194 ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
196 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
198 if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
199 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum, null);
201 // PayLoad Validations
202 commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
204 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, data, resourceAuthorityEnum);
206 if (responseWrapper.isEmpty()) {
207 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
211 private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
212 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
215 private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
216 Either<Resource, ResponseFormat> ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
217 if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
218 ret.left().value().setRequirements(null);
219 ret.left().value().setCapabilities(null);
225 @Path("/resources/{resourceId}")
226 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
227 public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) {
229 String url = request.getMethod() + " " + request.getRequestURI();
230 log.debug(START_HANDLE_REQUEST_OF, url);
232 String userId = request.getHeader(Constants.USER_ID_HEADER);
233 User modifier = new User();
234 modifier.setUserId(userId);
235 log.debug(MODIFIER_ID_IS, userId);
236 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.STARTED,"Starting to delete Resource by user {}",userId);
240 String resourceIdLower = resourceId.toLowerCase();
241 ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
243 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
244 log.debug("failed to delete resource");
245 response = buildErrorResponse(actionResponse);
248 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
249 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE ,StatusCode.COMPLETE,"Ended delete Resource by user {}",userId);
252 } catch (JSONException e) {
253 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
254 log.debug("delete resource failed with exception", e);
260 @Path("/resources/{resourceName}/{version}")
261 @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content",
262 responses = {@ApiResponse(
263 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
264 @ApiResponse(responseCode = "204", description = "Resource deleted"),
265 @ApiResponse(responseCode = "403", description = "Restricted operation"),
266 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
267 @ApiResponse(responseCode = "404", description = "Resource not found")})
268 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
269 public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) {
271 ServletContext context = request.getSession().getServletContext();
273 String url = request.getMethod() + " " + request.getRequestURI();
274 log.debug(START_HANDLE_REQUEST_OF, url);
277 String userId = request.getHeader(Constants.USER_ID_HEADER);
278 User modifier = new User();
279 modifier.setUserId(userId);
280 log.debug(MODIFIER_ID_IS, userId);
283 ResourceBusinessLogic businessLogic = getResourceBL(context);
284 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
286 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
287 log.debug("failed to delete resource");
288 response = buildErrorResponse(actionResponse);
291 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
296 @Path("/resources/{resourceId}")
297 @Consumes(MediaType.APPLICATION_JSON)
298 @Produces(MediaType.APPLICATION_JSON)
299 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId",
300 responses = {@ApiResponse(
301 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
302 @ApiResponse(responseCode = "200", description = "Resource found"),
303 @ApiResponse(responseCode = "403", description = "Restricted operation"),
304 @ApiResponse(responseCode = "404", description = "Resource not found")})
305 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
306 public Response getResourceById(@PathParam("resourceId") final String resourceId,
307 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
309 ServletContext context = request.getSession().getServletContext();
311 String url = request.getMethod() + " " + request.getRequestURI();
312 log.debug(START_HANDLE_REQUEST_OF, url);
315 User modifier = new User();
316 modifier.setUserId(userId);
317 log.debug(MODIFIER_ID_IS, userId);
322 String resourceIdLower = resourceId.toLowerCase();
323 log.trace("get resource with id {}", resourceId);
324 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
326 if (actionResponse.isRight()) {
327 log.debug("failed to get resource");
328 response = buildErrorResponse(actionResponse.right().value());
331 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
332 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
334 } catch (IOException e) {
335 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
336 log.debug("get resource failed with exception", e);
342 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
343 @Consumes(MediaType.APPLICATION_JSON)
344 @Produces(MediaType.APPLICATION_JSON)
345 @Operation(description = "Retrieve Resource by name and version", method = "GET",
346 summary = "Returns resource according to resourceId", responses = {
347 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
348 @ApiResponse(responseCode = "200", description = "Resource found"),
349 @ApiResponse(responseCode = "403", description = "Restricted operation"),
350 @ApiResponse(responseCode = "404", description = "Resource not found")})
351 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
352 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
353 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
354 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
357 User modifier = new User();
358 modifier.setUserId(userId);
359 log.debug(MODIFIER_ID_IS, userId);
362 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId);
363 if (actionResponse.isRight()) {
364 response = buildErrorResponse(actionResponse.right().value());
367 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
368 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
370 } catch (IOException e) {
371 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
372 log.debug("get resource failed with exception", e);
378 @Path("/resources/validate-name/{resourceName}")
379 @Consumes(MediaType.APPLICATION_JSON)
380 @Produces(MediaType.APPLICATION_JSON)
381 @Operation(description = "validate resource name", method = "GET",
382 summary = "checks if the chosen resource name is available ", responses = {
383 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
384 @ApiResponse(responseCode = "200", description = "Resource found"),
385 @ApiResponse(responseCode = "403", description = "Restricted operation")})
386 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
387 public Response validateResourceName(@PathParam("resourceName") final String resourceName,
388 @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request,
389 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
390 String url = request.getMethod() + " " + request.getRequestURI();
391 log.debug(START_HANDLE_REQUEST_OF, url);
394 User modifier = new User();
395 modifier.setUserId(userId);
396 log.debug(MODIFIER_ID_IS, userId);
399 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
400 log.debug("invalid resource type received");
401 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
405 ResourceTypeEnum typeEnum = null;
406 if (resourceType != null) {
407 typeEnum = ResourceTypeEnum.valueOf(resourceType);
409 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic.validateResourceNameExists(resourceName, typeEnum, userId);
411 if (actionResponse.isRight()) {
412 log.debug("failed to validate resource name");
413 response = buildErrorResponse(actionResponse.right().value());
416 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
420 @Path("/resources/certified/abstract")
421 @Consumes(MediaType.APPLICATION_JSON)
422 @Produces(MediaType.APPLICATION_JSON)
423 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
424 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
425 String url = request.getMethod() + " " + request.getRequestURI();
426 log.debug("(get) Start handle request of {}" , url);
428 List<Resource> resources = resourceBusinessLogic
429 .getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
430 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
432 } catch (IOException e) {
433 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
434 log.debug("getCertifiedAbstractResources failed with exception", e);
440 @Path("/resources/certified/notabstract")
441 @Consumes(MediaType.APPLICATION_JSON)
442 @Produces(MediaType.APPLICATION_JSON)
443 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
444 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
445 String url = request.getMethod() + " " + request.getRequestURI();
446 log.debug("(get) Start handle request of {}" , url);
448 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
449 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
451 } catch (IOException e) {
452 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
453 log.debug("getCertifiedNotAbstractResources failed with exception", e);
460 @Path("/resources/{resourceId}/metadata")
461 @Consumes(MediaType.APPLICATION_JSON)
462 @Produces(MediaType.APPLICATION_JSON)
463 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata",
464 responses = {@ApiResponse(
465 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
466 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
467 @ApiResponse(responseCode = "403", description = "Restricted operation"),
468 @ApiResponse(responseCode = "400", description = "Invalid content")})
469 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
470 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
471 @Parameter(description = "Resource metadata to be updated", required = true) String data,
472 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
474 String url = request.getMethod() + " " + request.getRequestURI();
475 log.debug(START_HANDLE_REQUEST_OF, url);
478 User modifier = new User();
479 modifier.setUserId(userId);
480 log.debug(MODIFIER_ID_IS, userId);
483 String resourceIdLower = resourceId.toLowerCase();
484 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE);
485 if (updateInfoResource.isRight()) {
486 log.debug("failed to parse resource metadata");
487 response = buildErrorResponse(updateInfoResource.right().value());
490 Resource updatedResource = resourceBusinessLogic.updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
491 Object resource = RepresentationUtils.toRepresentation(updatedResource);
492 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
493 } catch (IOException e) {
494 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
495 log.debug("Update Resource Metadata failed with exception", e);
501 @Path("/resources/{resourceId}")
502 @Consumes(MediaType.APPLICATION_JSON)
503 @Produces(MediaType.APPLICATION_JSON)
504 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
505 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
506 @ApiResponse(responseCode = "200", description = "Resource updated"),
507 @ApiResponse(responseCode = "403", description = "Restricted operation"),
508 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
509 @ApiResponse(responseCode = "409", description = "Resource already exist")})
510 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
511 public Response updateResource(
512 @Parameter(description = "Resource object to be updated", required = true) String data,
513 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
514 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
516 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
518 String url = request.getMethod() + " " + request.getRequestURI();
519 log.debug(START_HANDLE_REQUEST_OF, url);
521 User modifier = new User();
522 modifier.setUserId(userId);
523 log.debug(MODIFIER_ID_IS, userId);
524 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,StatusCode.STARTED,"Starting to update a resource by user {}",userId);
527 Wrapper<Response> responseWrapper = new Wrapper<>();
529 if (isUIImport(data)) {
530 performUIImport(responseWrapper, data, request, userId, resourceId);
532 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
533 if (convertResponse.isRight()) {
534 log.debug("failed to parse resource");
535 response = buildErrorResponse(convertResponse.right().value());
538 Resource updatedResource = resourceBusinessLogic.validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
539 Object representation = RepresentationUtils.toRepresentation(updatedResource);
540 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
541 responseWrapper.setInnerElement(response);
542 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE,updatedResource.getComponentMetadataForSupportLog(),StatusCode.COMPLETE,"Ended update a resource by user {}",userId);
545 return responseWrapper.getInnerElement();
546 } catch (final IOException | ZipException e) {
547 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
548 log.debug("update resource failed with exception", e);
554 @Path("/resources/csar/{csaruuid}")
555 @Consumes(MediaType.APPLICATION_JSON)
556 @Produces(MediaType.APPLICATION_JSON)
557 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid",
558 responses = {@ApiResponse(
559 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
560 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
561 @ApiResponse(responseCode = "403", description = "Restricted operation"),
562 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
563 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
564 public Response getResourceFromCsar(@Context final HttpServletRequest request,
565 @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
566 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
570 String url = request.getMethod() + " " + request.getRequestURI();
571 log.debug(START_HANDLE_REQUEST_OF, url);
573 // retrieve user details
574 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
575 User user = new User();
576 user.setUserId(userId);
578 log.debug("user id is {}", userId);
584 Either<Resource, ResponseFormat> eitherResource =
585 resourceBusinessLogic.getLatestResourceFromCsarUuid(csarUUID, user);
588 if (eitherResource.isRight()) {
589 log.debug("failed to get resource from csarUuid : {}", csarUUID);
590 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), eitherResource.right().value());
592 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
593 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
598 } catch (IOException e) {
599 log.debug("get resource by csar failed with exception", e);
605 @Path("/resources/importReplaceResource")
606 @Produces(MediaType.APPLICATION_JSON)
607 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
608 @ApiResponse(responseCode = "201", description = "Resource created"),
609 @ApiResponse(responseCode = "403", description = "Restricted operation"),
610 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
611 @ApiResponse(responseCode = "409", description = "Resource already exist")})
612 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
613 public Response importReplaceResource(
614 @Parameter(description = "The user id",
615 required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
616 @Parameter(description = "X-ECOMP-RequestID header",
617 required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
618 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
619 value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
620 @Parameter(description = "Determines the format of the body of the response",
621 required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
622 @Parameter(description = "The username and password",
623 required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
624 @Context final HttpServletRequest request,
625 @Parameter(description = "FileInputStream")
626 @FormDataParam("resourceZip") File file,
627 @Parameter(description = "ContentDisposition")
628 @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
629 @Parameter(description = "resourceMetadata")
630 @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
634 String requestURI = request.getRequestURI();
635 String url = request.getMethod() + " " + requestURI;
636 log.debug("importReplaceResource,Start handle request of {}", url);
639 User modifier = new User();
640 modifier.setUserId(userId);
641 log.debug("importReplaceResource,modifier id is {}", userId);
643 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
646 ResponseFormat responseFormat = null;
647 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
648 String assetType = "resources";
650 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
651 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
652 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
654 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
655 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
656 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
657 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
658 resourceCommonInfo, requestId, null);
659 return buildErrorResponse(responseFormat);
663 Wrapper<Response> responseWrapper = new Wrapper<>();
665 Wrapper<User> userWrapper = new Wrapper<>();
666 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
667 Wrapper<String> yamlStringWrapper = new Wrapper<>();
669 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
671 // PayLoad Validations
672 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
674 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
676 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, serviceAuthorityEnum);
678 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
680 log.debug("importReplaceResource:get ResourceType:{}",
681 uploadResourceInfoWrapper.getInnerElement().getResourceType());
683 if (responseWrapper.isEmpty()) {
684 log.debug("importReplaceService:start handleImport");
685 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
688 return responseWrapper.getInnerElement();
689 } catch (ZipException e) {
690 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
691 log.debug("import resource failed with exception", e);
692 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));