953fcda1bfe37ac2ef08c7437d253015fbd88376
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / TypesFetchServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
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 package org.openecomp.sdc.be.servlets;
21
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.tags.Tag;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.stream.Collectors;
36 import javax.inject.Inject;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.ws.rs.Consumes;
39 import javax.ws.rs.GET;
40 import javax.ws.rs.HeaderParam;
41 import javax.ws.rs.Path;
42 import javax.ws.rs.Produces;
43 import javax.ws.rs.QueryParam;
44 import javax.ws.rs.core.Context;
45 import javax.ws.rs.core.MediaType;
46 import javax.ws.rs.core.Response;
47 import org.apache.commons.collections4.ListUtils;
48 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
49 import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
50 import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
52 import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
53 import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic;
54 import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
55 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
56 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
57 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
58 import org.openecomp.sdc.be.config.BeEcompErrorManager;
59 import org.openecomp.sdc.be.dao.api.ActionStatus;
60 import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
61 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
62 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
63 import org.openecomp.sdc.be.exception.BusinessException;
64 import org.openecomp.sdc.be.impl.ComponentsUtils;
65 import org.openecomp.sdc.be.impl.ServletUtils;
66 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
67 import org.openecomp.sdc.be.model.Component;
68 import org.openecomp.sdc.be.model.DataTypeDefinition;
69 import org.openecomp.sdc.be.model.InterfaceDefinition;
70 import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
71 import org.openecomp.sdc.be.model.User;
72 import org.openecomp.sdc.common.api.Constants;
73 import org.openecomp.sdc.common.datastructure.Wrapper;
74 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
75 import org.openecomp.sdc.common.log.wrappers.Logger;
76 import org.openecomp.sdc.common.util.ValidationUtils;
77 import org.openecomp.sdc.exception.ResponseFormat;
78 import org.springframework.stereotype.Controller;
79
80 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
81 @Path("/v1/catalog")
82 @Tag(name = "SDCE-2 APIs")
83 @Server(url = "/sdc2/rest")
84 @Controller
85 public class TypesFetchServlet extends AbstractValidationsServlet {
86
87     private static final Logger log = Logger.getLogger(TypesFetchServlet.class);
88     private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}";
89     private static final String START_HANDLE_REQUEST_OF_MODIFIER_ID_IS = "Start handle request of {} | modifier id is {}";
90     private final RelationshipTypeBusinessLogic relationshipTypeBusinessLogic;
91     private final CapabilitiesBusinessLogic capabilitiesBusinessLogic;
92     private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
93     private final ResourceBusinessLogic resourceBusinessLogic;
94     private final ArtifactsBusinessLogic artifactsBusinessLogic;
95
96     @Inject
97     public TypesFetchServlet(
98         ComponentInstanceBusinessLogic componentInstanceBL,
99         ComponentsUtils componentsUtils,
100         ServletUtils servletUtils,
101         ResourceImportManager resourceImportManager,
102         RelationshipTypeBusinessLogic relationshipTypeBusinessLogic,
103         CapabilitiesBusinessLogic capabilitiesBusinessLogic,
104         InterfaceOperationBusinessLogic interfaceOperationBusinessLogic,
105         ResourceBusinessLogic resourceBusinessLogic,
106         ArtifactsBusinessLogic artifactsBusinessLogic
107     ) {
108         super(
109             componentInstanceBL,
110             componentsUtils,
111             servletUtils,
112             resourceImportManager
113         );
114         this.relationshipTypeBusinessLogic = relationshipTypeBusinessLogic;
115         this.capabilitiesBusinessLogic = capabilitiesBusinessLogic;
116         this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
117         this.resourceBusinessLogic = resourceBusinessLogic;
118         this.artifactsBusinessLogic = artifactsBusinessLogic;
119     }
120
121     @GET
122     @Path("dataTypes")
123     @Consumes(MediaType.APPLICATION_JSON)
124     @Produces(MediaType.APPLICATION_JSON)
125     @Operation(description = "Get data types", method = "GET", summary = "Returns data types", responses = {
126         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
127         @ApiResponse(responseCode = "200", description = "datatypes"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
128         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
129         @ApiResponse(responseCode = "404", description = "Data types not found")})
130     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
131     public Response getAllDataTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
132                                            @Parameter(description = "model") @QueryParam("model") String modelName) {
133         Wrapper<Response> responseWrapper = new Wrapper<>();
134         Wrapper<User> userWrapper = new Wrapper<>();
135         init();
136         validateUserExist(responseWrapper, userWrapper, userId);
137         if (responseWrapper.isEmpty()) {
138             String url = request.getMethod() + " " + request.getRequestURI();
139             log.debug("Start handle request of {} - modifier id is {}", url, userId);
140             resourceBusinessLogic.getApplicationDataTypeCache().refreshDataTypesCacheIfStale();
141             final Map<String, DataTypeDefinition> dataTypes = resourceBusinessLogic.getComponentsUtils()
142                 .getAllDataTypes(resourceBusinessLogic.getApplicationDataTypeCache(), modelName);
143             String dataTypeJson = gson.toJson(dataTypes);
144             Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson);
145             responseWrapper.setInnerElement(okResponse);
146         }
147         return responseWrapper.getInnerElement();
148     }
149
150     @GET
151     @Path("interfaceLifecycleTypes")
152     @Consumes(MediaType.APPLICATION_JSON)
153     @Produces(MediaType.APPLICATION_JSON)
154     @Operation(description = "Get interface lifecycle types", method = "GET", summary = "Returns interface lifecycle types", responses = {
155         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
156         @ApiResponse(responseCode = "200", description = "Interface lifecycle types"),
157         @ApiResponse(responseCode = "403", description = "Restricted operation"),
158         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
159         @ApiResponse(responseCode = "404", description = "Interface lifecycle types not found")})
160     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
161     public Response getInterfaceLifecycleTypes(@Context final HttpServletRequest request,
162                                                @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
163                                                @Parameter(description = "model") @QueryParam("model") String modelName) {
164         Wrapper<Response> responseWrapper = new Wrapper<>();
165         Wrapper<User> userWrapper = new Wrapper<>();
166         try {
167             validateUserExist(responseWrapper, userWrapper, userId);
168             if (responseWrapper.isEmpty()) {
169                 String url = request.getMethod() + " " + request.getRequestURI();
170                 log.info(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId);
171                 Either<Map<String, InterfaceDefinition>, ResponseFormat> allInterfaceLifecycleTypes = interfaceOperationBusinessLogic
172                     .getAllInterfaceLifecycleTypes(modelName);
173                 if (allInterfaceLifecycleTypes.isRight()) {
174                     log.info("Failed to get all interface lifecycle types. Reason - {}", allInterfaceLifecycleTypes.right().value());
175                     Response errorResponse = buildErrorResponse(allInterfaceLifecycleTypes.right().value());
176                     responseWrapper.setInnerElement(errorResponse);
177                 } else {
178                     String interfaceLifecycleTypeJson = gson.toJson(allInterfaceLifecycleTypes.left().value());
179                     Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), interfaceLifecycleTypeJson);
180                     responseWrapper.setInnerElement(okResponse);
181                 }
182             }
183             return responseWrapper.getInnerElement();
184         } catch (Exception e) {
185             log.debug("get all interface lifecycle types failed with exception", e);
186             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
187             return buildErrorResponse(responseFormat);
188         }
189     }
190
191     @GET
192     @Path("capabilityTypes")
193     @Consumes(MediaType.APPLICATION_JSON)
194     @Produces(MediaType.APPLICATION_JSON)
195     @Operation(description = "Get capability types", method = "GET", summary = "Returns capability types", responses = {
196         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
197         @ApiResponse(responseCode = "200", description = "capabilityTypes"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
198         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
199         @ApiResponse(responseCode = "404", description = "Capability types not found")})
200     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
201     public Response getAllCapabilityTypesServlet(@Context final HttpServletRequest request,
202                                                  @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
203                                                  @Parameter(description = "model") @QueryParam("model") String modelName) {
204         Wrapper<Response> responseWrapper = new Wrapper<>();
205         Wrapper<User> userWrapper = new Wrapper<>();
206         try {
207             init();
208             validateUserExist(responseWrapper, userWrapper, userId);
209             modelName = ValidationUtils.sanitizeInputString(modelName);
210             if (responseWrapper.isEmpty()) {
211                 String url = request.getMethod() + " " + request.getRequestURI();
212                 log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId);
213                 Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> allDataTypes = capabilitiesBusinessLogic.getAllCapabilityTypes(
214                     modelName);
215                 if (allDataTypes.isRight()) {
216                     log.info("Failed to get all capability types. Reason - {}", allDataTypes.right().value());
217                     Response errorResponse = buildErrorResponse(allDataTypes.right().value());
218                     responseWrapper.setInnerElement(errorResponse);
219                 } else {
220                     Map<String, CapabilityTypeDefinition> dataTypes = allDataTypes.left().value();
221                     String dataTypeJson = gson.toJson(dataTypes);
222                     Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson);
223                     responseWrapper.setInnerElement(okResponse);
224                 }
225             }
226             return responseWrapper.getInnerElement();
227         } catch (Exception e) {
228             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capability Types");
229             log.debug("get all capability types failed with exception", e);
230             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
231             return buildErrorResponse(responseFormat);
232         }
233     }
234
235     @GET
236     @Path("relationshipTypes")
237     @Consumes(MediaType.APPLICATION_JSON)
238     @Produces(MediaType.APPLICATION_JSON)
239     @Operation(description = "Get relationship types", method = "GET", summary = "Returns relationship types", responses = {
240         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
241         @ApiResponse(responseCode = "200", description = "relationshipTypes"),
242         @ApiResponse(responseCode = "403", description = "Restricted operation"),
243         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
244         @ApiResponse(responseCode = "404", description = "Relationship types not found")})
245     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
246     public Response getAllRelationshipTypesServlet(@Context final HttpServletRequest request,
247                                                    @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
248                                                    @Parameter(description = "model") @QueryParam("model") String modelName) {
249         Wrapper<Response> responseWrapper = new Wrapper<>();
250         Wrapper<User> userWrapper = new Wrapper<>();
251         try {
252             init();
253             validateUserExist(responseWrapper, userWrapper, userId);
254             modelName = ValidationUtils.sanitizeInputString(modelName);
255             if (responseWrapper.isEmpty()) {
256                 String url = request.getMethod() + " " + request.getRequestURI();
257                 log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId);
258                 Either<Map<String, RelationshipTypeDefinition>, ResponseFormat> allDataTypes = relationshipTypeBusinessLogic
259                     .getAllRelationshipTypes(modelName);
260                 if (allDataTypes.isRight()) {
261                     log.info("Failed to get all relationship types. Reason - {}", allDataTypes.right().value());
262                     Response errorResponse = buildErrorResponse(allDataTypes.right().value());
263                     responseWrapper.setInnerElement(errorResponse);
264                 } else {
265                     Map<String, RelationshipTypeDefinition> dataTypes = allDataTypes.left().value();
266                     String dataTypeJson = gson.toJson(dataTypes);
267                     Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson);
268                     responseWrapper.setInnerElement(okResponse);
269                 }
270             }
271             return responseWrapper.getInnerElement();
272         } catch (Exception e) {
273             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Relationship Types");
274             log.debug("get all relationship types failed with exception", e);
275             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
276             return buildErrorResponse(responseFormat);
277         }
278     }
279
280     @GET
281     @Path("nodeTypes")
282     @Consumes(MediaType.APPLICATION_JSON)
283     @Produces(MediaType.APPLICATION_JSON)
284     @Operation(description = "Get node types", method = "GET", summary = "Returns node types", responses = {
285         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
286         @ApiResponse(responseCode = "200", description = "nodeTypes"), @ApiResponse(responseCode = "403", description = "Restricted operation"),
287         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
288         @ApiResponse(responseCode = "404", description = "Node types not found")})
289     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
290     public Response getAllNodeTypesServlet(
291         @Context final HttpServletRequest request,
292         @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
293         @Parameter(description = "model") @QueryParam("model") String modelName
294     ) {
295         Wrapper<Response> responseWrapper = new Wrapper<>();
296         Wrapper<User> userWrapper = new Wrapper<>();
297         Either<Map<String, Component>, Response> response;
298         Map<String, Component> componentMap;
299         try {
300             init();
301             validateUserExist(responseWrapper, userWrapper, userId);
302             modelName = ValidationUtils.sanitizeInputString(modelName);
303             if (responseWrapper.isEmpty()) {
304                 String url = request.getMethod() + " " + request.getRequestURI();
305                 log.debug(START_HANDLE_REQUEST_OF_MODIFIER_ID_IS, url, userId);
306                 response = getComponent(resourceBusinessLogic, true, userId, modelName);
307                 if (response.isRight()) {
308                     return response.right().value();
309                 }
310                 componentMap = new HashMap<>(response.left().value());
311                 response = getComponent(resourceBusinessLogic, false, userId, modelName);
312                 if (response.isRight()) {
313                     return response.right().value();
314                 }
315                 componentMap.putAll(response.left().value());
316                 String nodeTypesJson = gson.toJson(componentMap);
317                 Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeTypesJson);
318                 responseWrapper.setInnerElement(okResponse);
319             }
320             return responseWrapper.getInnerElement();
321         } catch (Exception e) {
322             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Node Types");
323             log.debug("get all node types failed with exception", e);
324             ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
325             return buildErrorResponse(responseFormat);
326         }
327     }
328
329     @GET
330     @Path("/artifactTypes")
331     @Operation(description = "Get Tosca ArtifactTypes", method = "GET", summary = "Returns tosca artifact types", responses = {
332         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
333         @ApiResponse(responseCode = "200", description = "Listing successful"),
334         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
335         @ApiResponse(responseCode = "403", description = "Restricted operation"),
336         @ApiResponse(responseCode = "404", description = "Tosca Artifact Types not found")})
337     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
338     public Response getAllToscaArtifactTypes(@Parameter(description = "Model name") @QueryParam("model") String model,
339                                              @Context final HttpServletRequest request, @HeaderParam(Constants.USER_ID_HEADER) String creator) {
340         try {
341             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), artifactsBusinessLogic.getAllToscaArtifacts(model));
342         } catch (final BusinessException e) {
343             throw e;
344         } catch (final Exception e) {
345             final var errorMsg = "Unexpected error while listing the Tosca Artifact types";
346             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(errorMsg);
347             log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, this.getClass().getName(), errorMsg, e);
348             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
349         }
350
351     }
352
353     private Either<Map<String, Component>, Response> getComponent(
354         ComponentBusinessLogic resourceBL,
355         boolean isAbstract, String userId,
356         final String modelName
357     ) {
358         Either<List<Component>, ResponseFormat> actionResponse;
359         List<Component> componentList;
360         actionResponse = resourceBL
361             .getLatestVersionNotAbstractComponentsMetadata(isAbstract, HighestFilterEnum.HIGHEST_ONLY, ComponentTypeEnum.RESOURCE, null, userId,
362                 modelName, false);
363         if (actionResponse.isRight()) {
364             log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, ComponentTypeEnum.RESOURCE.getValue());
365             return Either.right(buildErrorResponse(actionResponse.right().value()));
366         }
367         componentList = actionResponse.left().value();
368         return Either.left(ListUtils.emptyIfNull(componentList).stream().filter(component ->
369                 ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName() != null)
370             .collect(Collectors.toMap(
371                 component -> ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition())
372                     .getToscaResourceName(), component -> component, (component1, component2) -> component1)));
373     }
374 }