Publish swagger files for SDC APIs
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / OutputsServlet.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  *
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=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import com.jcabi.aspects.Loggable;
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.servers.Server;
32 import io.swagger.v3.oas.annotations.tags.Tag;
33 import io.swagger.v3.oas.annotations.tags.Tags;
34 import java.util.List;
35 import javax.inject.Inject;
36 import javax.servlet.ServletContext;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.ws.rs.Consumes;
39 import javax.ws.rs.DELETE;
40 import javax.ws.rs.GET;
41 import javax.ws.rs.HeaderParam;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.Path;
44 import javax.ws.rs.PathParam;
45 import javax.ws.rs.Produces;
46 import javax.ws.rs.core.Context;
47 import javax.ws.rs.core.MediaType;
48 import javax.ws.rs.core.Response;
49 import org.openecomp.sdc.be.components.impl.BaseBusinessLogic;
50 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.OutputsBusinessLogic;
52 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
53 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
54 import org.openecomp.sdc.be.config.BeEcompErrorManager;
55 import org.openecomp.sdc.be.dao.api.ActionStatus;
56 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
57 import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum;
58 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
59 import org.openecomp.sdc.be.impl.ComponentsUtils;
60 import org.openecomp.sdc.be.impl.ServletUtils;
61 import org.openecomp.sdc.be.model.ComponentInstOutputsMap;
62 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
63 import org.openecomp.sdc.be.model.OutputDefinition;
64 import org.openecomp.sdc.be.model.Resource;
65 import org.openecomp.sdc.be.model.User;
66 import org.openecomp.sdc.be.user.UserBusinessLogic;
67 import org.openecomp.sdc.common.api.Constants;
68 import org.openecomp.sdc.common.log.wrappers.Logger;
69 import org.openecomp.sdc.exception.ResponseFormat;
70 import org.springframework.stereotype.Controller;
71
72 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
73 @Tags({@Tag(name = "SDCE-2 APIs")})
74 @Server(url = "/sdc2/rest")
75 @Path("/v1/catalog")
76 @Controller
77 @Consumes(MediaType.APPLICATION_JSON)
78 @Produces(MediaType.APPLICATION_JSON)
79 public class OutputsServlet extends AbstractValidationsServlet {
80
81     private static final Logger log = Logger.getLogger(OutputsServlet.class);
82     private static final String START_HANDLE_REQUEST_OF = "(get) Start handle request of {}";
83
84     private final OutputsBusinessLogic outputsBusinessLogic;
85
86     @Inject
87     public OutputsServlet(final UserBusinessLogic userBusinessLogic,
88                           final OutputsBusinessLogic outputsBusinessLogic,
89                           final ComponentInstanceBusinessLogic componentInstanceBL,
90                           final ComponentsUtils componentsUtils,
91                           final ServletUtils servletUtils,
92                           final ResourceImportManager resourceImportManager) {
93         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
94         this.outputsBusinessLogic = outputsBusinessLogic;
95     }
96
97     @GET
98     @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{originComponentUid}/outputs")
99     @Operation(description = "Get Outputs only", method = "GET", summary = "Returns Outputs list", responses = {
100         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
101         @ApiResponse(responseCode = "200", description = "Component found"),
102         @ApiResponse(responseCode = "403", description = "Restricted operation"),
103         @ApiResponse(responseCode = "404", description = "Component not found")})
104     public Response getComponentInstanceOutputs(@PathParam("componentType") final String componentType,
105                                                 @PathParam("componentId") final String componentId,
106                                                 @PathParam("instanceId") final String instanceId,
107                                                 @PathParam("originComponentUid") final String originComponentUid,
108                                                 @Context final HttpServletRequest request,
109                                                 @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) {
110
111         final String url = request.getMethod() + " " + request.getRequestURI();
112         log.debug(START_HANDLE_REQUEST_OF, url);
113
114         try {
115             final Either<List<ComponentInstanceOutput>, ResponseFormat> outputsResponse =
116                 outputsBusinessLogic.getComponentInstanceOutputs(userId, componentId, instanceId);
117             if (outputsResponse.isRight()) {
118                 log.debug("failed to get component instance outputs {}", componentType);
119                 return buildErrorResponse(outputsResponse.right().value());
120             }
121             final Object outputs = RepresentationUtils.toRepresentation(outputsResponse.left().value());
122             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), outputs);
123
124         } catch (final Exception e) {
125             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Outputs " + componentType);
126             log.debug("getOutputs failed with exception", e);
127             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
128         }
129     }
130
131     @POST
132     @Path("/{componentType}/{componentId}/create/outputs")
133     @Operation(description = "Create outputs on service", method = "POST", summary = "Return outputs list", responses = {
134         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
135         @ApiResponse(responseCode = "200", description = "Component found"),
136         @ApiResponse(responseCode = "403", description = "Restricted operation"),
137         @ApiResponse(responseCode = "404", description = "Component not found")})
138     public Response createMultipleOutputs(@PathParam("componentType") final String componentType,
139                                           @PathParam("componentId") final String componentId,
140                                           @Context final HttpServletRequest request,
141                                           @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
142                                           @Parameter(description = "ComponentIns Outputs Object to be created", required = true) final String componentInstOutputsMapObj) {
143         final String url = request.getMethod() + " " + request.getRequestURI();
144         log.debug(START_HANDLE_REQUEST_OF, url);
145
146         try {
147             return declareAttributes(userId, componentId, componentType, componentInstOutputsMapObj, DeclarationTypeEnum.OUTPUT, request);
148
149         } catch (final Exception e) {
150             BeEcompErrorManager.getInstance()
151                 .logBeRestApiGeneralError("Create outputs for service with id: " + componentId);
152             log.debug("Attributes declaration failed with exception", e);
153             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
154         }
155     }
156
157     private Response declareAttributes(final String userId,
158                                          final String componentId,
159                                          final String componentType,
160                                          final String componentInstOutputsMapObj,
161                                          final DeclarationTypeEnum typeEnum,
162                                          final HttpServletRequest request) {
163         final ServletContext context = request.getSession().getServletContext();
164         final String url = request.getMethod() + " " + request.getRequestURI();
165         log.debug(START_HANDLE_REQUEST_OF, url);
166
167         try {
168             final BaseBusinessLogic businessLogic = getBlForDeclaration(typeEnum, context);
169
170             // get modifier id
171             final User modifier = new User(userId);
172             log.debug("modifier id is {}", userId);
173             final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
174             final Either<ComponentInstOutputsMap, ResponseFormat> componentInstOutputsMapRes = parseToComponentInstanceMap(
175                 componentInstOutputsMapObj, modifier, componentTypeEnum, ComponentInstOutputsMap.class);
176             if (componentInstOutputsMapRes.isRight()) {
177                 log.debug("failed to parse componentInstOutMap");
178                 return buildErrorResponse(componentInstOutputsMapRes.right().value());
179             }
180
181             final Either<List<ToscaDataDefinition>, ResponseFormat> attributesAfterDeclaration =
182                 businessLogic.declareAttributes(userId, componentId, componentTypeEnum, componentInstOutputsMapRes.left().value());
183             if (attributesAfterDeclaration.isRight()) {
184                 log.debug("failed to create outputs  for service: {}", componentId);
185                 return buildErrorResponse(attributesAfterDeclaration.right().value());
186             }
187             final Object attributes = RepresentationUtils.toRepresentation(attributesAfterDeclaration.left().value());
188             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), attributes);
189
190         } catch (final Exception e) {
191             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create outputs for service with id: " + componentId);
192             log.debug("Attributes declaration failed with exception", e);
193             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
194         }
195     }
196
197     @DELETE
198     @Path("/{componentType}/{componentId}/delete/{outputId}/output")
199     @Operation(description = "Delete output from service", method = "DELETE", summary = "Delete service output",
200         responses = {@ApiResponse(
201             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
202             @ApiResponse(responseCode = "200", description = "Output deleted"),
203             @ApiResponse(responseCode = "403", description = "Restricted operation"),
204             @ApiResponse(responseCode = "404", description = "Output not found")})
205     public Response deleteOutput(@PathParam("componentType") final String componentType,
206                                  @PathParam("componentId") final String componentId,
207                                  @PathParam("outputId") final String outputId,
208                                  @Context final HttpServletRequest request,
209                                  @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
210                                  @Parameter(description = "Service Output to be deleted", required = true) final String componentInstOutputsMapObj) {
211
212         String url = request.getMethod() + " " + request.getRequestURI();
213         log.debug(START_HANDLE_REQUEST_OF, url);
214
215         try {
216             final OutputDefinition deleteOutput = outputsBusinessLogic.deleteOutput(componentId, userId, outputId);
217             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteOutput);
218         } catch (final ComponentException e) {
219             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete output for service + " + componentId + " + with id: " + outputId);
220             log.debug("Delete output failed with exception", e);
221             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
222         }
223     }
224
225 }