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