2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2021 Nordix Foundation. 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
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.servlets;
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.tags.Tag;
31 import io.swagger.v3.oas.annotations.tags.Tags;
32 import java.io.IOException;
33 import java.util.Optional;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.ws.rs.Consumes;
36 import javax.ws.rs.HeaderParam;
37 import javax.ws.rs.PUT;
38 import javax.ws.rs.Path;
39 import javax.ws.rs.PathParam;
40 import javax.ws.rs.Produces;
41 import javax.ws.rs.core.Context;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.Response;
44 import org.apache.commons.io.IOUtils;
45 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
46 import org.openecomp.sdc.be.components.impl.ComponentInterfaceOperationBusinessLogic;
47 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
48 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
49 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
50 import org.openecomp.sdc.be.config.BeEcompErrorManager;
51 import org.openecomp.sdc.be.dao.api.ActionStatus;
52 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
53 import org.openecomp.sdc.be.impl.ComponentsUtils;
54 import org.openecomp.sdc.be.impl.ServletUtils;
55 import org.openecomp.sdc.be.model.ComponentInstance;
56 import org.openecomp.sdc.be.model.InterfaceDefinition;
57 import org.openecomp.sdc.be.model.User;
58 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
59 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
60 import org.openecomp.sdc.be.user.UserBusinessLogic;
61 import org.openecomp.sdc.common.api.Constants;
62 import org.openecomp.sdc.common.datastructure.Wrapper;
63 import org.openecomp.sdc.exception.ResponseFormat;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.stereotype.Controller;
69 @Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/interfaceOperation")
70 @Tags({@Tag(name = "SDCE-2 APIs")})
71 @Consumes(MediaType.APPLICATION_JSON)
72 @Produces(MediaType.APPLICATION_JSON)
74 public class ComponentInterfaceOperationServlet extends AbstractValidationsServlet {
76 private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationServlet.class);
77 private static final String START_HANDLE_REQUEST_OF = "Start handle {} request of {}";
78 private static final String MODIFIER_ID_IS = "modifier id is {}";
79 private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION = "failed to update Interface Operation on component instance {}";
80 private static final String UPDATE_INTERFACE_OPERATION = "Update Interface Operation on Component Instance";
81 private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR = "Failed to update Interface Operation with an error";
82 private static final String INTERFACE_OPERATION_CONTENT_INVALID = "Interface Operation content is invalid - {}";
83 private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
84 private static final String INTERFACE_OPERATION_SUCCESSFULLY_UPDATED = "Interface Operation successfully updated on component instance with id {}";
85 private final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic;
88 public ComponentInterfaceOperationServlet(final UserBusinessLogic userBusinessLogic, final ComponentInstanceBusinessLogic componentInstanceBL,
89 final ComponentsUtils componentsUtils, final ServletUtils servletUtils,
90 final ResourceImportManager resourceImportManager,
91 final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic) {
92 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
93 this.componentInterfaceOperationBusinessLogic = componentInterfaceOperationBusinessLogic;
97 @Consumes(MediaType.APPLICATION_JSON)
98 @Produces(MediaType.APPLICATION_JSON)
99 @Operation(description = "Update Interface Operation", method = "PUT", summary = "Update Interface Operation on ComponentInstance", responses = {
100 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
101 @ApiResponse(responseCode = "201", description = "Update Interface Operation"),
102 @ApiResponse(responseCode = "403", description = "Restricted operation"),
103 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
104 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
105 public Response updateComponentInstanceInterfaceOperation(
106 @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
107 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType,
108 @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
109 @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
110 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
111 LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
112 LOGGER.debug(MODIFIER_ID_IS, userId);
113 final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
114 final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
115 if (componentTypeEnum == null) {
116 LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType);
117 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
119 final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
120 if (bytes == null || bytes.length == 0) {
121 LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID);
122 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
124 final String data = new String(bytes);
125 final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum);
126 if (mappedInterfaceOperationData.isEmpty()) {
127 LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
128 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
130 final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
132 final Optional<ComponentInstance> actionResponse = componentInterfaceOperationBusinessLogic
133 .updateComponentInstanceInterfaceOperation(componentId, componentInstanceId, mappedInterfaceOperationData.get(), componentTypeEnum,
135 final Response response;
136 if (actionResponse.isEmpty()) {
137 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentInstanceId);
138 response = buildErrorResponse(errorWrapper.getInnerElement());
140 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentInstanceId);
141 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
144 } catch (final Exception e) {
145 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
146 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
147 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
151 private Optional<InterfaceDefinition> getMappedInterfaceData(final String inputJson, final User user, final ComponentTypeEnum componentTypeEnum) {
152 final Either<UiComponentDataTransfer, ResponseFormat> uiComponentEither = getComponentsUtils()
153 .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
155 return uiComponentEither.left().value().getInterfaces().values().stream().findFirst();