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;
39 import javax.inject.Inject;
40 import javax.servlet.ServletContext;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.ws.rs.Consumes;
43 import javax.ws.rs.DELETE;
44 import javax.ws.rs.GET;
45 import javax.ws.rs.HeaderParam;
46 import javax.ws.rs.POST;
47 import javax.ws.rs.PUT;
48 import javax.ws.rs.Path;
49 import javax.ws.rs.PathParam;
50 import javax.ws.rs.Produces;
51 import javax.ws.rs.QueryParam;
52 import javax.ws.rs.core.Context;
53 import javax.ws.rs.core.MediaType;
54 import javax.ws.rs.core.Response;
55 import org.apache.http.HttpStatus;
56 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
57 import org.glassfish.jersey.media.multipart.FormDataParam;
58 import org.json.JSONException;
59 import org.json.JSONObject;
60 import org.keycloak.representations.AccessToken;
61 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
62 import org.openecomp.sdc.be.components.impl.CsarValidationUtils;
63 import org.openecomp.sdc.be.components.impl.ImportUtils;
64 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
65 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
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.openecomp.sdc.common.util.Multitenancy;
91 import org.springframework.stereotype.Controller;
93 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
95 @Tags({@Tag(name = "SDCE-2 APIs")})
96 @Servers({@Server(url = "/sdc2/rest")})
98 public class ResourcesServlet extends AbstractValidationsServlet {
100 private static final Logger log = Logger.getLogger(ResourcesServlet.class);
101 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourcesServlet.class.getName());
102 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
103 private static final String MODIFIER_ID_IS = "modifier id is {}";
104 private final ResourceBusinessLogic resourceBusinessLogic;
107 public ResourcesServlet(ComponentInstanceBusinessLogic componentInstanceBL,
108 ResourceBusinessLogic resourceBusinessLogic, ComponentsUtils componentsUtils, ServletUtils servletUtils,
109 ResourceImportManager resourceImportManager) {
110 super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
111 this.resourceBusinessLogic = resourceBusinessLogic;
116 @Consumes(MediaType.APPLICATION_JSON)
117 @Produces(MediaType.APPLICATION_JSON)
118 @Operation(description = "Create Resource", method = "POST", summary = "Returns created resource", responses = {
119 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
120 @ApiResponse(responseCode = "201", description = "Resource created"),
121 @ApiResponse(responseCode = "403", description = "Restricted operation"),
122 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
123 @ApiResponse(responseCode = "409", description = "Resource already exist"),
124 @ApiResponse(responseCode = "401", description = "Unauthorized Tenant")})
125 public Response createResource(@Parameter(description = "Resource object to be created", required = true) String data,
126 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
127 throws IOException, ZipException {
128 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
130 String url = request.getMethod() + " " + request.getRequestURI();
131 log.debug(START_HANDLE_REQUEST_OF, url);
133 User modifier = new User();
134 modifier.setUserId(userId);
135 log.debug(MODIFIER_ID_IS, userId);
136 loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE, StatusCode.STARTED, "Starting to create Resource by user {}", userId);
139 Wrapper<Response> responseWrapper = new Wrapper<>();
141 if (isUIImport(data)) {
142 performUIImport(responseWrapper, data, request, userId, null);
146 Either<Resource, ResponseFormat> convertResponse = parseToResource(data, modifier);
147 if (convertResponse.isRight()) {
148 log.debug("failed to parse resource");
149 response = buildErrorResponse(convertResponse.right().value());
152 Multitenancy keyaccess = new Multitenancy();
153 Resource resource = convertResponse.left().value();
154 if (keyaccess.multiTenancyCheck())
156 AccessToken.Access realmAccess = keyaccess.getAccessToken(request).getRealmAccess();
157 Set<String> realmroles = realmAccess.getRoles();
158 boolean match = realmroles.contains(resource.getTenant());
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);
165 .log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
166 "Resource successfully created user {}", userId);
168 return Response.status(401, "Unauthorized Tenant").build();
171 Resource createdResource = resourceBusinessLogic.createResource(resource, AuditingActionEnum.CREATE_RESOURCE, modifier, null, null);
172 Object representation = RepresentationUtils.toRepresentation(createdResource);
173 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
174 responseWrapper.setInnerElement(response);
176 .log(LoggerSupportabilityActions.CREATE_RESOURCE, resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
177 "Resource successfully created user {}", userId);
180 return responseWrapper.getInnerElement();
181 } catch (final IOException | ZipException e) {
182 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource");
183 log.debug("create resource failed with exception", e);
188 private boolean isUIImport(String data) {
191 JSONObject json = new JSONObject(data);
192 String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME);
193 isUIImport = payloadName != null && !payloadName.isEmpty();
194 } catch (JSONException e) {
195 log.debug("failed to parse json sent from client, json:{}", data, e);
201 private void performUIImport(final Wrapper<Response> responseWrapper, final String data, final HttpServletRequest request, final String userId,
202 final String resourceUniqueId) throws ZipException {
203 Wrapper<User> userWrapper = new Wrapper<>();
204 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
205 Wrapper<String> yamlStringWrapper = new Wrapper<>();
206 ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI;
207 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, data);
208 if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) {
209 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), data, resourceAuthorityEnum,
211 // PayLoad Validations
212 commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement());
214 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request,
215 data, resourceAuthorityEnum);
216 if (responseWrapper.isEmpty()) {
217 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
218 yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId);
222 private Either<Resource, ResponseFormat> parseToResource(String resourceJson, User user) {
223 return getComponentsUtils()
224 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
227 private Either<Resource, ResponseFormat> parseToLightResource(String resourceJson, User user) {
228 Either<Resource, ResponseFormat> ret = getComponentsUtils()
229 .convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
230 ComponentTypeEnum.RESOURCE);
231 if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow)
232 ret.left().value().setRequirements(null);
233 ret.left().value().setCapabilities(null);
239 @Path("/resources/{resourceId}")
240 public Response deleteResource(@PathParam("resourceId") final String resourceId,
241 @Parameter(description = "Optional parameter to determine the delete action: " +
242 "DELETE, which will permanently delete the Resource from the system or " +
243 "MARK_AS_DELETE, which will logically mark the Resource as deleted. Default action is to MARK_AS_DELETE")
244 @QueryParam("deleteAction") final DeleteActionEnum deleteAction,
245 @Context final HttpServletRequest request) {
246 String url = request.getMethod() + " " + request.getRequestURI();
247 log.debug(START_HANDLE_REQUEST_OF, url);
249 String userId = request.getHeader(Constants.USER_ID_HEADER);
250 User modifier = new User();
251 modifier.setUserId(userId);
252 log.debug(MODIFIER_ID_IS, userId);
253 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.STARTED, "Starting to delete Resource by user {}", userId);
255 String resourceIdLower = resourceId.toLowerCase();
256 ResponseFormat actionResponse;
257 if (DeleteActionEnum.DELETE.equals(deleteAction)) {
258 resourceBusinessLogic.deleteResourceAllVersions(resourceId, modifier);
259 actionResponse = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
261 actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
263 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
264 log.debug("failed to delete resource");
265 return buildErrorResponse(actionResponse);
268 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.COMPLETE, "Ended delete Resource by user {}", userId);
269 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
270 } catch (Exception e) {
271 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
272 log.debug("delete resource failed with exception ", e);
278 @Path("/resources/{resourceName}/{version}")
279 @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content", responses = {
280 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
281 @ApiResponse(responseCode = "204", description = "Resource deleted"),
282 @ApiResponse(responseCode = "403", description = "Restricted operation"),
283 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
284 @ApiResponse(responseCode = "404", description = "Resource not found")})
285 public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version,
286 @Context final HttpServletRequest request) {
287 ServletContext context = request.getSession().getServletContext();
288 String url = request.getMethod() + " " + request.getRequestURI();
289 log.debug(START_HANDLE_REQUEST_OF, url);
291 String userId = request.getHeader(Constants.USER_ID_HEADER);
292 User modifier = new User();
293 modifier.setUserId(userId);
294 log.debug(MODIFIER_ID_IS, userId);
296 ResourceBusinessLogic businessLogic = getResourceBL(context);
297 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
298 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
299 log.debug("failed to delete resource");
300 response = buildErrorResponse(actionResponse);
303 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
308 @Path("/resources/{resourceId}")
309 @Consumes(MediaType.APPLICATION_JSON)
310 @Produces(MediaType.APPLICATION_JSON)
311 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", responses = {
312 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
313 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
314 @ApiResponse(responseCode = "404", description = "Resource not found")})
315 public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request,
316 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
317 ServletContext context = request.getSession().getServletContext();
318 String url = request.getMethod() + " " + request.getRequestURI();
319 log.debug(START_HANDLE_REQUEST_OF, url);
321 User modifier = new User();
322 modifier.setUserId(userId);
323 log.debug(MODIFIER_ID_IS, userId);
326 String resourceIdLower = resourceId.toLowerCase();
327 log.trace("get resource with id {}", resourceId);
328 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
329 if (actionResponse.isRight()) {
330 log.debug("failed to get resource");
331 response = buildErrorResponse(actionResponse.right().value());
334 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
335 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
336 } catch (IOException e) {
337 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
338 log.debug("get resource failed with exception", e);
344 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
345 @Consumes(MediaType.APPLICATION_JSON)
346 @Produces(MediaType.APPLICATION_JSON)
347 @Operation(description = "Retrieve Resource by name and version", method = "GET", summary = "Returns resource according to resourceId", responses = {
348 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
349 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
350 @ApiResponse(responseCode = "404", description = "Resource not found")})
351 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
352 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
353 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
355 User modifier = new User();
356 modifier.setUserId(userId);
357 log.debug(MODIFIER_ID_IS, userId);
360 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic
361 .getResourceByNameAndVersion(resourceName, resourceVersion, userId);
362 if (actionResponse.isRight()) {
363 response = buildErrorResponse(actionResponse.right().value());
366 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
367 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
368 } catch (IOException e) {
369 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
370 log.debug("get resource failed with exception", e);
376 @Path("/resources/validate-name/{resourceName}")
377 @Consumes(MediaType.APPLICATION_JSON)
378 @Produces(MediaType.APPLICATION_JSON)
379 @Operation(description = "validate resource name", method = "GET", summary = "checks if the chosen resource name is available ", responses = {
380 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
381 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation")})
382 public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType,
383 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
384 String url = request.getMethod() + " " + request.getRequestURI();
385 log.debug(START_HANDLE_REQUEST_OF, url);
387 User modifier = new User();
388 modifier.setUserId(userId);
389 log.debug(MODIFIER_ID_IS, userId);
391 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
392 log.debug("invalid resource type received");
393 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
396 ResourceTypeEnum typeEnum = null;
397 if (resourceType != null) {
398 typeEnum = ResourceTypeEnum.valueOf(resourceType);
400 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic
401 .validateResourceNameExists(resourceName, typeEnum, userId);
402 if (actionResponse.isRight()) {
403 log.debug("failed to validate resource name");
404 response = buildErrorResponse(actionResponse.right().value());
407 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
411 @Path("/resources/certified/abstract")
412 @Consumes(MediaType.APPLICATION_JSON)
413 @Produces(MediaType.APPLICATION_JSON)
414 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request,
415 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
416 String url = request.getMethod() + " " + request.getRequestURI();
417 log.debug("(get) Start handle request of {}", url);
419 List<Resource> resources = resourceBusinessLogic.getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
420 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
421 } catch (IOException e) {
422 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
423 log.debug("getCertifiedAbstractResources failed with exception", e);
429 @Path("/resources/certified/notabstract")
430 @Consumes(MediaType.APPLICATION_JSON)
431 @Produces(MediaType.APPLICATION_JSON)
432 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request,
433 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
434 String url = request.getMethod() + " " + request.getRequestURI();
435 log.debug("(get) Start handle request of {}", url);
437 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
438 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
439 } catch (IOException e) {
440 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
441 log.debug("getCertifiedNotAbstractResources failed with exception", e);
447 @Path("/resources/{resourceId}/metadata")
448 @Consumes(MediaType.APPLICATION_JSON)
449 @Produces(MediaType.APPLICATION_JSON)
450 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", responses = {
451 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
452 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
453 @ApiResponse(responseCode = "403", description = "Restricted operation"),
454 @ApiResponse(responseCode = "400", description = "Invalid content")})
455 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
456 @Parameter(description = "Resource metadata to be updated", required = true) String data,
457 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
459 String url = request.getMethod() + " " + request.getRequestURI();
460 log.debug(START_HANDLE_REQUEST_OF, url);
462 User modifier = new User();
463 modifier.setUserId(userId);
464 log.debug(MODIFIER_ID_IS, userId);
467 String resourceIdLower = resourceId.toLowerCase();
468 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils()
469 .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
470 ComponentTypeEnum.RESOURCE);
471 if (updateInfoResource.isRight()) {
472 log.debug("failed to parse resource metadata");
473 response = buildErrorResponse(updateInfoResource.right().value());
476 Resource updatedResource = resourceBusinessLogic
477 .updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
478 Object resource = RepresentationUtils.toRepresentation(updatedResource);
479 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
480 } catch (IOException e) {
481 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
482 log.debug("Update Resource Metadata failed with exception", e);
488 @Path("/resources/{resourceId}")
489 @Consumes(MediaType.APPLICATION_JSON)
490 @Produces(MediaType.APPLICATION_JSON)
491 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
492 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
493 @ApiResponse(responseCode = "200", description = "Resource updated"),
494 @ApiResponse(responseCode = "403", description = "Restricted operation"),
495 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
496 @ApiResponse(responseCode = "409", description = "Resource already exist")})
497 public Response updateResource(@Parameter(description = "Resource object to be updated", required = true) String data,
498 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
499 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
500 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
502 String url = request.getMethod() + " " + request.getRequestURI();
503 log.debug(START_HANDLE_REQUEST_OF, url);
505 User modifier = new User();
506 modifier.setUserId(userId);
507 log.debug(MODIFIER_ID_IS, userId);
508 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.STARTED, "Starting to update a resource by user {}", userId);
511 Wrapper<Response> responseWrapper = new Wrapper<>();
513 if (isUIImport(data)) {
514 performUIImport(responseWrapper, data, request, userId, resourceId);
516 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
517 if (convertResponse.isRight()) {
518 log.debug("failed to parse resource");
519 response = buildErrorResponse(convertResponse.right().value());
522 Resource updatedResource = resourceBusinessLogic
523 .validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
524 Object representation = RepresentationUtils.toRepresentation(updatedResource);
525 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
526 responseWrapper.setInnerElement(response);
528 .log(LoggerSupportabilityActions.UPDATE_RESOURCE, updatedResource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
529 "Ended update a resource by user {}", userId);
531 return responseWrapper.getInnerElement();
532 } catch (final IOException | ZipException e) {
533 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
534 log.debug("update resource failed with exception", e);
540 @Path("/resources/csar/{csaruuid}")
541 @Consumes(MediaType.APPLICATION_JSON)
542 @Produces(MediaType.APPLICATION_JSON)
543 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", responses = {
544 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
545 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
546 @ApiResponse(responseCode = "403", description = "Restricted operation"),
547 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
548 public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
549 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
551 String url = request.getMethod() + " " + request.getRequestURI();
552 log.debug(START_HANDLE_REQUEST_OF, url);
553 // retrieve user details
554 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
555 User user = new User();
556 user.setUserId(userId);
557 log.debug("user id is {}", userId);
560 Either<Resource, ResponseFormat> eitherResource = resourceBusinessLogic
561 .getLatestResourceFromCsarUuid(ValidationUtils.sanitizeInputString(csarUUID), user);
563 if (eitherResource.isRight()) {
564 log.debug("failed to get resource from csarUuid : {}", csarUUID);
565 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT), eitherResource.right().value());
567 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
568 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
571 } catch (IOException e) {
572 log.debug("get resource by csar failed with exception", e);
578 @Path("/resources/importReplaceResource")
579 @Produces(MediaType.APPLICATION_JSON)
580 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
581 @ApiResponse(responseCode = "201", description = "Resource created"),
582 @ApiResponse(responseCode = "403", description = "Restricted operation"),
583 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
584 @ApiResponse(responseCode = "409", description = "Resource already exist")})
585 public Response importReplaceResource(
586 @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
587 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
588 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
589 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
590 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
591 @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file,
592 @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
593 @Parameter(description = "resourceMetadata") @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
595 String requestURI = request.getRequestURI();
596 String url = request.getMethod() + " " + requestURI;
597 log.debug("importReplaceResource,Start handle request of {}", url);
599 User modifier = new User();
600 modifier.setUserId(userId);
601 log.debug("importReplaceResource,modifier id is {}", userId);
602 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
604 ResponseFormat responseFormat = null;
605 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
606 String assetType = "resources";
607 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
608 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
609 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
611 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
612 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
613 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
614 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, resourceCommonInfo, requestId, null);
615 return buildErrorResponse(responseFormat);
618 Wrapper<Response> responseWrapper = new Wrapper<>();
620 Wrapper<User> userWrapper = new Wrapper<>();
621 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
622 Wrapper<String> yamlStringWrapper = new Wrapper<>();
623 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
624 // PayLoad Validations
625 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
626 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
627 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(),
628 request, resourceInfoJsonString, serviceAuthorityEnum);
629 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
630 log.debug("importReplaceResource:get ResourceType:{}", uploadResourceInfoWrapper.getInnerElement().getResourceType());
631 if (responseWrapper.isEmpty()) {
632 log.debug("importReplaceService:start handleImport");
633 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
634 yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
636 return responseWrapper.getInnerElement();
637 } catch (ZipException e) {
638 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
639 log.debug("import resource failed with exception", e);
640 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));