Read subnetCapabilities configuration file from SO pod
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / onap / so / apihandlerinfra / Onap3gppServiceInstances.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2020 Wipro Limited.
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.onap.so.apihandlerinfra;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileReader;
26 import java.sql.Timestamp;
27 import java.util.HashMap;
28 import java.util.UUID;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.function.Function;
35 import javax.ws.rs.Consumes;
36 import javax.ws.rs.DELETE;
37 import javax.ws.rs.GET;
38 import javax.ws.rs.POST;
39 import javax.ws.rs.PUT;
40 import javax.ws.rs.Path;
41 import javax.ws.rs.PathParam;
42 import javax.ws.rs.Produces;
43 import javax.ws.rs.container.ContainerRequestContext;
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.http.HttpStatus;
48 import org.onap.logging.filter.base.ErrorCode;
49 import org.onap.so.apihandler.camundabeans.CamundaResponse;
50 import org.onap.so.apihandler.common.CamundaClient;
51 import org.onap.so.apihandler.common.ErrorNumbers;
52 import org.onap.so.apihandler.common.RequestClientParameter;
53 import org.onap.so.apihandler.common.ResponseBuilder;
54 import org.onap.so.apihandler.common.ResponseHandler;
55 import org.onap.so.apihandlerinfra.exceptions.ApiException;
56 import org.onap.so.apihandlerinfra.exceptions.BPMNFailureException;
57 import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException;
58 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
59 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
60 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.ActivateOrDeactivate3gppService;
61 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.Allocate3gppService;
62 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.DeAllocate3gppService;
63 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.Modify3gppService;
64 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.QuerySubnetCapability;
65 import org.onap.so.apihandlerinfra.onap3gppserviceinstancebeans.SubnetTypes;
66 import org.onap.so.constants.Status;
67 import org.onap.so.db.catalog.beans.Service;
68 import org.onap.so.db.catalog.beans.ServiceRecipe;
69 import org.onap.so.db.catalog.client.CatalogDbClient;
70 import org.onap.so.logger.LogConstants;
71 import org.onap.so.logger.LoggingAnchor;
72 import org.onap.so.logger.MessageEnum;
73 import org.onap.so.serviceinstancebeans.ModelType;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
76 import org.slf4j.MDC;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.beans.factory.annotation.Value;
79 import org.springframework.http.ResponseEntity;
80 import org.springframework.stereotype.Component;
81 import com.fasterxml.jackson.core.JsonProcessingException;
82 import com.fasterxml.jackson.databind.ObjectMapper;
83 import com.fasterxml.jackson.core.type.TypeReference;
84 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
85 import io.swagger.v3.oas.annotations.Operation;
86 import io.swagger.v3.oas.annotations.info.Info;
87 import io.swagger.v3.oas.annotations.media.ArraySchema;
88 import io.swagger.v3.oas.annotations.media.Content;
89 import io.swagger.v3.oas.annotations.media.Schema;
90 import io.swagger.v3.oas.annotations.responses.ApiResponse;
91 import org.onap.so.db.request.beans.InfraActiveRequests;
92 import org.onap.so.db.request.client.RequestsDbClient;
93
94 @Component
95 @Path("/onap/so/infra/3gppservices")
96 @OpenAPIDefinition(
97         info = @Info(title = "/onap/so/infra/3gppservices", description = "API Requests for 3GPP Service Instances"))
98 public class Onap3gppServiceInstances {
99
100     private static final Logger logger = LoggerFactory.getLogger(Onap3gppServiceInstances.class);
101
102     private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
103
104     private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
105
106     private static final String SAVE_TO_DB = "save instance to db";
107
108     private static final String URI_PREFIX = "/3gppservices/";
109
110     @Autowired
111     private MsoRequest msoRequest;
112
113     @Autowired
114     private CatalogDbClient catalogDbClient;
115
116     @Autowired
117     private RequestsDbClient requestsDbClient;
118
119     @Autowired
120     private RequestHandlerUtils requestHandlerUtils;
121
122     @Autowired
123     private ResponseBuilder builder;
124
125     @Autowired
126     private CamundaClient camundaClient;
127
128     @Autowired
129     private ResponseHandler responseHandler;
130
131     @Value("${subnetCapability.config.file}")
132     private String subnetCapabilityConfigFile;
133
134     /**
135      * POST Requests for 3GPP Service create Instance on a version provided
136      *
137      * @throws ApiException
138      */
139
140     @POST
141     @Path("/{version:[vV][1]}/allocate")
142     @Consumes(MediaType.APPLICATION_JSON)
143     @Produces(MediaType.APPLICATION_JSON)
144     @Operation(description = "Create a 3GPP Service Instance on a version provided", responses = @ApiResponse(
145             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
146     public Response createServiceInstance(Allocate3gppService request, @PathParam("version") String version,
147             @Context ContainerRequestContext requestContext) throws ApiException {
148         String requestId = requestHandlerUtils.getRequestId(requestContext);
149         return processServiceInstanceRequest(request, Action.createInstance, version, requestId, null,
150                 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
151     }
152
153     /**
154      * PUT Requests for 3GPP Service update Instance on a version provided
155      *
156      * @throws ApiException
157      */
158
159     @PUT
160     @Path("/{version:[vV][1]}/modify")
161     @Consumes(MediaType.APPLICATION_JSON)
162     @Produces(MediaType.APPLICATION_JSON)
163     @Operation(description = "Modify a 3GPP Service Instance on a version provided", responses = @ApiResponse(
164             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
165     public Response updateServiceInstance(Modify3gppService request, @PathParam("version") String version,
166             @Context ContainerRequestContext requestContext) throws ApiException {
167         String requestId = requestHandlerUtils.getRequestId(requestContext);
168         HashMap<String, String> instanceIdMap = new HashMap<>();
169         instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
170         return updateServiceInstances(request, Action.updateInstance, version, requestId, instanceIdMap,
171                 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
172     }
173
174     /**
175      * DELETE Requests for 3GPP Service delete Instance on a specified version
176      *
177      * @throws ApiException
178      */
179
180     @DELETE
181     @Path("/{version:[vV][1]}/deAllocate")
182     @Consumes(MediaType.APPLICATION_JSON)
183     @Produces(MediaType.APPLICATION_JSON)
184     @Operation(description = "Terminate/Deallocate a 3GPP Service Instance on a version provided",
185             responses = @ApiResponse(
186                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
187     public Response deleteServiceInstance(DeAllocate3gppService request, @PathParam("version") String version,
188             @Context ContainerRequestContext requestContext) throws ApiException {
189         String requestId = requestHandlerUtils.getRequestId(requestContext);
190         HashMap<String, String> instanceIdMap = new HashMap<>();
191         instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
192         return deleteServiceInstances(request, Action.deleteInstance, version, requestId, instanceIdMap,
193                 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
194     }
195
196     /**
197      * POST Requests for 3GPP Service Activate on a specified version
198      *
199      * @throws ApiException
200      */
201
202     @POST
203     @Path("/{version:[vV][1]}/activate")
204     @Consumes(MediaType.APPLICATION_JSON)
205     @Produces(MediaType.APPLICATION_JSON)
206     @Operation(description = "Activate a 3GPP Service Instance on a version provided", responses = @ApiResponse(
207             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
208     public Response activateServiceInstance(ActivateOrDeactivate3gppService request,
209             @PathParam("version") String version, @Context ContainerRequestContext requestContext) throws ApiException {
210         String requestId = requestHandlerUtils.getRequestId(requestContext);
211         HashMap<String, String> instanceIdMap = new HashMap<>();
212         instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
213         return activateOrDeactivateServiceInstances(request, Action.activateInstance, version, requestId, instanceIdMap,
214                 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
215     }
216
217     /**
218      * POST Requests for 3GPP Service DeActivate on a specified version
219      *
220      * @throws ApiException
221      */
222
223     @POST
224     @Path("/{version:[vV][1]}/deActivate")
225     @Consumes(MediaType.APPLICATION_JSON)
226     @Produces(MediaType.APPLICATION_JSON)
227     @Operation(description = "Deactivate a 3GPP Service Instance on a version provided", responses = @ApiResponse(
228             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
229     public Response deActivateServiceInstance(ActivateOrDeactivate3gppService request,
230             @PathParam("version") String version, @Context ContainerRequestContext requestContext) throws ApiException {
231         String requestId = requestHandlerUtils.getRequestId(requestContext);
232         HashMap<String, String> instanceIdMap = new HashMap<>();
233         instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
234         return activateOrDeactivateServiceInstances(request, Action.deactivateInstance, version, requestId,
235                 instanceIdMap, requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
236     }
237
238     /**
239      *
240      * GET requests for slice subnet capabilities on a specified version
241      *
242      * @param version
243      * @return
244      * @throws ApiException
245      */
246     @GET
247     @Path("/{version:[vV][1]}/subnetCapabilityQuery")
248     @Operation(description = "Provides subnet capability based on subnet types", responses = @ApiResponse(
249             content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
250     @Produces(MediaType.APPLICATION_JSON)
251     @Consumes(MediaType.APPLICATION_JSON)
252     public Response getSliceSubnetCapabilities(QuerySubnetCapability request, @PathParam("version") String version)
253             throws ApiException {
254         logger.debug("Request received {}", request);
255         List<SubnetTypes> subnetTypes = request.getSubnetTypes();
256         return getSubnetCapabilities(subnetTypes, version);
257     }
258
259     /**
260      * Process allocate service request and send request to corresponding workflow
261      *
262      * @param request
263      * @param action
264      * @param version
265      * @return
266      * @throws ApiException
267      */
268     private Response processServiceInstanceRequest(Allocate3gppService request, Action action, String version,
269             String requestId, HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
270         String defaultServiceModelName = "COMMON_SS_DEFAULT";
271         String requestScope = ModelType.service.name();
272         String apiVersion = version.substring(1);
273         String serviceRequestJson = toString.apply(request);
274         if (serviceRequestJson != null) {
275             InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
276                     requestScope, serviceRequestJson);
277             String instanceName = request.getName();
278             requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
279                     instanceName);
280             try {
281                 requestsDbClient.save(currentActiveReq);
282             } catch (Exception e) {
283                 logger.error("Exception occurred", e);
284                 ErrorLoggerInfo errorLoggerInfo =
285                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
286                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
287                 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
288                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
289                                 .errorInfo(errorLoggerInfo).build();
290             }
291
292             RecipeLookupResult recipeLookupResult;
293             try {
294                 recipeLookupResult =
295                         getServiceInstanceOrchestrationURI(request.getModelUuid(), action, defaultServiceModelName);
296             } catch (Exception e) {
297                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
298                         ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
299                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
300                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
301                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
302                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
303                 return response;
304             }
305
306             if (recipeLookupResult == null) {
307                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
308                         MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
309                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
310                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
311                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
312                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
313                 return response;
314             }
315
316             String serviceInstanceType = request.getSubscriptionServiceType();
317             RequestClientParameter parameter;
318             try {
319                 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
320                         .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
321                         .setServiceInstanceId(null).setServiceType(serviceInstanceType)
322                         .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
323                         .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
324             } catch (Exception e) {
325                 logger.error("Exception occurred", e);
326                 ErrorLoggerInfo errorLoggerInfo =
327                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
328                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
329                 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
330                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
331                                 .build();
332             }
333             return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
334         } else {
335             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
336                     MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
337                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
338             return response;
339         }
340     }
341
342     /**
343      * process modify service request and call corresponding workflow
344      *
345      * @param request
346      * @param action
347      * @param version
348      * @return
349      * @throws ApiException
350      */
351     private Response updateServiceInstances(Modify3gppService request, Action action, String version, String requestId,
352             HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
353         String defaultServiceModelName = "COMMON_SS_DEFAULT";
354         String requestScope = ModelType.service.name();
355         String apiVersion = version.substring(1);
356         String serviceRequestJson = toString.apply(request);
357         if (serviceRequestJson != null) {
358             InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
359                     requestScope, serviceRequestJson);
360             String instanceName = request.getName();
361             requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
362                     instanceName);
363             try {
364                 requestsDbClient.save(currentActiveReq);
365             } catch (Exception e) {
366                 logger.error("Exception occurred", e);
367                 ErrorLoggerInfo errorLoggerInfo =
368                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
369                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
370                 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
371                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
372                                 .errorInfo(errorLoggerInfo).build();
373             }
374
375             RecipeLookupResult recipeLookupResult;
376             try {
377                 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
378             } catch (Exception e) {
379                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
380                         ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
381                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
382                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
383                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
384                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
385                 return response;
386             }
387
388             if (recipeLookupResult == null) {
389                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
390                         MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
391                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
392                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
393                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
394                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
395                 return response;
396             }
397
398             String serviceInstanceType = request.getSubscriptionServiceType();
399             String serviceInstanceId = request.getServiceInstanceID();
400             RequestClientParameter parameter;
401             try {
402                 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
403                         .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
404                         .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
405                         .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
406                         .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
407             } catch (Exception e) {
408                 logger.error("Exception occurred", e);
409                 ErrorLoggerInfo errorLoggerInfo =
410                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
411                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
412                 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
413                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
414                                 .build();
415             }
416             return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
417
418         } else {
419             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
420                     MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
421                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
422             return response;
423         }
424     }
425
426     /**
427      * process delete service instance request and call corresponding workflow
428      *
429      * @param request
430      * @param action
431      * @param version
432      * @return
433      * @throws ApiException
434      */
435     private Response deleteServiceInstances(DeAllocate3gppService request, Action action, String version,
436             String requestId, HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
437         String defaultServiceModelName = "COMMON_SS_DEFAULT";
438         String requestScope = ModelType.service.name();
439         String apiVersion = version.substring(1);
440         String serviceRequestJson = toString.apply(request);
441         if (serviceRequestJson != null) {
442             InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
443                     requestScope, serviceRequestJson);
444             requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq, null);
445             try {
446                 requestsDbClient.save(currentActiveReq);
447             } catch (Exception e) {
448                 logger.error("Exception occurred", e);
449                 ErrorLoggerInfo errorLoggerInfo =
450                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
451                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
452                 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
453                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
454                                 .errorInfo(errorLoggerInfo).build();
455             }
456             RecipeLookupResult recipeLookupResult;
457             try {
458                 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
459             } catch (Exception e) {
460                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
461                         ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
462                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
463                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
464                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
465                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
466                 return response;
467             }
468
469             if (recipeLookupResult == null) {
470                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
471                         MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
472                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
473                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
474                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
475                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
476                 return response;
477             }
478
479             String serviceInstanceType = request.getSubscriptionServiceType();
480             String serviceInstanceId = request.getServiceInstanceID();
481             RequestClientParameter parameter;
482             try {
483                 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
484                         .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
485                         .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
486                         .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
487                         .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
488             } catch (Exception e) {
489                 logger.error("Exception occurred", e);
490                 ErrorLoggerInfo errorLoggerInfo =
491                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
492                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
493                 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
494                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
495                                 .build();
496             }
497             return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
498         } else {
499             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
500                     MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
501                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
502             return response;
503         }
504     }
505
506     /**
507      * process activate/deactivate service request and call corresponding workflow
508      *
509      * @param request the request object for activate/deactivate service
510      * @param action the action for the service
511      * @param version
512      * @return
513      * @throws ApiException
514      */
515     private Response activateOrDeactivateServiceInstances(ActivateOrDeactivate3gppService request, Action action,
516             String version, String requestId, HashMap<String, String> instanceIdMap, String requestUri)
517             throws ApiException {
518         String defaultServiceModelName = "COMMON_SS_DEFAULT";
519         String requestScope = ModelType.service.name();
520         String apiVersion = version.substring(1);
521         String serviceRequestJson = toString.apply(request);
522         if (serviceRequestJson != null) {
523             InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
524                     requestScope, serviceRequestJson);
525             if (action == Action.activateInstance) {
526                 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
527                         request.getServiceInstanceID());
528             } else {
529                 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
530                         null);
531             }
532             try {
533                 requestsDbClient.save(currentActiveReq);
534             } catch (Exception e) {
535                 logger.error("Exception occurred", e);
536                 ErrorLoggerInfo errorLoggerInfo =
537                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
538                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
539                 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
540                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
541                                 .errorInfo(errorLoggerInfo).build();
542             }
543             RecipeLookupResult recipeLookupResult;
544             try {
545                 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
546             } catch (Exception e) {
547                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
548                         ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
549                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
550                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
551                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
552                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
553                 return response;
554             }
555
556             if (recipeLookupResult == null) {
557                 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
558                         MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
559                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
560                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
561                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
562                 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
563                 return response;
564             }
565
566             String serviceInstanceType = request.getSubscriptionServiceType();
567             String serviceInstanceId = request.getServiceInstanceID();
568             RequestClientParameter parameter;
569             try {
570                 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
571                         .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
572                         .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
573                         .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
574                         .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
575             } catch (Exception e) {
576                 logger.error("Exception occurred", e);
577                 ErrorLoggerInfo errorLoggerInfo =
578                         new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
579                                 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
580                 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
581                         HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
582                                 .build();
583             }
584             return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
585         } else {
586             Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
587                     MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
588                     ErrorNumbers.SVC_BAD_PARAMETER, null, version);
589             return response;
590         }
591     }
592
593     private Response getSubnetCapabilities(List<SubnetTypes> subnetTypes, String version) throws ApiException {
594         ObjectMapper oMapper = new ObjectMapper();
595         String inputFileString = "";
596         Map<String, Object> subnetCapability = new HashMap<>();
597         BufferedReader br = null;
598         try {
599             logger.debug("Reading SubnetCapability file");
600             br = new BufferedReader(new FileReader(new File(subnetCapabilityConfigFile)));
601             StringBuilder sb = new StringBuilder();
602             String line = br.readLine();
603             while (line != null) {
604                 sb.append(line);
605                 sb.append("\n");
606                 line = br.readLine();
607             }
608             inputFileString = sb.toString();
609             subnetCapability = oMapper.readValue(inputFileString, Map.class);
610         } catch (Exception e) {
611             logger.debug("Exception while reading subnet capability value from json", e);
612         }
613         Map<String, Object> responseMap = new HashMap<>();
614         for (SubnetTypes value : subnetTypes) {
615             if (subnetCapability.containsKey(value.toString())) {
616                 responseMap.put(value.toString(), subnetCapability.get(value.toString()));
617             }
618         }
619         String response = null;
620         try {
621             response = oMapper.writeValueAsString(responseMap);
622         } catch (JsonProcessingException e) {
623             logger.debug("Exception while converting subnet capability object to String {}", e);
624         }
625         return builder.buildResponse(HttpStatus.SC_OK, null, response, version);
626     }
627
628     /**
629      * Getting recipes from catalogDb
630      *
631      * @param serviceModelUUID the service model version uuid
632      * @param action the action for the service
633      * @param defaultServiceModelName default service name
634      * @return the service recipe result
635      */
636     private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action,
637             String defaultServiceModelName) {
638
639         RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action, defaultServiceModelName);
640
641         if (recipeLookupResult != null) {
642             logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
643                     + Integer.toString(recipeLookupResult.getRecipeTimeout()));
644         } else {
645             logger.debug("No matching recipe record found");
646         }
647         return recipeLookupResult;
648     }
649
650     /**
651      * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
652      *
653      * @param serviceModelUUID the service version uuid
654      * @param action the action of the service.
655      * @param defaultServiceModelName default service name
656      * @return the service recipe result.
657      */
658     private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action, String defaultServiceModelName) {
659
660         Service defaultServiceRecord =
661                 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
662         // set recipe as default generic recipe
663         ServiceRecipe recipe =
664                 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
665         // check the service special recipe
666         if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
667             ServiceRecipe serviceSpecialRecipe =
668                     catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
669             if (null != serviceSpecialRecipe) {
670                 // set service special recipe.
671                 recipe = serviceSpecialRecipe;
672             }
673         }
674
675         if (recipe == null) {
676             return null;
677         }
678         return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
679
680     }
681
682     Function<Object, String> toString = serviceRequest -> {
683         ObjectMapper mapper = new ObjectMapper();
684         String requestAsString = null;
685         try {
686             requestAsString = mapper.writeValueAsString(serviceRequest);
687         } catch (JsonProcessingException e) {
688             logger.debug("Exception while converting service request object to String {}", e);
689         }
690         return requestAsString;
691     };
692
693     public InfraActiveRequests createRequestObject(Object request, Action action, String requestId, Status status,
694             String requestScope, String requestJson) {
695         InfraActiveRequests aq = new InfraActiveRequests();
696         try {
697             String networkType = null;
698             String serviceInstanceName = null;
699             String serviceInstanceId = null;
700             if (action.name().equals("createInstance")) {
701                 networkType = ((Allocate3gppService) request).getNetworkType();
702                 serviceInstanceName = ((Allocate3gppService) request).getName();
703                 aq.setServiceInstanceName(serviceInstanceName);
704             } else if (action.name().equals("updateInstance")) {
705                 networkType = ((Modify3gppService) request).getNetworkType();
706                 serviceInstanceName = ((Modify3gppService) request).getName();
707                 serviceInstanceId = ((Modify3gppService) request).getServiceInstanceID();
708                 aq.setServiceInstanceName(serviceInstanceName);
709                 aq.setServiceInstanceId(serviceInstanceId);
710             } else if (action.name().equals("deleteInstance")) {
711                 networkType = ((DeAllocate3gppService) request).getNetworkType();
712                 serviceInstanceId = ((DeAllocate3gppService) request).getServiceInstanceID();
713                 aq.setServiceInstanceId(serviceInstanceId);
714             } else if (action.name().equals("activateInstance")) {
715                 networkType = ((ActivateOrDeactivate3gppService) request).getNetworkType();
716                 serviceInstanceId = ((ActivateOrDeactivate3gppService) request).getServiceInstanceID();
717                 aq.setServiceInstanceName(serviceInstanceId); // setting serviceInstanceId as serviceInstanceName
718                                                               // -->serviceInstanceName shouldn't be null for action -
719                                                               // activateInstance duplicateRequests check
720                 aq.setServiceInstanceId(serviceInstanceId);
721             } else if (action.name().equals("deactivateInstance")) {
722                 networkType = ((ActivateOrDeactivate3gppService) request).getNetworkType();
723                 serviceInstanceId = ((ActivateOrDeactivate3gppService) request).getServiceInstanceID();
724                 aq.setServiceInstanceId(serviceInstanceId);
725             }
726
727             aq.setRequestId(requestId);
728             aq.setRequestAction(action.toString());
729             aq.setRequestUrl(MDC.get(LogConstants.HTTP_URL));
730             Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
731             aq.setStartTime(startTimeStamp);
732             aq.setRequestScope(requestScope);
733             aq.setRequestBody(requestJson);
734             aq.setRequestStatus(status.toString());
735             aq.setLastModifiedBy(Constants.MODIFIED_BY_APIHANDLER);
736             aq.setNetworkType(networkType);
737         } catch (Exception e) {
738             logger.error("Exception when creation record request", e);
739
740             if (!status.equals(Status.FAILED)) {
741                 throw e;
742             }
743         }
744         return aq;
745     }
746
747     private Response postBPELRequest(InfraActiveRequests currentActiveReq, RequestClientParameter parameter,
748             String orchestrationURI, String requestScope) throws ApiException {
749         ResponseEntity<String> response =
750                 requestHandlerUtils.postRequest(currentActiveReq, parameter, orchestrationURI);
751         logger.debug("BPEL response : " + response);
752         int bpelStatus = responseHandler.setStatus(response.getStatusCodeValue());
753         String jsonResponse;
754         try {
755             responseHandler.acceptedResponse(response);
756             CamundaResponse camundaResponse = responseHandler.getCamundaResponse(response);
757             String responseBody = camundaResponse.getResponse();
758             if ("Success".equalsIgnoreCase(camundaResponse.getMessage())) {
759                 jsonResponse = responseBody;
760             } else {
761                 BPMNFailureException bpmnException =
762                         new BPMNFailureException.Builder(String.valueOf(bpelStatus) + responseBody, bpelStatus,
763                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).build();
764                 requestHandlerUtils.updateStatus(currentActiveReq, Status.FAILED, bpmnException.getMessage());
765                 throw bpmnException;
766             }
767         } catch (ApiException e) {
768             requestHandlerUtils.updateStatus(currentActiveReq, Status.FAILED, e.getMessage());
769             throw e;
770         }
771         return builder.buildResponse(HttpStatus.SC_ACCEPTED, parameter.getRequestId(), jsonResponse,
772                 parameter.getApiVersion());
773     }
774 }
775
776