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 java.io.IOException;
36 import java.util.List;
38 import javax.inject.Inject;
39 import javax.servlet.ServletContext;
40 import javax.servlet.http.HttpServletRequest;
41 import javax.ws.rs.Consumes;
42 import javax.ws.rs.DELETE;
43 import javax.ws.rs.GET;
44 import javax.ws.rs.HeaderParam;
45 import javax.ws.rs.POST;
46 import javax.ws.rs.PUT;
47 import javax.ws.rs.Path;
48 import javax.ws.rs.PathParam;
49 import javax.ws.rs.Produces;
50 import javax.ws.rs.QueryParam;
51 import javax.ws.rs.core.Context;
52 import javax.ws.rs.core.MediaType;
53 import javax.ws.rs.core.Response;
54 import org.apache.http.HttpStatus;
55 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
56 import org.glassfish.jersey.media.multipart.FormDataParam;
57 import org.json.JSONException;
58 import org.json.JSONObject;
59 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
60 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
61 import org.openecomp.sdc.be.components.impl.ImportUtils;
62 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
63 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
64 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
65 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
66 import org.openecomp.sdc.be.config.BeEcompErrorManager;
67 import org.openecomp.sdc.be.dao.api.ActionStatus;
68 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
69 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
70 import org.openecomp.sdc.be.datatypes.enums.DeleteActionEnum;
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.common.api.Constants;
82 import org.openecomp.sdc.common.datastructure.Wrapper;
83 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
84 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
85 import org.openecomp.sdc.common.log.enums.StatusCode;
86 import org.openecomp.sdc.common.log.wrappers.Logger;
87 import org.openecomp.sdc.common.util.ValidationUtils;
88 import org.openecomp.sdc.common.zip.exception.ZipException;
89 import org.openecomp.sdc.exception.ResponseFormat;
90 import org.springframework.stereotype.Controller;
92 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
94 @Tags({@Tag(name = "SDCE-2 APIs")})
95 @Servers({@Server(url = "/sdc2/rest")})
97 public class ResourcesServlet extends AbstractValidationsServlet {
99 private static final Logger log = Logger.getLogger(ResourcesServlet.class);
100 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourcesServlet.class.getName());
101 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
102 private static final String MODIFIER_ID_IS = "modifier id is {}";
103 private final ResourceBusinessLogic resourceBusinessLogic;
106 public ResourcesServlet(ComponentInstanceBusinessLogic componentInstanceBL,
107 ResourceBusinessLogic resourceBusinessLogic, ComponentsUtils componentsUtils, ServletUtils servletUtils,
108 ResourceImportManager resourceImportManager) {
109 super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
110 this.resourceBusinessLogic = resourceBusinessLogic;
115 @Consumes(MediaType.APPLICATION_JSON)
116 @Produces(MediaType.APPLICATION_JSON)
117 @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", responses = {
118 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
119 @ApiResponse(responseCode = "201", description = "Resource created"),
120 @ApiResponse(responseCode = "403", description = "Restricted operation"),
121 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
122 @ApiResponse(responseCode = "409", description = "Resource already exist")})
123 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
124 public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
125 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
126 throws IOException, ZipException {
127 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
129 String url = request.getMethod() + " " + request.getRequestURI();
130 log.debug(START_HANDLE_REQUEST_OF, url);
132 User modifier = new User();
133 modifier.setUserId(userId);
134 log.debug(MODIFIER_ID_IS, userId);
135 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED, "Starting to create Resource by user {}", userId);
138 Wrapper<Response> responseWrapper = new Wrapper<>();
140 if (isUIImport(data)) {
141 performUIImport(responseWrapper, data, request, userId, null);
145 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
146 if (convertResponse.isRight()) {
147 log.debug("failed to parse resource");
148 response = buildErrorResponse(convertResponse.right().value());
151 Resource resource = convertResponse.left().value();
152 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
153 Object representation = RepresentationUtils.toRepresentation(createdResource);
154 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
155 responseWrapper.setInnerElement(response);
157 .log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
158 "Resource successfully created user {}", userId);
160 return responseWrapper.getInnerElement();
161 } catch (final IOException | ZipException e) {
162 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
163 log.debug("create resource failed with exception", e);
168 private boolean isUIImport(String data) {
171 JSONObject json = new JSONObject(data);
172 String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
173 isUIImport = payloadName != null && !payloadName.isEmpty();
174 } catch (JSONException e) {
175 log.debug("failed to parse json sent from client, json:{}", data, e);
181 private void performUIImport(final Wrapper<Response> responseWrapper, final String data, final HttpServletRequest request, final String userId,
182 final String resourceUniqueId) throws ZipException {
183 Wrapper<User> userWrapper = new Wrapper<>();
184 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
185 Wrapper<String> yamlStringWrapper = new Wrapper<>();
186 ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
187 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
188 if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
189 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum,
191 // PayLoad Validations
192 commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
194 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request,
195 data, resourceAuthorityEnum);
196 if (responseWrapper.isEmpty()) {
197 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
198 yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
202 private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
203 return getComponentsUtils()
204 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
207 private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
208 Either<Resource, ResponseFormat> ret = getComponentsUtils()
209 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
210 ComponentTypeEnum.RESOURCE);
211 if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
212 ret.left().value().setRequirements(null);
213 ret.left().value().setCapabilities(null);
219 @Path("/resources/{resourceId}")
220 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
221 public Response deleteResource(@PathParam("resourceId") final String resourceId,
222 @Parameter(description = "Optional parameter to determine the delete action: " +
223 "DELETE, which will permanently delete the Resource from the system or " +
224 "MARK_AS_DELETE, which will logically mark the Resource as deleted. Default action is to MARK_AS_DELETE")
225 @QueryParam("deleteAction") final DeleteActionEnum deleteAction,
226 @Context final HttpServletRequest request) {
227 String url = request.getMethod() + " " + request.getRequestURI();
228 log.debug(START_HANDLE_REQUEST_OF, url);
230 String userId = request.getHeader(Constants.USER_ID_HEADER);
231 User modifier = new User();
232 modifier.setUserId(userId);
233 log.debug(MODIFIER_ID_IS, userId);
234 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.STARTED, "Starting to delete Resource by user {}", userId);
236 String resourceIdLower = resourceId.toLowerCase();
237 ResponseFormat actionResponse;
238 if (DeleteActionEnum.DELETE.equals(deleteAction)) {
239 resourceBusinessLogic.deleteResourceAllVersions(resourceId, modifier);
240 actionResponse = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
242 actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
244 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
245 log.debug("failed to delete resource");
246 return buildErrorResponse(actionResponse);
249 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.COMPLETE, "Ended delete Resource by user {}", userId);
250 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
251 } catch (Exception 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", responses = {
261 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
262 @ApiResponse(responseCode = "204", description = "Resource deleted"),
263 @ApiResponse(responseCode = "403", description = "Restricted operation"),
264 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
265 @ApiResponse(responseCode = "404", description = "Resource not found")})
266 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
267 public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version,
268 @Context final HttpServletRequest request) {
269 ServletContext context = request.getSession().getServletContext();
270 String url = request.getMethod() + " " + request.getRequestURI();
271 log.debug(START_HANDLE_REQUEST_OF, url);
273 String userId = request.getHeader(Constants.USER_ID_HEADER);
274 User modifier = new User();
275 modifier.setUserId(userId);
276 log.debug(MODIFIER_ID_IS, userId);
278 ResourceBusinessLogic businessLogic = getResourceBL(context);
279 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
280 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
281 log.debug("failed to delete resource");
282 response = buildErrorResponse(actionResponse);
285 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
290 @Path("/resources/{resourceId}")
291 @Consumes(MediaType.APPLICATION_JSON)
292 @Produces(MediaType.APPLICATION_JSON)
293 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", responses = {
294 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
295 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
296 @ApiResponse(responseCode = "404", description = "Resource not found")})
297 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
298 public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request,
299 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
300 ServletContext context = request.getSession().getServletContext();
301 String url = request.getMethod() + " " + request.getRequestURI();
302 log.debug(START_HANDLE_REQUEST_OF, url);
304 User modifier = new User();
305 modifier.setUserId(userId);
306 log.debug(MODIFIER_ID_IS, userId);
309 String resourceIdLower = resourceId.toLowerCase();
310 log.trace("get resource with id {}", resourceId);
311 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
312 if (actionResponse.isRight()) {
313 log.debug("failed to get resource");
314 response = buildErrorResponse(actionResponse.right().value());
317 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
318 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
319 } catch (IOException e) {
320 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
321 log.debug("get resource failed with exception", e);
327 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
328 @Consumes(MediaType.APPLICATION_JSON)
329 @Produces(MediaType.APPLICATION_JSON)
330 @Operation(description = "Retrieve Resource by name and version", method = "GET", summary = "Returns resource according to resourceId", responses = {
331 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
332 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
333 @ApiResponse(responseCode = "404", description = "Resource not found")})
334 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
335 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
336 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
337 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
339 User modifier = new User();
340 modifier.setUserId(userId);
341 log.debug(MODIFIER_ID_IS, userId);
344 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic
345 .getResourceByNameAndVersion(resourceName, resourceVersion, userId);
346 if (actionResponse.isRight()) {
347 response = buildErrorResponse(actionResponse.right().value());
350 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
351 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
352 } catch (IOException e) {
353 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
354 log.debug("get resource failed with exception", e);
360 @Path("/resources/validate-name/{resourceName}")
361 @Consumes(MediaType.APPLICATION_JSON)
362 @Produces(MediaType.APPLICATION_JSON)
363 @Operation(description = "validate resource name", method = "GET", summary = "checks if the chosen resource name is available ", responses = {
364 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
365 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation")})
366 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
367 public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType,
368 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
369 String url = request.getMethod() + " " + request.getRequestURI();
370 log.debug(START_HANDLE_REQUEST_OF, url);
372 User modifier = new User();
373 modifier.setUserId(userId);
374 log.debug(MODIFIER_ID_IS, userId);
376 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
377 log.debug("invalid resource type received");
378 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
381 ResourceTypeEnum typeEnum = null;
382 if (resourceType != null) {
383 typeEnum = ResourceTypeEnum.valueOf(resourceType);
385 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic
386 .validateResourceNameExists(resourceName, typeEnum, userId);
387 if (actionResponse.isRight()) {
388 log.debug("failed to validate resource name");
389 response = buildErrorResponse(actionResponse.right().value());
392 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
396 @Path("/resources/certified/abstract")
397 @Consumes(MediaType.APPLICATION_JSON)
398 @Produces(MediaType.APPLICATION_JSON)
399 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
400 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request,
401 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
402 String url = request.getMethod() + " " + request.getRequestURI();
403 log.debug("(get) Start handle request of {}", url);
405 List<Resource> resources = resourceBusinessLogic.getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
406 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
407 } catch (IOException e) {
408 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
409 log.debug("getCertifiedAbstractResources failed with exception", e);
415 @Path("/resources/certified/notabstract")
416 @Consumes(MediaType.APPLICATION_JSON)
417 @Produces(MediaType.APPLICATION_JSON)
418 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
419 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request,
420 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
421 String url = request.getMethod() + " " + request.getRequestURI();
422 log.debug("(get) Start handle request of {}", url);
424 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
425 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
426 } catch (IOException e) {
427 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
428 log.debug("getCertifiedNotAbstractResources failed with exception", e);
434 @Path("/resources/{resourceId}/metadata")
435 @Consumes(MediaType.APPLICATION_JSON)
436 @Produces(MediaType.APPLICATION_JSON)
437 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", responses = {
438 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
439 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
440 @ApiResponse(responseCode = "403", description = "Restricted operation"),
441 @ApiResponse(responseCode = "400", description = "Invalid content")})
442 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
443 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
444 @Parameter(description = "Resource metadata to be updated", required = true) String data,
445 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
447 String url = request.getMethod() + " " + request.getRequestURI();
448 log.debug(START_HANDLE_REQUEST_OF, url);
450 User modifier = new User();
451 modifier.setUserId(userId);
452 log.debug(MODIFIER_ID_IS, userId);
455 String resourceIdLower = resourceId.toLowerCase();
456 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils()
457 .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
458 ComponentTypeEnum.RESOURCE);
459 if (updateInfoResource.isRight()) {
460 log.debug("failed to parse resource metadata");
461 response = buildErrorResponse(updateInfoResource.right().value());
464 Resource updatedResource = resourceBusinessLogic
465 .updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
466 Object resource = RepresentationUtils.toRepresentation(updatedResource);
467 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
468 } catch (IOException e) {
469 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
470 log.debug("Update Resource Metadata failed with exception", e);
476 @Path("/resources/{resourceId}")
477 @Consumes(MediaType.APPLICATION_JSON)
478 @Produces(MediaType.APPLICATION_JSON)
479 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
480 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
481 @ApiResponse(responseCode = "200", description = "Resource updated"),
482 @ApiResponse(responseCode = "403", description = "Restricted operation"),
483 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
484 @ApiResponse(responseCode = "409", description = "Resource already exist")})
485 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
486 public Response updateResource(@Parameter(description = "Resource object to be updated", required = true) String data,
487 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
488 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
489 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
491 String url = request.getMethod() + " " + request.getRequestURI();
492 log.debug(START_HANDLE_REQUEST_OF, url);
494 User modifier = new User();
495 modifier.setUserId(userId);
496 log.debug(MODIFIER_ID_IS, userId);
497 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.STARTED, "Starting to update a resource by user {}", userId);
500 Wrapper<Response> responseWrapper = new Wrapper<>();
502 if (isUIImport(data)) {
503 performUIImport(responseWrapper, data, request, userId, resourceId);
505 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
506 if (convertResponse.isRight()) {
507 log.debug("failed to parse resource");
508 response = buildErrorResponse(convertResponse.right().value());
511 Resource updatedResource = resourceBusinessLogic
512 .validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
513 Object representation = RepresentationUtils.toRepresentation(updatedResource);
514 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
515 responseWrapper.setInnerElement(response);
517 .log(LoggerSupportabilityActions.UPDATE_RESOURCE, updatedResource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
518 "Ended update a resource by user {}", userId);
520 return responseWrapper.getInnerElement();
521 } catch (final IOException | ZipException e) {
522 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
523 log.debug("update resource failed with exception", e);
529 @Path("/resources/csar/{csaruuid}")
530 @Consumes(MediaType.APPLICATION_JSON)
531 @Produces(MediaType.APPLICATION_JSON)
532 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", responses = {
533 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
534 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
535 @ApiResponse(responseCode = "403", description = "Restricted operation"),
536 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
537 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
538 public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
539 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
541 String url = request.getMethod() + " " + request.getRequestURI();
542 log.debug(START_HANDLE_REQUEST_OF, url);
543 // retrieve user details
544 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
545 User user = new User();
546 user.setUserId(userId);
547 log.debug("user id is {}", userId);
550 Either<Resource, ResponseFormat> eitherResource = resourceBusinessLogic
551 .getLatestResourceFromCsarUuid(ValidationUtils.sanitizeInputString(csarUUID), user);
553 if (eitherResource.isRight()) {
554 log.debug("failed to get resource from csarUuid : {}", csarUUID);
555 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT), eitherResource.right().value());
557 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
558 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
561 } catch (IOException e) {
562 log.debug("get resource by csar failed with exception", e);
568 @Path("/resources/importReplaceResource")
569 @Produces(MediaType.APPLICATION_JSON)
570 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
571 @ApiResponse(responseCode = "201", description = "Resource created"),
572 @ApiResponse(responseCode = "403", description = "Restricted operation"),
573 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
574 @ApiResponse(responseCode = "409", description = "Resource already exist")})
575 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
576 public Response importReplaceResource(
577 @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
578 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
579 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
580 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
581 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
582 @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file,
583 @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
584 @Parameter(description = "resourceMetadata") @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
586 String requestURI = request.getRequestURI();
587 String url = request.getMethod() + " " + requestURI;
588 log.debug("importReplaceResource,Start handle request of {}", url);
590 User modifier = new User();
591 modifier.setUserId(userId);
592 log.debug("importReplaceResource,modifier id is {}", userId);
593 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
595 ResponseFormat responseFormat = null;
596 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
597 String assetType = "resources";
598 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
599 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
600 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
602 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
603 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
604 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
605 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, resourceCommonInfo, requestId, null);
606 return buildErrorResponse(responseFormat);
609 Wrapper<Response> responseWrapper = new Wrapper<>();
611 Wrapper<User> userWrapper = new Wrapper<>();
612 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
613 Wrapper<String> yamlStringWrapper = new Wrapper<>();
614 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
615 // PayLoad Validations
616 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
617 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
618 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(),
619 request, resourceInfoJsonString, serviceAuthorityEnum);
620 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
621 log.debug("importReplaceResource:get ResourceType:{}", uploadResourceInfoWrapper.getInnerElement().getResourceType());
622 if (responseWrapper.isEmpty()) {
623 log.debug("importReplaceService:start handleImport");
624 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
625 yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
627 return responseWrapper.getInnerElement();
628 } catch (ZipException e) {
629 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
630 log.debug("import resource failed with exception", e);
631 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));