Publish swagger files for SDC APIs
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ComponentInterfaceOperationServlet.java
1 /*
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
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.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdc.be.servlets;
23
24 import fj.data.Either;
25 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.media.ArraySchema;
28 import io.swagger.v3.oas.annotations.media.Content;
29 import io.swagger.v3.oas.annotations.media.Schema;
30 import io.swagger.v3.oas.annotations.responses.ApiResponse;
31 import io.swagger.v3.oas.annotations.tags.Tag;
32 import io.swagger.v3.oas.annotations.tags.Tags;
33 import java.io.IOException;
34 import java.util.Optional;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.ws.rs.Consumes;
37 import javax.ws.rs.HeaderParam;
38 import javax.ws.rs.PUT;
39 import javax.ws.rs.Path;
40 import javax.ws.rs.PathParam;
41 import javax.ws.rs.Produces;
42 import javax.ws.rs.core.Context;
43 import javax.ws.rs.core.MediaType;
44 import javax.ws.rs.core.Response;
45 import org.apache.commons.io.IOUtils;
46 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
47 import org.openecomp.sdc.be.components.impl.ComponentInterfaceOperationBusinessLogic;
48 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
49 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
50 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
51 import org.openecomp.sdc.be.config.BeEcompErrorManager;
52 import org.openecomp.sdc.be.dao.api.ActionStatus;
53 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
54 import org.openecomp.sdc.be.impl.ComponentsUtils;
55 import org.openecomp.sdc.be.impl.ServletUtils;
56 import org.openecomp.sdc.be.model.ComponentInstance;
57 import org.openecomp.sdc.be.model.InterfaceDefinition;
58 import org.openecomp.sdc.be.model.User;
59 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
60 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
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.exception.ResponseFormat;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67 import org.springframework.beans.factory.annotation.Autowired;
68 import org.springframework.stereotype.Controller;
69
70 @Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/interfaceOperation")
71 @Tags({@Tag(name = "SDCE-2 APIs")})
72 @Consumes(MediaType.APPLICATION_JSON)
73 @Produces(MediaType.APPLICATION_JSON)
74 @Controller
75 public class ComponentInterfaceOperationServlet extends AbstractValidationsServlet {
76
77     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationServlet.class);
78     private static final String START_HANDLE_REQUEST_OF = "Start handle {} request of {}";
79     private static final String MODIFIER_ID_IS = "modifier id is {}";
80
81     private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION =
82         "failed to update Interface Operation on component instance {}";
83     private static final String UPDATE_INTERFACE_OPERATION = "Update Interface Operation on Component Instance";
84     private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR =
85         "Failed to update Interface Operation with an error";
86     private static final String INTERFACE_OPERATION_CONTENT_INVALID = "Interface Operation content is invalid - {}";
87     private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
88     private static final String INTERFACE_OPERATION_SUCCESSFULLY_UPDATED =
89         "Interface Operation successfully updated on component instance with id {}";
90
91     private final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic;
92
93     @Autowired
94     public ComponentInterfaceOperationServlet(final UserBusinessLogic userBusinessLogic,
95                                               final ComponentInstanceBusinessLogic componentInstanceBL,
96                                               final ComponentsUtils componentsUtils,
97                                               final ServletUtils servletUtils,
98                                               final ResourceImportManager resourceImportManager,
99                                               final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic) {
100         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
101         this.componentInterfaceOperationBusinessLogic = componentInterfaceOperationBusinessLogic;
102     }
103
104     @PUT
105     @Consumes(MediaType.APPLICATION_JSON)
106     @Produces(MediaType.APPLICATION_JSON)
107     @Operation(description = "Update Interface Operation", method = "PUT",
108         summary = "Update Interface Operation on ComponentInstance", responses = {
109         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
110         @ApiResponse(responseCode = "201", description = "Update Interface Operation"),
111         @ApiResponse(responseCode = "403", description = "Restricted operation"),
112         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
113     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
114     public Response updateComponentInstanceInterfaceOperation(
115         @Parameter(description = "valid values: resources / services",
116             schema = @Schema(allowableValues = {
117                 ComponentTypeEnum.RESOURCE_PARAM_NAME,
118                 ComponentTypeEnum.SERVICE_PARAM_NAME}))
119         @PathParam("componentType") final String componentType,
120         @Parameter(description = "Component Id")
121         @PathParam("componentId") String componentId,
122         @Parameter(description = "Component Instance Id")
123         @PathParam("componentInstanceId") String componentInstanceId,
124         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId)
125         throws IOException {
126
127         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
128         LOGGER.debug(MODIFIER_ID_IS, userId);
129
130         final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
131         final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
132         if (componentTypeEnum == null) {
133             LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType);
134             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
135         }
136
137         final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
138         if (bytes == null || bytes.length == 0) {
139             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID);
140             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
141         }
142         final String data = new String(bytes);
143
144         final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum);
145         if (mappedInterfaceOperationData.isEmpty()) {
146             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
147             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
148         }
149         final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
150         try {
151              final Optional<ComponentInstance> actionResponse = componentInterfaceOperationBusinessLogic
152                 .updateComponentInstanceInterfaceOperation(componentId, componentInstanceId, mappedInterfaceOperationData.get(),
153                     componentTypeEnum, errorWrapper, true);
154
155             final Response response;
156             if (actionResponse.isEmpty()) {
157                 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentInstanceId);
158                 response = buildErrorResponse(errorWrapper.getInnerElement());
159             } else {
160                 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentInstanceId);
161                 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
162             }
163
164             return response;
165
166         } catch (final Exception e) {
167             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
168             LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
169             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
170         }
171     }
172
173     private Optional<InterfaceDefinition> getMappedInterfaceData(final String inputJson,
174                                                                  final User user,
175                                                                  final ComponentTypeEnum componentTypeEnum) {
176         final Either<UiComponentDataTransfer, ResponseFormat> uiComponentEither =
177             getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user,
178                 UiComponentDataTransfer.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, componentTypeEnum);
179         return uiComponentEither.left().value().getInterfaces().values().stream().findFirst();
180     }
181
182 }