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;
34 import org.apache.http.HttpStatus;
35 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
36 import org.glassfish.jersey.media.multipart.FormDataParam;
37 import org.json.JSONException;
38 import org.json.JSONObject;
39 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
40 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
41 import org.openecomp.sdc.be.components.impl.ImportUtils;
42 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
43 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
44 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
45 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
46 import org.openecomp.sdc.be.config.BeEcompErrorManager;
47 import org.openecomp.sdc.be.dao.api.ActionStatus;
48 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.DeleteActionEnum;
51 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
52 import org.openecomp.sdc.be.impl.ComponentsUtils;
53 import org.openecomp.sdc.be.impl.ServletUtils;
54 import org.openecomp.sdc.be.model.Resource;
55 import org.openecomp.sdc.be.model.UploadResourceInfo;
56 import org.openecomp.sdc.be.model.User;
57 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
58 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
59 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
60 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
61 import org.openecomp.sdc.be.user.UserBusinessLogic;
62 import org.openecomp.sdc.common.api.Constants;
63 import org.openecomp.sdc.common.datastructure.Wrapper;
64 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
65 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
66 import org.openecomp.sdc.common.log.enums.StatusCode;
67 import org.openecomp.sdc.common.log.wrappers.Logger;
68 import org.openecomp.sdc.common.util.ValidationUtils;
69 import org.openecomp.sdc.common.zip.exception.ZipException;
70 import org.openecomp.sdc.exception.ResponseFormat;
71 import org.springframework.stereotype.Controller;
73 import javax.inject.Inject;
74 import javax.servlet.ServletContext;
75 import javax.servlet.http.HttpServletRequest;
76 import javax.ws.rs.Consumes;
77 import javax.ws.rs.DELETE;
78 import javax.ws.rs.GET;
79 import javax.ws.rs.HeaderParam;
80 import javax.ws.rs.POST;
81 import javax.ws.rs.PUT;
82 import javax.ws.rs.Path;
83 import javax.ws.rs.PathParam;
84 import javax.ws.rs.Produces;
85 import javax.ws.rs.QueryParam;
86 import javax.ws.rs.core.Context;
87 import javax.ws.rs.core.MediaType;
88 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 = "SDCE-2 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, ComponentInstanceBusinessLogic componentInstanceBL,
109 ResourceBusinessLogic resourceBusinessLogic, ComponentsUtils componentsUtils, ServletUtils servletUtils,
110 ResourceImportManager resourceImportManager) {
111 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
112 this.resourceBusinessLogic = resourceBusinessLogic;
117 @Consumes(MediaType.APPLICATION_JSON)
118 @Produces(MediaType.APPLICATION_JSON)
119 @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", responses = {
120 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
121 @ApiResponse(responseCode = "201", description = "Resource created"),
122 @ApiResponse(responseCode = "403", description = "Restricted operation"),
123 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
124 @ApiResponse(responseCode = "409", description = "Resource already exist")})
125 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
126 public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
127 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
128 throws IOException, ZipException {
129 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
131 String url = request.getMethod() + " " + request.getRequestURI();
132 log.debug(START_HANDLE_REQUEST_OF, url);
134 User modifier = new User();
135 modifier.setUserId(userId);
136 log.debug(MODIFIER_ID_IS, userId);
137 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED, "Starting to create Resource by user {}", userId);
140 Wrapper<Response> responseWrapper = new Wrapper<>();
142 if (isUIImport(data)) {
143 performUIImport(responseWrapper, data, request, userId, null);
147 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
148 if (convertResponse.isRight()) {
149 log.debug("failed to parse resource");
150 response = buildErrorResponse(convertResponse.right().value());
153 Resource resource = convertResponse.left().value();
154 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
155 Object representation = RepresentationUtils.toRepresentation(createdResource);
156 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
157 responseWrapper.setInnerElement(response);
159 .log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
160 "Resource successfully created user {}", userId);
162 return responseWrapper.getInnerElement();
163 } catch (final IOException | ZipException e) {
164 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
165 log.debug("create resource failed with exception", e);
170 private boolean isUIImport(String data) {
173 JSONObject json = new JSONObject(data);
174 String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
175 isUIImport = payloadName != null && !payloadName.isEmpty();
176 } catch (JSONException e) {
177 log.debug("failed to parse json sent from client, json:{}", data, e);
183 private void performUIImport(final Wrapper<Response> responseWrapper, final String data, final HttpServletRequest request, final String userId,
184 final String resourceUniqueId) throws ZipException {
185 Wrapper<User> userWrapper = new Wrapper<>();
186 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
187 Wrapper<String> yamlStringWrapper = new Wrapper<>();
188 ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
189 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
190 if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
191 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum,
193 // PayLoad Validations
194 commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
196 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request,
197 data, resourceAuthorityEnum);
198 if (responseWrapper.isEmpty()) {
199 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
200 yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
204 private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
205 return getComponentsUtils()
206 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
209 private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
210 Either<Resource, ResponseFormat> ret = getComponentsUtils()
211 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
212 ComponentTypeEnum.RESOURCE);
213 if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
214 ret.left().value().setRequirements(null);
215 ret.left().value().setCapabilities(null);
221 @Path("/resources/{resourceId}")
222 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
223 public Response deleteResource(@PathParam("resourceId") final String resourceId,
224 @Parameter(description = "Optional parameter to determine the delete action: " +
225 "DELETE, which will permanently delete the Resource from the system or " +
226 "MARK_AS_DELETE, which will logically mark the Resource as deleted. Default action is to MARK_AS_DELETE")
227 @QueryParam("deleteAction") final DeleteActionEnum deleteAction,
228 @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);
238 String resourceIdLower = resourceId.toLowerCase();
239 ResponseFormat actionResponse;
240 if (DeleteActionEnum.DELETE.equals(deleteAction)) {
241 resourceBusinessLogic.deleteResourceAllVersions(resourceId, modifier);
242 actionResponse = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
244 actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
246 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
247 log.debug("failed to delete resource");
248 return buildErrorResponse(actionResponse);
251 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.COMPLETE, "Ended delete Resource by user {}", userId);
252 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
253 } catch (Exception e) {
254 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
255 log.debug("delete resource failed with exception ", e);
261 @Path("/resources/{resourceName}/{version}")
262 @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content", responses = {
263 @ApiResponse(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,
270 @Context final HttpServletRequest request) {
271 ServletContext context = request.getSession().getServletContext();
272 String url = request.getMethod() + " " + request.getRequestURI();
273 log.debug(START_HANDLE_REQUEST_OF, url);
275 String userId = request.getHeader(Constants.USER_ID_HEADER);
276 User modifier = new User();
277 modifier.setUserId(userId);
278 log.debug(MODIFIER_ID_IS, userId);
280 ResourceBusinessLogic businessLogic = getResourceBL(context);
281 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
282 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
283 log.debug("failed to delete resource");
284 response = buildErrorResponse(actionResponse);
287 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
292 @Path("/resources/{resourceId}")
293 @Consumes(MediaType.APPLICATION_JSON)
294 @Produces(MediaType.APPLICATION_JSON)
295 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", responses = {
296 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
297 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
298 @ApiResponse(responseCode = "404", description = "Resource not found")})
299 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
300 public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request,
301 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
302 ServletContext context = request.getSession().getServletContext();
303 String url = request.getMethod() + " " + request.getRequestURI();
304 log.debug(START_HANDLE_REQUEST_OF, url);
306 User modifier = new User();
307 modifier.setUserId(userId);
308 log.debug(MODIFIER_ID_IS, userId);
311 String resourceIdLower = resourceId.toLowerCase();
312 log.trace("get resource with id {}", resourceId);
313 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
314 if (actionResponse.isRight()) {
315 log.debug("failed to get resource");
316 response = buildErrorResponse(actionResponse.right().value());
319 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
320 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
321 } catch (IOException e) {
322 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
323 log.debug("get resource failed with exception", e);
329 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
330 @Consumes(MediaType.APPLICATION_JSON)
331 @Produces(MediaType.APPLICATION_JSON)
332 @Operation(description = "Retrieve Resource by name and version", method = "GET", summary = "Returns resource according to resourceId", responses = {
333 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
334 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
335 @ApiResponse(responseCode = "404", description = "Resource not found")})
336 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
337 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
338 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
339 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
341 User modifier = new User();
342 modifier.setUserId(userId);
343 log.debug(MODIFIER_ID_IS, userId);
346 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic
347 .getResourceByNameAndVersion(resourceName, resourceVersion, userId);
348 if (actionResponse.isRight()) {
349 response = buildErrorResponse(actionResponse.right().value());
352 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
353 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
354 } catch (IOException e) {
355 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
356 log.debug("get resource failed with exception", e);
362 @Path("/resources/validate-name/{resourceName}")
363 @Consumes(MediaType.APPLICATION_JSON)
364 @Produces(MediaType.APPLICATION_JSON)
365 @Operation(description = "validate resource name", method = "GET", summary = "checks if the chosen resource name is available ", responses = {
366 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
367 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation")})
368 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
369 public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType,
370 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
371 String url = request.getMethod() + " " + request.getRequestURI();
372 log.debug(START_HANDLE_REQUEST_OF, url);
374 User modifier = new User();
375 modifier.setUserId(userId);
376 log.debug(MODIFIER_ID_IS, userId);
378 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
379 log.debug("invalid resource type received");
380 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
383 ResourceTypeEnum typeEnum = null;
384 if (resourceType != null) {
385 typeEnum = ResourceTypeEnum.valueOf(resourceType);
387 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic
388 .validateResourceNameExists(resourceName, typeEnum, userId);
389 if (actionResponse.isRight()) {
390 log.debug("failed to validate resource name");
391 response = buildErrorResponse(actionResponse.right().value());
394 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
398 @Path("/resources/certified/abstract")
399 @Consumes(MediaType.APPLICATION_JSON)
400 @Produces(MediaType.APPLICATION_JSON)
401 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
402 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request,
403 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
404 String url = request.getMethod() + " " + request.getRequestURI();
405 log.debug("(get) Start handle request of {}", url);
407 List<Resource> resources = resourceBusinessLogic.getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
408 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
409 } catch (IOException e) {
410 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
411 log.debug("getCertifiedAbstractResources failed with exception", e);
417 @Path("/resources/certified/notabstract")
418 @Consumes(MediaType.APPLICATION_JSON)
419 @Produces(MediaType.APPLICATION_JSON)
420 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
421 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request,
422 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
423 String url = request.getMethod() + " " + request.getRequestURI();
424 log.debug("(get) Start handle request of {}", url);
426 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
427 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
428 } catch (IOException e) {
429 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
430 log.debug("getCertifiedNotAbstractResources failed with exception", e);
436 @Path("/resources/{resourceId}/metadata")
437 @Consumes(MediaType.APPLICATION_JSON)
438 @Produces(MediaType.APPLICATION_JSON)
439 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", responses = {
440 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
441 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
442 @ApiResponse(responseCode = "403", description = "Restricted operation"),
443 @ApiResponse(responseCode = "400", description = "Invalid content")})
444 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
445 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
446 @Parameter(description = "Resource metadata to be updated", required = true) String data,
447 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
449 String url = request.getMethod() + " " + request.getRequestURI();
450 log.debug(START_HANDLE_REQUEST_OF, url);
452 User modifier = new User();
453 modifier.setUserId(userId);
454 log.debug(MODIFIER_ID_IS, userId);
457 String resourceIdLower = resourceId.toLowerCase();
458 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils()
459 .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
460 ComponentTypeEnum.RESOURCE);
461 if (updateInfoResource.isRight()) {
462 log.debug("failed to parse resource metadata");
463 response = buildErrorResponse(updateInfoResource.right().value());
466 Resource updatedResource = resourceBusinessLogic
467 .updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
468 Object resource = RepresentationUtils.toRepresentation(updatedResource);
469 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
470 } catch (IOException e) {
471 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
472 log.debug("Update Resource Metadata failed with exception", e);
478 @Path("/resources/{resourceId}")
479 @Consumes(MediaType.APPLICATION_JSON)
480 @Produces(MediaType.APPLICATION_JSON)
481 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
482 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
483 @ApiResponse(responseCode = "200", description = "Resource updated"),
484 @ApiResponse(responseCode = "403", description = "Restricted operation"),
485 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
486 @ApiResponse(responseCode = "409", description = "Resource already exist")})
487 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
488 public Response updateResource(@Parameter(description = "Resource object to be updated", required = true) String data,
489 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
490 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
491 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
493 String url = request.getMethod() + " " + request.getRequestURI();
494 log.debug(START_HANDLE_REQUEST_OF, url);
496 User modifier = new User();
497 modifier.setUserId(userId);
498 log.debug(MODIFIER_ID_IS, userId);
499 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.STARTED, "Starting to update a resource by user {}", userId);
502 Wrapper<Response> responseWrapper = new Wrapper<>();
504 if (isUIImport(data)) {
505 performUIImport(responseWrapper, data, request, userId, resourceId);
507 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
508 if (convertResponse.isRight()) {
509 log.debug("failed to parse resource");
510 response = buildErrorResponse(convertResponse.right().value());
513 Resource updatedResource = resourceBusinessLogic
514 .validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
515 Object representation = RepresentationUtils.toRepresentation(updatedResource);
516 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
517 responseWrapper.setInnerElement(response);
519 .log(LoggerSupportabilityActions.UPDATE_RESOURCE, updatedResource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
520 "Ended update a resource by user {}", userId);
522 return responseWrapper.getInnerElement();
523 } catch (final IOException | ZipException e) {
524 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
525 log.debug("update resource failed with exception", e);
531 @Path("/resources/csar/{csaruuid}")
532 @Consumes(MediaType.APPLICATION_JSON)
533 @Produces(MediaType.APPLICATION_JSON)
534 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", responses = {
535 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
536 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
537 @ApiResponse(responseCode = "403", description = "Restricted operation"),
538 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
539 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
540 public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
541 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
543 String url = request.getMethod() + " " + request.getRequestURI();
544 log.debug(START_HANDLE_REQUEST_OF, url);
545 // retrieve user details
546 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
547 User user = new User();
548 user.setUserId(userId);
549 log.debug("user id is {}", userId);
552 Either<Resource, ResponseFormat> eitherResource = resourceBusinessLogic
553 .getLatestResourceFromCsarUuid(ValidationUtils.sanitizeInputString(csarUUID), user);
555 if (eitherResource.isRight()) {
556 log.debug("failed to get resource from csarUuid : {}", csarUUID);
557 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT), eitherResource.right().value());
559 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
560 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
563 } catch (IOException e) {
564 log.debug("get resource by csar failed with exception", e);
570 @Path("/resources/importReplaceResource")
571 @Produces(MediaType.APPLICATION_JSON)
572 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
573 @ApiResponse(responseCode = "201", description = "Resource created"),
574 @ApiResponse(responseCode = "403", description = "Restricted operation"),
575 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
576 @ApiResponse(responseCode = "409", description = "Resource already exist")})
577 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
578 public Response importReplaceResource(
579 @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
580 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
581 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
582 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
583 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
584 @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file,
585 @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
586 @Parameter(description = "resourceMetadata") @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
588 String requestURI = request.getRequestURI();
589 String url = request.getMethod() + " " + requestURI;
590 log.debug("importReplaceResource,Start handle request of {}", url);
592 User modifier = new User();
593 modifier.setUserId(userId);
594 log.debug("importReplaceResource,modifier id is {}", userId);
595 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
597 ResponseFormat responseFormat = null;
598 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
599 String assetType = "resources";
600 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
601 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
602 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
604 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
605 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
606 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
607 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, resourceCommonInfo, requestId, null);
608 return buildErrorResponse(responseFormat);
611 Wrapper<Response> responseWrapper = new Wrapper<>();
613 Wrapper<User> userWrapper = new Wrapper<>();
614 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
615 Wrapper<String> yamlStringWrapper = new Wrapper<>();
616 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
617 // PayLoad Validations
618 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
619 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
620 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(),
621 request, resourceInfoJsonString, serviceAuthorityEnum);
622 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
623 log.debug("importReplaceResource:get ResourceType:{}", uploadResourceInfoWrapper.getInnerElement().getResourceType());
624 if (responseWrapper.isEmpty()) {
625 log.debug("importReplaceService:start handleImport");
626 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
627 yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
629 return responseWrapper.getInnerElement();
630 } catch (ZipException e) {
631 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
632 log.debug("import resource failed with exception", e);
633 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));