Remove dead code
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / externalapi / servlet / AbstractTemplateServlet.java
1 /*
2  * Copyright (C) 2020 CMCC, Inc. and others. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.be.externalapi.servlet;
18
19 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.jcabi.aspects.Loggable;
21 import fj.data.Either;
22 import io.swagger.v3.oas.annotations.Operation;
23 import io.swagger.v3.oas.annotations.Parameter;
24 import io.swagger.v3.oas.annotations.media.ArraySchema;
25 import io.swagger.v3.oas.annotations.media.Content;
26 import io.swagger.v3.oas.annotations.media.Schema;
27 import io.swagger.v3.oas.annotations.responses.ApiResponse;
28 import io.swagger.v3.oas.annotations.servers.Server;
29 import io.swagger.v3.oas.annotations.servers.Servers;
30 import io.swagger.v3.oas.annotations.tags.Tag;
31 import io.swagger.v3.oas.annotations.tags.Tags;
32
33 import java.io.IOException;
34 import java.util.List;
35 import javax.inject.Inject;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.ws.rs.*;
38 import javax.ws.rs.core.Context;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41
42
43 import org.openecomp.sdc.be.components.impl.*;
44 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
45 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
46 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
47 import org.openecomp.sdc.be.config.BeEcompErrorManager;
48 import org.openecomp.sdc.be.dao.api.ActionStatus;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.externalapi.servlet.representation.AbstractTemplateInfo;
51 import org.openecomp.sdc.be.externalapi.servlet.representation.CopyServiceInfo;
52 import org.openecomp.sdc.be.impl.ComponentsUtils;
53 import org.openecomp.sdc.be.impl.ServletUtils;
54 import org.openecomp.sdc.be.model.*;
55 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
56 import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
57 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
58 import org.openecomp.sdc.be.servlets.*;
59 import org.openecomp.sdc.be.user.UserBusinessLogic;
60 import org.openecomp.sdc.common.api.Constants;
61 import org.openecomp.sdc.common.datastructure.Wrapper;
62 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
63 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
64 import org.openecomp.sdc.common.log.enums.StatusCode;
65 import org.openecomp.sdc.common.log.wrappers.Logger;
66 import org.openecomp.sdc.exception.ResponseFormat;
67 import org.springframework.stereotype.Controller;
68
69 /**
70  * This servlet provides external interfaces related to abstract templates.
71  *
72  * @author hekeguang
73  */
74
75 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
76 @Path("/v1/catalog")
77 @Tags({@Tag(name = "SDC External APIs")})
78 @Servers({@Server(url = "/sdc")})
79 @Controller
80
81 public class AbstractTemplateServlet extends AbstractValidationsServlet {
82
83     @Context
84     private HttpServletRequest request;
85
86     private final ElementBusinessLogic elementBusinessLogic;
87     private final AbstractTemplateBusinessLogic abstractTemplateBusinessLogic;
88
89     private final ServiceBusinessLogic serviceBusinessLogic;
90     private final ResourceBusinessLogic resourceBusinessLogic;
91
92     private static final Logger log = Logger.getLogger(AbstractTemplateServlet.class);
93     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(AbstractTemplateServlet.class.getName());
94
95     @Inject
96     public AbstractTemplateServlet(UserBusinessLogic userBusinessLogic,
97                                    ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
98                                    ServletUtils servletUtils, ResourceImportManager resourceImportManager,
99                                    ElementBusinessLogic elementBusinessLogic,
100                                    AbstractTemplateBusinessLogic abstractTemplateBusinessLogic, ServiceBusinessLogic serviceBusinessLogic, ResourceBusinessLogic resourceBusinessLogic) {
101         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
102         this.elementBusinessLogic = elementBusinessLogic;
103         this.abstractTemplateBusinessLogic = abstractTemplateBusinessLogic;
104         this.serviceBusinessLogic = serviceBusinessLogic;
105         this.resourceBusinessLogic = resourceBusinessLogic;
106     }
107
108     private Wrapper<ResponseFormat> validateRequestHeaders(String instanceIdHeader, String userId) {
109         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
110         if (responseWrapper.isEmpty()) {
111             validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
112         }
113         if (responseWrapper.isEmpty()) {
114             validateHttpCspUserIdHeader(userId, responseWrapper);
115         }
116         return responseWrapper;
117     }
118
119     /**
120      * @param requestId
121      * @param instanceIdHeader
122      * @param accept
123      * @param authorization
124      * @param uuid
125      * @return
126      */
127     @GET
128     @Path("/abstract/service/serviceUUID/{uuid}/status")
129     @Produces(MediaType.APPLICATION_JSON)
130     @Operation(description = "Fetch abstract status of service", method = "GET",
131             summary = "Return whether the service is a virtual service", responses = {@ApiResponse(responseCode = "200",
132             description = "The check result of whether the service is an abstract service is returned",
133             content = @Content(array = @ArraySchema(schema = @Schema(implementation = AbstractTemplateInfo.class)))),
134             @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
135             @ApiResponse(responseCode = "401",
136                     description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic Authentication credentials - POL5002"),
137             @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
138             @ApiResponse(responseCode = "404",
139                     description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
140             @ApiResponse(responseCode = "405",
141                     description = "Method  Not Allowed  :  Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
142             @ApiResponse(responseCode = "500",
143                     description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")})
144     @PermissionAllowed(AafPermission.PermNames.READ_VALUE)
145     public Response getServiceAbstractStatus(
146             @Parameter(description = "X-ECOMP-RequestID header",
147                     required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
148             @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
149                     value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
150             @Parameter(description = "Determines the format of the body of the response",
151                     required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
152             @Parameter(description = "The username and password",
153                     required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
154             @Parameter(description = "The requested asset uuid",
155                     required = true) @PathParam("uuid") final String uuid) throws IOException {
156
157         ResponseFormat responseFormat = null;
158         AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_TEMPLATE_ABSTRACT_STATUS;
159         String requestURI = request.getRequestURI();
160         String url = request.getMethod() + " " + requestURI;
161         log.debug("getServiceAbstractStatus: Start handle request of {}", url);
162
163         String assetType = "services";
164         ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
165         ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentType.getValue());
166         DistributionData distributionData = new DistributionData(instanceIdHeader, requestURI);
167         // Mandatory
168         if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
169             log.debug("getServiceAbstractStatus: Missing X-ECOMP-InstanceID header");
170             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID);
171             getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
172                     resourceCommonInfo, requestId, uuid);
173             return buildErrorResponse(responseFormat);
174         }
175
176         try {
177
178             Either<List<? extends Component>, ResponseFormat> assetTypeData = elementBusinessLogic.getCatalogComponentsByUuidAndAssetType(assetType, uuid);
179
180             if (assetTypeData.isRight()) {
181                 log.debug("getServiceAbstractStatus: Service Fetching Failed");
182                 responseFormat = assetTypeData.right().value();
183                 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
184                         resourceCommonInfo, requestId, uuid);
185
186                 return buildErrorResponse(responseFormat);
187             }
188             resourceCommonInfo.setResourceName(assetTypeData.left().value().iterator().next().getName());
189             log.debug("getServiceAbstractStatus: Service Fetching Success");
190             Either<AbstractTemplateInfo, ResponseFormat> resMetadata = abstractTemplateBusinessLogic.getServiceAbstractStatus(assetTypeData.left().value());
191             if (resMetadata.isRight()) {
192                 log.debug("getServiceAbstractStatus: Service abstract status get Failed");
193                 responseFormat = resMetadata.right().value();
194
195                 getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
196                         resourceCommonInfo, requestId, uuid);
197                 return buildErrorResponse(responseFormat);
198             }
199             Object result = RepresentationUtils.toRepresentation(resMetadata.left().value());
200             responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
201             getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, distributionData,
202                     resourceCommonInfo, requestId, uuid);
203
204             return buildOkResponse(responseFormat, result);
205         } catch (Exception e) {
206             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch abstract status of service");
207             log.debug("getServiceAbstractStatus: Fetch abstract status of service with exception", e);
208             throw e;
209         }
210     }
211
212     /**
213      * @param requestId
214      * @param instanceIdHeader
215      * @param accept
216      * @param authorization
217      * @param uuid
218      * @return
219      */
220     @POST
221     @Path("/abstract/service/serviceUUID/{uuid}/copy")
222     @Produces(MediaType.APPLICATION_JSON)
223     @Operation(description = "Copy a new service based on the existing service", method = "POST",
224             summary = "Return whether the copy service is successful", responses = {@ApiResponse(responseCode = "200",
225             description = "ECOMP component is authenticated and list of Catalog Assets Metadata is returned",
226             content = @Content(array = @ArraySchema(schema = @Schema(implementation = AbstractTemplateInfo.class)))),
227             @ApiResponse(responseCode = "400", description = "Missing  'X-ECOMP-InstanceID'  HTTP header - POL5001"),
228             @ApiResponse(responseCode = "401",
229                     description = "ECOMP component  should authenticate itself  and  to  re-send  again  HTTP  request  with its Basic Authentication credentials - POL5002"),
230             @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
231             @ApiResponse(responseCode = "404",
232                     description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
233             @ApiResponse(responseCode = "405",
234                     description = "Method  Not Allowed  :  Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
235             @ApiResponse(responseCode = "500",
236                     description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
237             @ApiResponse(responseCode = "409", description = "Service already exist")})
238     @PermissionAllowed(AafPermission.PermNames.WRITE_VALUE)
239     public Response copyExistService(
240             @Parameter(description = "The user id",
241                     required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
242             @Parameter(description = "X-ECOMP-RequestID header",
243                     required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
244             @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
245                     value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
246             @Parameter(description = "Determines the format of the body of the response",
247                     required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
248             @Parameter(description = "The username and password",
249                     required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
250             @Parameter(description = "The requested asset uuid",
251                     required = true) @PathParam("uuid") final String uuid,
252             @Parameter(hidden = true) String data) throws IOException {
253
254
255         String url = request.getMethod() + " " + request.getRequestURI();
256         log.debug("copyExistService: Start handle request of {}", url);
257         User modifier = new User();
258         modifier.setUserId(userId);
259         log.debug("modifier id is {}", userId);
260         loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, StatusCode.STARTED, "Starting to create a service by user {} ", userId);
261
262         validateNotEmptyBody(data);
263
264         Either<CopyServiceInfo, ResponseFormat> convertResponse = parseToCopyServiceInfo(data, modifier);
265         if (convertResponse.isRight()) {
266             throw new ByResponseFormatComponentException(convertResponse.right().value());
267         }
268
269         String assetType = "services";
270         CopyServiceInfo copyServiceInfo = convertResponse.left().value();
271         Either<List<? extends Component>, ResponseFormat> assetTypeData = elementBusinessLogic.getCatalogComponentsByUuidAndAssetType(assetType, uuid);
272
273         if (assetTypeData.isRight() || assetTypeData.left().value().size() != 1) {
274             log.debug("getServiceAbstractStatus: Service Fetching Failed");
275             throw new ByResponseFormatComponentException(assetTypeData.right().value());
276         }
277
278         log.debug("getServiceAbstractStatus: Service Fetching Success");
279
280         Service service = (Service) assetTypeData.left().value().get(0);
281         List<String> tags = service.getTags();
282         if (tags != null && !tags.isEmpty()) {
283             for (int i = tags.size() - 1; i >= 0; i--) {
284                 String tag = tags.get(i);
285                 if (service.getName().equals(tag)) {
286                     tags.remove(tag);
287                 }
288             }
289         }
290         service.setName(copyServiceInfo.getNewServiceName());
291         tags.add(copyServiceInfo.getNewServiceName());
292         Either<Service, ResponseFormat> actionResponse = serviceBusinessLogic.createService(service, modifier);
293
294         if (actionResponse.isRight()) {
295             log.debug("Failed to create service");
296             throw new ByResponseFormatComponentException(actionResponse.right().value());
297         }
298
299         loggerSupportability.log(LoggerSupportabilityActions.CREATE_SERVICE, service.getComponentMetadataForSupportLog(), StatusCode.COMPLETE, "Service {} has been copyied by user {} ", service.getName(), userId);
300
301         return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value());
302
303     }
304
305     public Either<CopyServiceInfo, ResponseFormat> parseToCopyServiceInfo(String serviceJson, User user) {
306         return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, CopyServiceInfo.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
307     }
308
309     private CopyServiceInfo convertJsonToServiceInfo(String data) {
310         ObjectMapper mapper = new ObjectMapper();
311         try {
312             return mapper.readValue(data, CopyServiceInfo.class);
313         } catch (IOException e) {
314             log.error("#convertJsonToServiceInfo - json deserialization failed with error: ", e);
315             return new CopyServiceInfo();
316         }
317     }
318 }