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