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.ResourceTypeEnum;
71 import org.openecomp.sdc.be.impl.ComponentsUtils;
72 import org.openecomp.sdc.be.impl.ServletUtils;
73 import org.openecomp.sdc.be.model.Resource;
74 import org.openecomp.sdc.be.model.UploadResourceInfo;
75 import org.openecomp.sdc.be.model.User;
76 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
77 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
78 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
79 import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum;
80 import org.openecomp.sdc.be.user.UserBusinessLogic;
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(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL,
107 ResourceBusinessLogic resourceBusinessLogic, ComponentsUtils componentsUtils, ServletUtils servletUtils,
108 ResourceImportManager resourceImportManager) {
109 super(userBusinessLogic, 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, @Context final HttpServletRequest request) {
222 String url = request.getMethod() + " " + request.getRequestURI();
223 log.debug(START_HANDLE_REQUEST_OF, url);
225 String userId = request.getHeader(Constants.USER_ID_HEADER);
226 User modifier = new User();
227 modifier.setUserId(userId);
228 log.debug(MODIFIER_ID_IS, userId);
229 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.STARTED, "Starting to delete Resource by user {}", userId);
232 String resourceIdLower = resourceId.toLowerCase();
233 ResponseFormat actionResponse = resourceBusinessLogic.deleteResource(resourceIdLower, modifier);
234 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
235 log.debug("failed to delete resource");
236 response = buildErrorResponse(actionResponse);
239 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
240 loggerSupportability.log(LoggerSupportabilityActions.DELETE_RESOURCE, StatusCode.COMPLETE, "Ended delete Resource by user {}", userId);
242 } catch (JSONException e) {
243 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");
244 log.debug("delete resource failed with exception", e);
250 @Path("/resources/{resourceName}/{version}")
251 @Operation(description = "Delete Resource By Name And Version", method = "DELETE", summary = "Returns no content", responses = {
252 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
253 @ApiResponse(responseCode = "204", description = "Resource deleted"),
254 @ApiResponse(responseCode = "403", description = "Restricted operation"),
255 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
256 @ApiResponse(responseCode = "404", description = "Resource not found")})
257 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
258 public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version,
259 @Context final HttpServletRequest request) {
260 ServletContext context = request.getSession().getServletContext();
261 String url = request.getMethod() + " " + request.getRequestURI();
262 log.debug(START_HANDLE_REQUEST_OF, url);
264 String userId = request.getHeader(Constants.USER_ID_HEADER);
265 User modifier = new User();
266 modifier.setUserId(userId);
267 log.debug(MODIFIER_ID_IS, userId);
269 ResourceBusinessLogic businessLogic = getResourceBL(context);
270 ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier);
271 if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) {
272 log.debug("failed to delete resource");
273 response = buildErrorResponse(actionResponse);
276 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null);
281 @Path("/resources/{resourceId}")
282 @Consumes(MediaType.APPLICATION_JSON)
283 @Produces(MediaType.APPLICATION_JSON)
284 @Operation(description = "Retrieve Resource", method = "GET", summary = "Returns resource according to resourceId", responses = {
285 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
286 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
287 @ApiResponse(responseCode = "404", description = "Resource not found")})
288 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
289 public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request,
290 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
291 ServletContext context = request.getSession().getServletContext();
292 String url = request.getMethod() + " " + request.getRequestURI();
293 log.debug(START_HANDLE_REQUEST_OF, url);
295 User modifier = new User();
296 modifier.setUserId(userId);
297 log.debug(MODIFIER_ID_IS, userId);
300 String resourceIdLower = resourceId.toLowerCase();
301 log.trace("get resource with id {}", resourceId);
302 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic.getResource(resourceIdLower, modifier);
303 if (actionResponse.isRight()) {
304 log.debug("failed to get resource");
305 response = buildErrorResponse(actionResponse.right().value());
308 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
309 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
310 } catch (IOException e) {
311 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource");
312 log.debug("get resource failed with exception", e);
318 @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}")
319 @Consumes(MediaType.APPLICATION_JSON)
320 @Produces(MediaType.APPLICATION_JSON)
321 @Operation(description = "Retrieve Resource by name and version", method = "GET", summary = "Returns resource according to resourceId", responses = {
322 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
323 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
324 @ApiResponse(responseCode = "404", description = "Resource not found")})
325 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
326 public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName,
327 @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request,
328 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
330 User modifier = new User();
331 modifier.setUserId(userId);
332 log.debug(MODIFIER_ID_IS, userId);
335 Either<Resource, ResponseFormat> actionResponse = resourceBusinessLogic
336 .getResourceByNameAndVersion(resourceName, resourceVersion, userId);
337 if (actionResponse.isRight()) {
338 response = buildErrorResponse(actionResponse.right().value());
341 Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value());
342 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
343 } catch (IOException e) {
344 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version");
345 log.debug("get resource failed with exception", e);
351 @Path("/resources/validate-name/{resourceName}")
352 @Consumes(MediaType.APPLICATION_JSON)
353 @Produces(MediaType.APPLICATION_JSON)
354 @Operation(description = "validate resource name", method = "GET", summary = "checks if the chosen resource name is available ", responses = {
355 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
356 @ApiResponse(responseCode = "200", description = "Resource found"), @ApiResponse(responseCode = "403", description = "Restricted operation")})
357 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
358 public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType,
359 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
360 String url = request.getMethod() + " " + request.getRequestURI();
361 log.debug(START_HANDLE_REQUEST_OF, url);
363 User modifier = new User();
364 modifier.setUserId(userId);
365 log.debug(MODIFIER_ID_IS, userId);
367 if (resourceType != null && !ResourceTypeEnum.containsName(resourceType)) {
368 log.debug("invalid resource type received");
369 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
372 ResourceTypeEnum typeEnum = null;
373 if (resourceType != null) {
374 typeEnum = ResourceTypeEnum.valueOf(resourceType);
376 Either<Map<String, Boolean>, ResponseFormat> actionResponse = resourceBusinessLogic
377 .validateResourceNameExists(resourceName, typeEnum, userId);
378 if (actionResponse.isRight()) {
379 log.debug("failed to validate resource name");
380 response = buildErrorResponse(actionResponse.right().value());
383 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
387 @Path("/resources/certified/abstract")
388 @Consumes(MediaType.APPLICATION_JSON)
389 @Produces(MediaType.APPLICATION_JSON)
390 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
391 public Response getCertifiedAbstractResources(@Context final HttpServletRequest request,
392 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
393 String url = request.getMethod() + " " + request.getRequestURI();
394 log.debug("(get) Start handle request of {}", url);
396 List<Resource> resources = resourceBusinessLogic.getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId);
397 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resources));
398 } catch (IOException e) {
399 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources");
400 log.debug("getCertifiedAbstractResources failed with exception", e);
406 @Path("/resources/certified/notabstract")
407 @Consumes(MediaType.APPLICATION_JSON)
408 @Produces(MediaType.APPLICATION_JSON)
409 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
410 public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request,
411 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
412 String url = request.getMethod() + " " + request.getRequestURI();
413 log.debug("(get) Start handle request of {}", url);
415 List<Resource> resouces = resourceBusinessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId);
416 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toRepresentation(resouces));
417 } catch (IOException e) {
418 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources");
419 log.debug("getCertifiedNotAbstractResources failed with exception", e);
425 @Path("/resources/{resourceId}/metadata")
426 @Consumes(MediaType.APPLICATION_JSON)
427 @Produces(MediaType.APPLICATION_JSON)
428 @Operation(description = "Update Resource Metadata", method = "PUT", summary = "Returns updated resource metadata", responses = {
429 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
430 @ApiResponse(responseCode = "200", description = "Resource metadata updated"),
431 @ApiResponse(responseCode = "403", description = "Restricted operation"),
432 @ApiResponse(responseCode = "400", description = "Invalid content")})
433 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
434 public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId,
435 @Parameter(description = "Resource metadata to be updated", required = true) String data,
436 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
438 String url = request.getMethod() + " " + request.getRequestURI();
439 log.debug(START_HANDLE_REQUEST_OF, url);
441 User modifier = new User();
442 modifier.setUserId(userId);
443 log.debug(MODIFIER_ID_IS, userId);
446 String resourceIdLower = resourceId.toLowerCase();
447 Either<Resource, ResponseFormat> updateInfoResource = getComponentsUtils()
448 .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
449 ComponentTypeEnum.RESOURCE);
450 if (updateInfoResource.isRight()) {
451 log.debug("failed to parse resource metadata");
452 response = buildErrorResponse(updateInfoResource.right().value());
455 Resource updatedResource = resourceBusinessLogic
456 .updateResourceMetadata(resourceIdLower, updateInfoResource.left().value(), null, modifier, false);
457 Object resource = RepresentationUtils.toRepresentation(updatedResource);
458 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource);
459 } catch (IOException e) {
460 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata");
461 log.debug("Update Resource Metadata failed with exception", e);
467 @Path("/resources/{resourceId}")
468 @Consumes(MediaType.APPLICATION_JSON)
469 @Produces(MediaType.APPLICATION_JSON)
470 @Operation(description = "Update Resource", method = "PUT", summary = "Returns updated resource", responses = {
471 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
472 @ApiResponse(responseCode = "200", description = "Resource updated"),
473 @ApiResponse(responseCode = "403", description = "Restricted operation"),
474 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
475 @ApiResponse(responseCode = "409", description = "Resource already exist")})
476 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
477 public Response updateResource(@Parameter(description = "Resource object to be updated", required = true) String data,
478 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
479 @PathParam(value = "resourceId") String resourceId) throws IOException, ZipException {
480 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
482 String url = request.getMethod() + " " + request.getRequestURI();
483 log.debug(START_HANDLE_REQUEST_OF, url);
485 User modifier = new User();
486 modifier.setUserId(userId);
487 log.debug(MODIFIER_ID_IS, userId);
488 loggerSupportability.log(LoggerSupportabilityActions.UPDATE_RESOURCE, StatusCode.STARTED, "Starting to update a resource by user {}", userId);
491 Wrapper<Response> responseWrapper = new Wrapper<>();
493 if (isUIImport(data)) {
494 performUIImport(responseWrapper, data, request, userId, resourceId);
496 Either<Resource, ResponseFormat> convertResponse = parseToLightResource(data, modifier);
497 if (convertResponse.isRight()) {
498 log.debug("failed to parse resource");
499 response = buildErrorResponse(convertResponse.right().value());
502 Resource updatedResource = resourceBusinessLogic
503 .validateAndUpdateResourceFromCsar(convertResponse.left().value(), modifier, null, null, resourceId);
504 Object representation = RepresentationUtils.toRepresentation(updatedResource);
505 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
506 responseWrapper.setInnerElement(response);
508 .log(LoggerSupportabilityActions.UPDATE_RESOURCE, updatedResource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,
509 "Ended update a resource by user {}", userId);
511 return responseWrapper.getInnerElement();
512 } catch (final IOException | ZipException e) {
513 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource");
514 log.debug("update resource failed with exception", e);
520 @Path("/resources/csar/{csaruuid}")
521 @Consumes(MediaType.APPLICATION_JSON)
522 @Produces(MediaType.APPLICATION_JSON)
523 @Operation(description = "Create Resource", method = "POST", summary = "Returns resource created from csar uuid", responses = {
524 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
525 @ApiResponse(responseCode = "201", description = "Resource retrieced"),
526 @ApiResponse(responseCode = "403", description = "Restricted operation"),
527 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
528 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
529 public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
530 @PathParam(value = "csaruuid") String csarUUID) throws IOException {
532 String url = request.getMethod() + " " + request.getRequestURI();
533 log.debug(START_HANDLE_REQUEST_OF, url);
534 // retrieve user details
535 userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER);
536 User user = new User();
537 user.setUserId(userId);
538 log.debug("user id is {}", userId);
541 Either<Resource, ResponseFormat> eitherResource = resourceBusinessLogic
542 .getLatestResourceFromCsarUuid(ValidationUtils.sanitizeInputString(csarUUID), user);
544 if (eitherResource.isRight()) {
545 log.debug("failed to get resource from csarUuid : {}", csarUUID);
546 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT), eitherResource.right().value());
548 Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value());
549 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation);
552 } catch (IOException e) {
553 log.debug("get resource by csar failed with exception", e);
559 @Path("/resources/importReplaceResource")
560 @Produces(MediaType.APPLICATION_JSON)
561 @Operation(description = "Import Resource", method = "POST", summary = "Returns imported resource", responses = {
562 @ApiResponse(responseCode = "201", description = "Resource created"),
563 @ApiResponse(responseCode = "403", description = "Restricted operation"),
564 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
565 @ApiResponse(responseCode = "409", description = "Resource already exist")})
566 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
567 public Response importReplaceResource(
568 @Parameter(description = "The user id", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
569 @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
570 @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
571 @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
572 @Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
573 @Context final HttpServletRequest request, @Parameter(description = "FileInputStream") @FormDataParam("resourceZip") File file,
574 @Parameter(description = "ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader,
575 @Parameter(description = "resourceMetadata") @FormDataParam("resourceZipMetadata") String resourceInfoJsonString) {
577 String requestURI = request.getRequestURI();
578 String url = request.getMethod() + " " + requestURI;
579 log.debug("importReplaceResource,Start handle request of {}", url);
581 User modifier = new User();
582 modifier.setUserId(userId);
583 log.debug("importReplaceResource,modifier id is {}", userId);
584 log.debug("importReplaceResource,get file:{},fileName:{}", file, file.getName());
586 ResponseFormat responseFormat = null;
587 AuditingActionEnum auditingActionEnum = AuditingActionEnum.Import_Replace_Resource;
588 String assetType = "resources";
589 ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
590 ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
591 DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
593 if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
594 log.debug("importReplaceResource: Missing X-ECOMP-InstanceID header");
595 responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
596 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData, resourceCommonInfo, requestId, null);
597 return buildErrorResponse(responseFormat);
600 Wrapper<Response> responseWrapper = new Wrapper<>();
602 Wrapper<User> userWrapper = new Wrapper<>();
603 Wrapper<UploadResourceInfo> uploadResourceInfoWrapper = new Wrapper<>();
604 Wrapper<String> yamlStringWrapper = new Wrapper<>();
605 ResourceAuthorityTypeEnum serviceAuthorityEnum = ResourceAuthorityTypeEnum.CSAR_TYPE_BE;
606 // PayLoad Validations
607 commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, serviceAuthorityEnum, userId, resourceInfoJsonString);
608 fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, modifier, resourceInfoJsonString, serviceAuthorityEnum, file);
609 specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(),
610 request, resourceInfoJsonString, serviceAuthorityEnum);
611 log.debug("importReplaceResource:get payload:{}", uploadResourceInfoWrapper.getInnerElement().getPayloadData());
612 log.debug("importReplaceResource:get ResourceType:{}", uploadResourceInfoWrapper.getInnerElement().getResourceType());
613 if (responseWrapper.isEmpty()) {
614 log.debug("importReplaceService:start handleImport");
615 handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(),
616 yamlStringWrapper.getInnerElement(), serviceAuthorityEnum, true, null);
618 return responseWrapper.getInnerElement();
619 } catch (ZipException e) {
620 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Import Resource");
621 log.debug("import resource failed with exception", e);
622 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));