2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.so.apihandlerinfra;
23 import java.sql.Timestamp;
24 import java.util.HashMap;
25 import java.util.UUID;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.HashMap;
29 import java.util.List;
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;
74 import org.springframework.beans.factory.annotation.Autowired;
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 com.fasterxml.jackson.core.type.TypeReference;
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;
91 @Path("/onap/so/infra/3gppservices")
93 info = @Info(title = "/onap/so/infra/3gppservices", description = "API Requests for 3GPP Service Instances"))
94 public class Onap3gppServiceInstances {
96 private static final Logger logger = LoggerFactory.getLogger(Onap3gppServiceInstances.class);
98 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
100 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
102 private static final String SAVE_TO_DB = "save instance to db";
104 private static final String URI_PREFIX = "/3gppservices/";
107 private MsoRequest msoRequest;
110 private CatalogDbClient catalogDbClient;
113 private RequestsDbClient requestsDbClient;
116 private RequestHandlerUtils requestHandlerUtils;
119 private ResponseBuilder builder;
122 private CamundaClient camundaClient;
125 private ResponseHandler responseHandler;
128 * POST Requests for 3GPP Service create Instance on a version provided
130 * @throws ApiException
134 @Path("/{version:[vV][1]}/allocate")
135 @Consumes(MediaType.APPLICATION_JSON)
136 @Produces(MediaType.APPLICATION_JSON)
137 @Operation(description = "Create a 3GPP Service Instance on a version provided", responses = @ApiResponse(
138 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
139 public Response createServiceInstance(Allocate3gppService request, @PathParam("version") String version,
140 @Context ContainerRequestContext requestContext) throws ApiException {
141 String requestId = requestHandlerUtils.getRequestId(requestContext);
142 return processServiceInstanceRequest(request, Action.createInstance, version, requestId, null,
143 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
147 * PUT Requests for 3GPP Service update Instance on a version provided
149 * @throws ApiException
153 @Path("/{version:[vV][1]}/modify")
154 @Consumes(MediaType.APPLICATION_JSON)
155 @Produces(MediaType.APPLICATION_JSON)
156 @Operation(description = "Modify a 3GPP Service Instance on a version provided", responses = @ApiResponse(
157 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
158 public Response updateServiceInstance(Modify3gppService request, @PathParam("version") String version,
159 @Context ContainerRequestContext requestContext) throws ApiException {
160 String requestId = requestHandlerUtils.getRequestId(requestContext);
161 HashMap<String, String> instanceIdMap = new HashMap<>();
162 instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
163 return updateServiceInstances(request, Action.updateInstance, version, requestId, instanceIdMap,
164 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
168 * DELETE Requests for 3GPP Service delete Instance on a specified version
170 * @throws ApiException
174 @Path("/{version:[vV][1]}/deAllocate")
175 @Consumes(MediaType.APPLICATION_JSON)
176 @Produces(MediaType.APPLICATION_JSON)
177 @Operation(description = "Terminate/Deallocate a 3GPP Service Instance on a version provided",
178 responses = @ApiResponse(
179 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
180 public Response deleteServiceInstance(DeAllocate3gppService request, @PathParam("version") String version,
181 @Context ContainerRequestContext requestContext) throws ApiException {
182 String requestId = requestHandlerUtils.getRequestId(requestContext);
183 HashMap<String, String> instanceIdMap = new HashMap<>();
184 instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
185 return deleteServiceInstances(request, Action.deleteInstance, version, requestId, instanceIdMap,
186 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
190 * POST Requests for 3GPP Service Activate on a specified version
192 * @throws ApiException
196 @Path("/{version:[vV][1]}/activate")
197 @Consumes(MediaType.APPLICATION_JSON)
198 @Produces(MediaType.APPLICATION_JSON)
199 @Operation(description = "Activate a 3GPP Service Instance on a version provided", responses = @ApiResponse(
200 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
201 public Response activateServiceInstance(ActivateOrDeactivate3gppService request,
202 @PathParam("version") String version, @Context ContainerRequestContext requestContext) throws ApiException {
203 String requestId = requestHandlerUtils.getRequestId(requestContext);
204 HashMap<String, String> instanceIdMap = new HashMap<>();
205 instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
206 return activateOrDeactivateServiceInstances(request, Action.activateInstance, version, requestId, instanceIdMap,
207 requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
211 * POST Requests for 3GPP Service DeActivate on a specified version
213 * @throws ApiException
217 @Path("/{version:[vV][1]}/deActivate")
218 @Consumes(MediaType.APPLICATION_JSON)
219 @Produces(MediaType.APPLICATION_JSON)
220 @Operation(description = "Deactivate a 3GPP Service Instance on a version provided", responses = @ApiResponse(
221 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
222 public Response deActivateServiceInstance(ActivateOrDeactivate3gppService request,
223 @PathParam("version") String version, @Context ContainerRequestContext requestContext) throws ApiException {
224 String requestId = requestHandlerUtils.getRequestId(requestContext);
225 HashMap<String, String> instanceIdMap = new HashMap<>();
226 instanceIdMap.put("serviceInstanceId", request.getServiceInstanceID());
227 return activateOrDeactivateServiceInstances(request, Action.deactivateInstance, version, requestId,
228 instanceIdMap, requestHandlerUtils.getRequestUri(requestContext, URI_PREFIX));
233 * GET requests for slice subnet capabilities on a specified version
237 * @throws ApiException
240 @Path("/{version:[vV][1]}/subnetCapabilityQuery")
241 @Operation(description = "Provides subnet capability based on subnet types", responses = @ApiResponse(
242 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
243 @Produces(MediaType.APPLICATION_JSON)
244 @Consumes(MediaType.APPLICATION_JSON)
245 public Response getSliceSubnetCapabilities(QuerySubnetCapability request, @PathParam("version") String version)
246 throws ApiException {
247 logger.debug("Request received {}", request);
248 List<SubnetTypes> subnetTypes = request.getSubnetTypes();
249 return getSubnetCapabilities(subnetTypes, version);
253 * Process allocate service request and send request to corresponding workflow
259 * @throws ApiException
261 private Response processServiceInstanceRequest(Allocate3gppService request, Action action, String version,
262 String requestId, HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
263 String defaultServiceModelName = "COMMON_SS_DEFAULT";
264 String requestScope = ModelType.service.name();
265 String apiVersion = version.substring(1);
266 String serviceRequestJson = toString.apply(request);
267 if (serviceRequestJson != null) {
268 InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
269 requestScope, serviceRequestJson);
270 String instanceName = request.getName();
271 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
274 requestsDbClient.save(currentActiveReq);
275 } catch (Exception e) {
276 logger.error("Exception occurred", e);
277 ErrorLoggerInfo errorLoggerInfo =
278 new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
279 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
280 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
281 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
282 .errorInfo(errorLoggerInfo).build();
285 RecipeLookupResult recipeLookupResult;
288 getServiceInstanceOrchestrationURI(request.getModelUuid(), action, defaultServiceModelName);
289 } catch (Exception e) {
290 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
291 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
292 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
293 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
294 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
295 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
299 if (recipeLookupResult == null) {
300 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
301 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
302 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
303 MsoException.ServiceException, "Recipe does not exist in catalog DB",
304 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
305 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
309 String serviceInstanceType = request.getSubscriptionServiceType();
310 RequestClientParameter parameter;
312 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
313 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
314 .setServiceInstanceId(null).setServiceType(serviceInstanceType)
315 .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
316 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
317 } catch (Exception e) {
318 logger.error("Exception occurred", e);
319 ErrorLoggerInfo errorLoggerInfo =
320 new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
321 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
322 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
323 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
326 return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
328 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
329 MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
330 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
336 * process modify service request and call corresponding workflow
342 * @throws ApiException
344 private Response updateServiceInstances(Modify3gppService request, Action action, String version, String requestId,
345 HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
346 String defaultServiceModelName = "COMMON_SS_DEFAULT";
347 String requestScope = ModelType.service.name();
348 String apiVersion = version.substring(1);
349 String serviceRequestJson = toString.apply(request);
350 if (serviceRequestJson != null) {
351 InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
352 requestScope, serviceRequestJson);
353 String instanceName = request.getName();
354 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
357 requestsDbClient.save(currentActiveReq);
358 } catch (Exception e) {
359 logger.error("Exception occurred", e);
360 ErrorLoggerInfo errorLoggerInfo =
361 new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
362 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
363 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
364 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
365 .errorInfo(errorLoggerInfo).build();
368 RecipeLookupResult recipeLookupResult;
370 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
371 } catch (Exception e) {
372 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
373 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
374 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
375 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
376 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
377 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
381 if (recipeLookupResult == null) {
382 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
383 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
384 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
385 MsoException.ServiceException, "Recipe does not exist in catalog DB",
386 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
387 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
391 String serviceInstanceType = request.getSubscriptionServiceType();
392 String serviceInstanceId = request.getServiceInstanceID();
393 RequestClientParameter parameter;
395 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
396 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
397 .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
398 .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
399 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
400 } catch (Exception e) {
401 logger.error("Exception occurred", e);
402 ErrorLoggerInfo errorLoggerInfo =
403 new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
404 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
405 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
406 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
409 return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
412 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
413 MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
414 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
420 * process delete service instance request and call corresponding workflow
426 * @throws ApiException
428 private Response deleteServiceInstances(DeAllocate3gppService request, Action action, String version,
429 String requestId, HashMap<String, String> instanceIdMap, String requestUri) throws ApiException {
430 String defaultServiceModelName = "COMMON_SS_DEFAULT";
431 String requestScope = ModelType.service.name();
432 String apiVersion = version.substring(1);
433 String serviceRequestJson = toString.apply(request);
434 if (serviceRequestJson != null) {
435 InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
436 requestScope, serviceRequestJson);
437 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq, null);
439 requestsDbClient.save(currentActiveReq);
440 } catch (Exception e) {
441 logger.error("Exception occurred", e);
442 ErrorLoggerInfo errorLoggerInfo =
443 new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
444 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
445 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
446 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
447 .errorInfo(errorLoggerInfo).build();
449 RecipeLookupResult recipeLookupResult;
451 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
452 } catch (Exception e) {
453 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
454 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
455 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
456 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
457 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
458 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
462 if (recipeLookupResult == null) {
463 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
464 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
465 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
466 MsoException.ServiceException, "Recipe does not exist in catalog DB",
467 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
468 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
472 String serviceInstanceType = request.getSubscriptionServiceType();
473 String serviceInstanceId = request.getServiceInstanceID();
474 RequestClientParameter parameter;
476 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
477 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
478 .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
479 .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
480 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
481 } catch (Exception e) {
482 logger.error("Exception occurred", e);
483 ErrorLoggerInfo errorLoggerInfo =
484 new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
485 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
486 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
487 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
490 return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
492 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
493 MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
494 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
500 * process activate/deactivate service request and call corresponding workflow
502 * @param request the request object for activate/deactivate service
503 * @param action the action for the service
506 * @throws ApiException
508 private Response activateOrDeactivateServiceInstances(ActivateOrDeactivate3gppService request, Action action,
509 String version, String requestId, HashMap<String, String> instanceIdMap, String requestUri)
510 throws ApiException {
511 String defaultServiceModelName = "COMMON_SS_DEFAULT";
512 String requestScope = ModelType.service.name();
513 String apiVersion = version.substring(1);
514 String serviceRequestJson = toString.apply(request);
515 if (serviceRequestJson != null) {
516 InfraActiveRequests currentActiveReq = createRequestObject(request, action, requestId, Status.IN_PROGRESS,
517 requestScope, serviceRequestJson);
518 if (action == Action.activateInstance) {
519 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
520 request.getServiceInstanceID());
522 requestHandlerUtils.checkForDuplicateRequests(action, instanceIdMap, requestScope, currentActiveReq,
526 requestsDbClient.save(currentActiveReq);
527 } catch (Exception e) {
528 logger.error("Exception occurred", e);
529 ErrorLoggerInfo errorLoggerInfo =
530 new ErrorLoggerInfo.Builder(MessageEnum.APIH_DB_ACCESS_EXC, ErrorCode.DataError)
531 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
532 throw new RequestDbFailureException.Builder(SAVE_TO_DB, e.toString(),
533 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).cause(e)
534 .errorInfo(errorLoggerInfo).build();
536 RecipeLookupResult recipeLookupResult;
538 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action, defaultServiceModelName);
539 } catch (Exception e) {
540 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
541 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
542 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
543 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
544 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
545 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
549 if (recipeLookupResult == null) {
550 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
551 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
552 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
553 MsoException.ServiceException, "Recipe does not exist in catalog DB",
554 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
555 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
559 String serviceInstanceType = request.getSubscriptionServiceType();
560 String serviceInstanceId = request.getServiceInstanceID();
561 RequestClientParameter parameter;
563 parameter = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
564 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
565 .setServiceInstanceId(serviceInstanceId).setServiceType(serviceInstanceType)
566 .setRequestDetails(serviceRequestJson).setApiVersion(version).setALaCarte(false)
567 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).setApiVersion(apiVersion).build();
568 } catch (Exception e) {
569 logger.error("Exception occurred", e);
570 ErrorLoggerInfo errorLoggerInfo =
571 new ErrorLoggerInfo.Builder(MessageEnum.APIH_BPEL_RESPONSE_ERROR, ErrorCode.SchemaError)
572 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
573 throw new ValidateException.Builder("Unable to generate RequestClientParamter object" + e.getMessage(),
574 HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorNumbers.SVC_BAD_PARAMETER).errorInfo(errorLoggerInfo)
577 return postBPELRequest(currentActiveReq, parameter, recipeLookupResult.getOrchestrationURI(), requestScope);
579 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
580 MsoException.ServiceException, "JsonProcessingException occurred - serviceRequestJson is null",
581 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
586 // To be implemented for fetching Subnet capabilities
587 private Response getSubnetCapabilities(List<SubnetTypes> subnetTypes, String version) throws ApiException {
588 ObjectMapper oMapper = new ObjectMapper();
589 InputStream inputStream = TypeReference.class.getResourceAsStream("/subnetCapability.json");
590 Map<String, Object> subnetCapability = new HashMap<>();
592 subnetCapability = oMapper.readValue(inputStream, Map.class);
593 } catch (Exception e) {
594 logger.debug("Exception while reading subnet capability value from json", e);
596 Map<String, Object> responseMap = new HashMap<>();
597 for (SubnetTypes value : subnetTypes) {
598 if (subnetCapability.containsKey(value.toString())) {
599 responseMap.put(value.toString(), subnetCapability.get(value.toString()));
602 String response = null;
604 response = oMapper.writeValueAsString(responseMap);
605 } catch (JsonProcessingException e) {
606 logger.debug("Exception while converting subnet capability object to String {}", e);
608 return builder.buildResponse(HttpStatus.SC_OK, null, response, version);
612 * Getting recipes from catalogDb
614 * @param serviceModelUUID the service model version uuid
615 * @param action the action for the service
616 * @param defaultServiceModelName default service name
617 * @return the service recipe result
619 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action,
620 String defaultServiceModelName) {
622 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action, defaultServiceModelName);
624 if (recipeLookupResult != null) {
625 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
626 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
628 logger.debug("No matching recipe record found");
630 return recipeLookupResult;
634 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
636 * @param serviceModelUUID the service version uuid
637 * @param action the action of the service.
638 * @param defaultServiceModelName default service name
639 * @return the service recipe result.
641 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action, String defaultServiceModelName) {
643 Service defaultServiceRecord =
644 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
645 // set recipe as default generic recipe
646 ServiceRecipe recipe =
647 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
648 // check the service special recipe
649 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
650 ServiceRecipe serviceSpecialRecipe =
651 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
652 if (null != serviceSpecialRecipe) {
653 // set service special recipe.
654 recipe = serviceSpecialRecipe;
658 if (recipe == null) {
661 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
665 Function<Object, String> toString = serviceRequest -> {
666 ObjectMapper mapper = new ObjectMapper();
667 String requestAsString = null;
669 requestAsString = mapper.writeValueAsString(serviceRequest);
670 } catch (JsonProcessingException e) {
671 logger.debug("Exception while converting service request object to String {}", e);
673 return requestAsString;
676 public InfraActiveRequests createRequestObject(Object request, Action action, String requestId, Status status,
677 String requestScope, String requestJson) {
678 InfraActiveRequests aq = new InfraActiveRequests();
680 String networkType = null;
681 String serviceInstanceName = null;
682 String serviceInstanceId = null;
683 if (action.name().equals("createInstance")) {
684 networkType = ((Allocate3gppService) request).getNetworkType();
685 serviceInstanceName = ((Allocate3gppService) request).getName();
686 aq.setServiceInstanceName(serviceInstanceName);
687 } else if (action.name().equals("updateInstance")) {
688 networkType = ((Modify3gppService) request).getNetworkType();
689 serviceInstanceName = ((Modify3gppService) request).getName();
690 serviceInstanceId = ((Modify3gppService) request).getServiceInstanceID();
691 aq.setServiceInstanceName(serviceInstanceName);
692 aq.setServiceInstanceId(serviceInstanceId);
693 } else if (action.name().equals("deleteInstance")) {
694 networkType = ((DeAllocate3gppService) request).getNetworkType();
695 serviceInstanceId = ((DeAllocate3gppService) request).getServiceInstanceID();
696 aq.setServiceInstanceId(serviceInstanceId);
697 } else if (action.name().equals("activateInstance")) {
698 networkType = ((ActivateOrDeactivate3gppService) request).getNetworkType();
699 serviceInstanceId = ((ActivateOrDeactivate3gppService) request).getServiceInstanceID();
700 aq.setServiceInstanceName(serviceInstanceId); // setting serviceInstanceId as serviceInstanceName
701 // -->serviceInstanceName shouldn't be null for action -
702 // activateInstance duplicateRequests check
703 aq.setServiceInstanceId(serviceInstanceId);
704 } else if (action.name().equals("deactivateInstance")) {
705 networkType = ((ActivateOrDeactivate3gppService) request).getNetworkType();
706 serviceInstanceId = ((ActivateOrDeactivate3gppService) request).getServiceInstanceID();
707 aq.setServiceInstanceId(serviceInstanceId);
710 aq.setRequestId(requestId);
711 aq.setRequestAction(action.toString());
712 aq.setRequestUrl(MDC.get(LogConstants.HTTP_URL));
713 Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
714 aq.setStartTime(startTimeStamp);
715 aq.setRequestScope(requestScope);
716 aq.setRequestBody(requestJson);
717 aq.setRequestStatus(status.toString());
718 aq.setLastModifiedBy(Constants.MODIFIED_BY_APIHANDLER);
719 aq.setNetworkType(networkType);
720 } catch (Exception e) {
721 logger.error("Exception when creation record request", e);
723 if (!status.equals(Status.FAILED)) {
730 private Response postBPELRequest(InfraActiveRequests currentActiveReq, RequestClientParameter parameter,
731 String orchestrationURI, String requestScope) throws ApiException {
732 ResponseEntity<String> response =
733 requestHandlerUtils.postRequest(currentActiveReq, parameter, orchestrationURI);
734 logger.debug("BPEL response : " + response);
735 int bpelStatus = responseHandler.setStatus(response.getStatusCodeValue());
738 responseHandler.acceptedResponse(response);
739 CamundaResponse camundaResponse = responseHandler.getCamundaResponse(response);
740 String responseBody = camundaResponse.getResponse();
741 if ("Success".equalsIgnoreCase(camundaResponse.getMessage())) {
742 jsonResponse = responseBody;
744 BPMNFailureException bpmnException =
745 new BPMNFailureException.Builder(String.valueOf(bpelStatus) + responseBody, bpelStatus,
746 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR).build();
747 requestHandlerUtils.updateStatus(currentActiveReq, Status.FAILED, bpmnException.getMessage());
750 } catch (ApiException e) {
751 requestHandlerUtils.updateStatus(currentActiveReq, Status.FAILED, e.getMessage());
754 return builder.buildResponse(HttpStatus.SC_ACCEPTED, parameter.getRequestId(), jsonResponse,
755 parameter.getApiVersion());