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