2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.apihandlerinfra;
25 import java.io.IOException;
27 import javax.ws.rs.Consumes;
28 import javax.ws.rs.DELETE;
29 import javax.ws.rs.GET;
30 import javax.ws.rs.POST;
31 import javax.ws.rs.PUT;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response;
37 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.*;
38 import org.onap.aai.domain.yang.v16.ServiceInstance;
39 import org.onap.so.client.aai.AAIObjectType;
40 import org.onap.so.client.aai.AAIResourcesClient;
41 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
42 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
43 import org.onap.so.logger.LoggingAnchor;
44 import org.apache.http.HttpResponse;
45 import org.apache.http.HttpStatus;
46 import org.json.JSONObject;
47 import org.onap.so.apihandler.common.ErrorNumbers;
48 import org.onap.so.apihandler.common.RequestClient;
49 import org.onap.so.apihandler.common.RequestClientFactory;
50 import org.onap.so.apihandler.common.RequestClientParameter;
51 import org.onap.so.apihandler.common.ResponseBuilder;
52 import org.onap.so.apihandler.common.ResponseHandler;
53 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.CompareModelsRequest;
54 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
55 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
56 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceScaleRequest;
57 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
58 import org.onap.so.apihandlerinfra.exceptions.ApiException;
59 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
60 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
61 import org.onap.so.constants.Status;
62 import org.onap.so.db.catalog.beans.Service;
63 import org.onap.so.db.catalog.beans.ServiceRecipe;
64 import org.onap.so.db.catalog.client.CatalogDbClient;
65 import org.onap.so.db.request.beans.OperationStatus;
66 import org.onap.so.db.request.client.RequestsDbClient;
67 import org.onap.so.logger.ErrorCode;
68 import org.onap.so.logger.MessageEnum;
69 import org.onap.so.serviceinstancebeans.ModelInfo;
70 import org.onap.so.serviceinstancebeans.ModelType;
71 import org.onap.so.serviceinstancebeans.RequestDetails;
72 import org.onap.so.serviceinstancebeans.RequestInfo;
73 import org.onap.so.serviceinstancebeans.RequestParameters;
74 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
75 import org.onap.so.serviceinstancebeans.SubscriberInfo;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78 import org.springframework.beans.factory.annotation.Autowired;
79 import org.springframework.stereotype.Component;
80 import com.fasterxml.jackson.databind.ObjectMapper;
81 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
82 import io.swagger.v3.oas.annotations.Operation;
83 import io.swagger.v3.oas.annotations.info.Info;
84 import io.swagger.v3.oas.annotations.media.ArraySchema;
85 import io.swagger.v3.oas.annotations.media.Content;
86 import io.swagger.v3.oas.annotations.media.Schema;
87 import io.swagger.v3.oas.annotations.responses.ApiResponse;
90 @Path("/onap/so/infra/e2eServiceInstances")
91 @OpenAPIDefinition(info = @Info(title = "/onap/so/infra/e2eServiceInstances",
92 description = "API Requests for E2E Service Instances"))
94 public class E2EServiceInstances {
96 private HashMap<String, String> instanceIdMap = new HashMap<>();
97 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
99 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
101 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
103 private static final String SERVICE_ID = "serviceId";
106 private MsoRequest msoRequest;
109 private RequestClientFactory requestClientFactory;
112 private RequestsDbClient requestsDbClient;
115 private CatalogDbClient catalogDbClient;
118 private ResponseBuilder builder;
121 * POST Requests for E2E Service create Instance on a version provided
123 * @throws ApiException
127 @Path("/{version:[vV][3-5]}")
128 @Consumes(MediaType.APPLICATION_JSON)
129 @Produces(MediaType.APPLICATION_JSON)
130 @Operation(description = "Create an E2E Service Instance on a version provided", responses = @ApiResponse(
131 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
132 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
134 return processE2EserviceInstances(request, Action.createInstance, null, version);
138 * PUT Requests for E2E Service update Instance on a version provided
140 * @throws ApiException
144 @Path("/{version:[vV][3-5]}/{serviceId}")
145 @Consumes(MediaType.APPLICATION_JSON)
146 @Produces(MediaType.APPLICATION_JSON)
147 @Operation(description = "Update an E2E Service Instance on a version provided and serviceId",
148 responses = @ApiResponse(
149 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
150 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
151 @PathParam("serviceId") String serviceId) throws ApiException {
153 instanceIdMap.put(SERVICE_ID, serviceId);
155 return updateE2EserviceInstances(request, Action.updateInstance, version);
159 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
161 * @throws ApiException
165 @Path("/{version:[vV][3-5]}/{serviceId}")
166 @Consumes(MediaType.APPLICATION_JSON)
167 @Produces(MediaType.APPLICATION_JSON)
168 @Operation(description = "Delete E2E Service Instance on a specified version and serviceId",
169 responses = @ApiResponse(
170 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
171 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
172 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
174 instanceIdMap.put(SERVICE_ID, serviceId);
176 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
180 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
181 @Operation(description = "Find e2eServiceInstances Requests for a given serviceId and operationId",
182 responses = @ApiResponse(
183 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
184 @Produces(MediaType.APPLICATION_JSON)
185 public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
186 @PathParam("version") String version, @PathParam("operationId") String operationId) {
187 return getE2EServiceInstance(serviceId, operationId, version);
191 * Scale Requests for E2E Service scale Instance on a specified version
193 * @throws ApiException
197 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
198 @Consumes(MediaType.APPLICATION_JSON)
199 @Produces(MediaType.APPLICATION_JSON)
200 @Operation(description = "Scale E2E Service Instance on a specified version", responses = @ApiResponse(
201 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
202 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
203 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
205 logger.debug("------------------scale begin------------------");
206 instanceIdMap.put(SERVICE_ID, serviceId);
207 return scaleE2EserviceInstances(request, Action.scaleInstance, version);
211 * GET Requests for Comparing model of service instance with target version
213 * @throws ApiException
217 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
218 @Consumes(MediaType.APPLICATION_JSON)
219 @Produces(MediaType.APPLICATION_JSON)
221 description = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
222 responses = @ApiResponse(
223 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
224 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
225 @PathParam("version") String version) throws ApiException {
227 instanceIdMap.put(SERVICE_ID, serviceId);
229 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
232 private Response compareModelwithTargetVersion(String requestJSON, Action action,
233 HashMap<String, String> instanceIdMap, String version) throws ApiException {
235 String requestId = UUID.randomUUID().toString();
237 CompareModelsRequest e2eCompareModelReq;
239 ObjectMapper mapper = new ObjectMapper();
241 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
243 } catch (Exception e) {
245 logger.debug("Mapping of request to JSON object failed : ", e);
246 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
247 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
248 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
249 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
250 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
251 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
256 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
260 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
261 String requestId, Action action, String version) throws ApiException {
263 // Define RecipeLookupResult info here instead of query DB for efficiency
264 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
265 int recipeTimeout = 180;
267 RequestClient requestClient;
268 HttpResponse response;
271 requestClient = requestClientFactory.getRequestClient(workflowUrl);
273 JSONObject jjo = new JSONObject(requestJSON);
274 String bpmnRequest = jjo.toString();
276 // Capture audit event
277 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
278 String serviceId = instanceIdMap.get(SERVICE_ID);
279 String serviceType = e2eCompareModelReq.getServiceType();
280 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
281 .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
282 .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
283 .setALaCarte(false).build();
284 response = requestClient.post(postParam);
285 } catch (Exception e) {
286 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
287 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
288 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
289 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
290 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
291 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
295 if (response == null) {
297 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
298 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
299 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
300 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
301 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
305 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
306 int bpelStatus = respHandler.getStatus();
308 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
311 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
313 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
315 String apiVersion = version.substring(1);
317 OperationStatus operationStatus;
320 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
321 } catch (Exception e) {
322 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
323 ErrorCode.AvailabilityError.getValue(),
324 "Exception while communciate with Request DB - Infra Request Lookup", e);
326 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
327 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
328 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
333 if (operationStatus == null) {
334 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
335 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
336 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
337 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
338 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(),
339 "Null response from RequestDB when searching by serviceId");
340 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
345 e2eServiceResponse.setOperation(operationStatus);
347 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
350 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
351 String version) throws ApiException {
352 // TODO should be a new one or the same service instance Id
353 E2EServiceInstanceDeleteRequest e2eDelReq;
355 ObjectMapper mapper = new ObjectMapper();
357 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
359 } catch (Exception e) {
361 logger.debug("Mapping of request to JSON object failed : ", e);
362 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
363 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
364 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
365 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
366 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
367 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
371 String requestId = UUID.randomUUID().toString();
372 RecipeLookupResult recipeLookupResult;
374 // TODO Get the service template model version uuid from AAI.
375 String modelVersionId = null;
376 AAIResourcesClient client = new AAIResourcesClient();
377 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE,
378 e2eDelReq.getGlobalSubscriberId(), e2eDelReq.getServiceType(), instanceIdMap.get(SERVICE_ID));
379 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
380 if (serviceInstanceOpt.isPresent()) {
381 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
383 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
384 } catch (Exception e) {
385 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
386 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
388 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
389 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
390 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
392 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
393 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
394 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
397 if (recipeLookupResult == null) {
398 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
399 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
400 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
401 MsoException.ServiceException, "Recipe does not exist in catalog DB",
402 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
404 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
405 ModelType.service.name(), requestJSON);
406 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
410 RequestClient requestClient;
411 HttpResponse response;
414 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
416 JSONObject jjo = new JSONObject(requestJSON);
417 jjo.put("operationId", requestId);
419 String bpmnRequest = jjo.toString();
421 // Capture audit event
422 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
423 String serviceId = instanceIdMap.get(SERVICE_ID);
424 String serviceInstanceType = e2eDelReq.getServiceType();
425 RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
426 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
427 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
428 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
429 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
430 response = requestClient.post(clientParam);
432 } catch (Exception e) {
433 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
434 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
435 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
436 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
437 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
438 "Exception while communicate with BPMN engine");
439 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
443 if (response == null) {
445 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
446 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
447 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
448 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
449 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
453 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
454 int bpelStatus = respHandler.getStatus();
456 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
459 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
461 String requestId = UUID.randomUUID().toString();
462 E2EServiceInstanceRequest e2eSir;
463 String serviceId = instanceIdMap.get(SERVICE_ID);
465 ObjectMapper mapper = new ObjectMapper();
467 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
469 } catch (Exception e) {
471 logger.debug("Mapping of request to JSON object failed : ", e);
472 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
473 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
474 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
475 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
476 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
477 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
481 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
482 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
484 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
485 } catch (Exception e) {
486 logger.debug("Validation failed: ", e);
488 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
489 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
490 if (requestId != null) {
491 logger.debug("Logging failed message to the database");
493 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
494 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
495 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
499 RecipeLookupResult recipeLookupResult;
501 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
502 } catch (Exception e) {
503 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
504 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
505 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
506 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
507 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
509 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
514 if (recipeLookupResult == null) {
515 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
516 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
517 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
518 MsoException.ServiceException, "Recipe does not exist in catalog DB",
519 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
520 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
525 String serviceInstanceType = e2eSir.getService().getServiceType();
527 RequestClient requestClient;
528 HttpResponse response;
530 String sirRequestJson = convertToString(sir);
533 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
535 // Capture audit event
536 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
537 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
538 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
539 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
540 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
541 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
542 response = requestClient.post(postParam);
543 } catch (Exception e) {
544 logger.debug("Exception while communicate with BPMN engine", e);
545 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
546 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
547 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
549 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
550 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
551 "Exception while communicate with BPMN engine");
552 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
557 if (response == null) {
558 Response getBPMNResp =
559 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
560 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
561 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
562 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
563 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
567 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
568 int bpelStatus = respHandler.getStatus();
570 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
573 private Response processE2EserviceInstances(String requestJSON, Action action,
574 HashMap<String, String> instanceIdMap, String version) throws ApiException {
576 String requestId = UUID.randomUUID().toString();
577 E2EServiceInstanceRequest e2eSir;
579 MsoRequest msoRequest = new MsoRequest();
580 ObjectMapper mapper = new ObjectMapper();
582 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
584 } catch (Exception e) {
586 logger.debug("Mapping of request to JSON object failed : ", e);
587 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
588 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
589 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
590 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
591 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
592 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
596 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
597 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
599 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
600 } catch (Exception e) {
601 logger.debug("Validation failed: ", e);
603 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
604 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
605 if (requestId != null) {
606 logger.debug("Logging failed message to the database");
608 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
609 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
610 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
614 RecipeLookupResult recipeLookupResult;
616 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
617 } catch (Exception e) {
618 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
619 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
620 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
621 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
622 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
623 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
627 if (recipeLookupResult == null) {
628 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
629 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
630 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
631 MsoException.ServiceException, "Recipe does not exist in catalog DB",
632 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
633 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
637 String serviceInstanceType = e2eSir.getService().getServiceType();
639 String serviceId = e2eSir.getService().getServiceId();
640 RequestClient requestClient;
641 HttpResponse response;
643 String sirRequestJson = convertToString(sir);
646 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
648 // Capture audit event
649 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
650 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
651 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
652 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
653 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
654 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
655 response = requestClient.post(parameter);
656 } catch (Exception e) {
657 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
658 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
659 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
661 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
662 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
663 "Exception while communicate with BPMN engine");
664 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
668 if (response == null) {
670 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
671 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
672 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
673 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
674 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
678 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
679 int bpelStatus = respHandler.getStatus();
681 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
684 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
686 String requestId = UUID.randomUUID().toString();
687 E2EServiceInstanceScaleRequest e2eScaleReq;
689 ObjectMapper mapper = new ObjectMapper();
691 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
693 } catch (Exception e) {
695 logger.debug("Mapping of request to JSON object failed : ", e);
696 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
697 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
698 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
699 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
700 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
701 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
705 RecipeLookupResult recipeLookupResult;
707 // TODO Get the service template model version uuid from AAI.
708 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
709 } catch (Exception e) {
710 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
711 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
713 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
714 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
715 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
717 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
718 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
719 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
722 if (recipeLookupResult == null) {
723 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
724 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
726 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
727 MsoException.ServiceException, "Recipe does not exist in catalog DB",
728 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
729 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
730 ModelType.service.name(), requestJSON);
731 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
735 RequestClient requestClient;
736 HttpResponse response;
739 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
741 JSONObject jjo = new JSONObject(requestJSON);
742 jjo.put("operationId", requestId);
744 String bpmnRequest = jjo.toString();
746 // Capture audit event
747 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
748 String serviceId = instanceIdMap.get(SERVICE_ID);
749 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
750 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
751 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
752 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
753 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
754 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
755 response = requestClient.post(postParam);
756 } catch (Exception e) {
757 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
758 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
759 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
761 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
762 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
763 "Exception while communicate with BPMN engine", e);
764 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
768 if (response == null) {
770 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
771 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
772 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
773 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
774 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
778 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
779 int bpelStatus = respHandler.getStatus();
781 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
784 private Response beplStatusUpdate(RequestClient requestClient, ResponseHandler respHandler, int bpelStatus,
787 String apiVersion = version.substring(1);
789 // BPMN accepted the request, the request is in progress
790 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
791 String camundaJSONResponseBody = respHandler.getResponseBody();
792 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
793 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
794 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
796 List<String> variables = new ArrayList<>();
797 variables.add(bpelStatus + "");
798 String camundaJSONResponseBody = respHandler.getResponseBody();
799 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
800 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
801 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
802 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
803 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
804 requestClient.getUrl(), ErrorCode.BusinessProcessError.getValue(),
805 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
806 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
809 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
810 "Request Failed due to BPEL error with HTTP Status= %1",
811 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
812 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
813 ErrorCode.BusinessProcessError.getValue(), "Response from BPEL engine is empty");
814 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
821 * Getting recipes from catalogDb
823 * @param serviceModelUUID the service model version uuid
824 * @param action the action for the service
825 * @return the service recipe result
827 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
829 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
831 if (recipeLookupResult != null) {
832 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
833 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
835 logger.debug("No matching recipe record found");
837 return recipeLookupResult;
841 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
843 * @param serviceModelUUID the service version uuid
844 * @param action the action of the service.
845 * @return the service recipe result.
847 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
849 String defaultServiceModelName = "UUI_DEFAULT";
851 Service defaultServiceRecord =
852 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
853 // set recipe as default generic recipe
854 ServiceRecipe recipe =
855 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
856 // check the service special recipe
857 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
858 ServiceRecipe serviceSpecialRecipe =
859 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
860 if (null != serviceSpecialRecipe) {
861 // set service special recipe.
862 recipe = serviceSpecialRecipe;
866 if (recipe == null) {
869 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
874 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
879 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
881 ServiceInstancesRequest sir = new ServiceInstancesRequest();
883 RequestDetails requestDetails = new RequestDetails();
884 ModelInfo modelInfo = new ModelInfo();
887 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
889 // modelNameVersionId
890 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
892 // String modelInfoValue =
893 // e2eSir.getService().getParameters().getNodeTemplateName();
894 // String[] arrayOfInfo = modelInfoValue.split(":");
895 // String modelName = arrayOfInfo[0];
896 // String modelVersion = arrayOfInfo[1];
898 // TODO: To ensure, if we dont get the values from the UUI
899 String modelName = "voLTE";
900 String modelVersion = "1.0";
902 modelInfo.setModelName(modelName);
905 modelInfo.setModelVersion(modelVersion);
908 modelInfo.setModelType(ModelType.service);
910 // setting modelInfo to requestDetails
911 requestDetails.setModelInfo(modelInfo);
913 SubscriberInfo subscriberInfo = new SubscriberInfo();
915 // globalsubscriberId
916 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
918 // setting subscriberInfo to requestDetails
919 requestDetails.setSubscriberInfo(subscriberInfo);
921 RequestInfo requestInfo = new RequestInfo();
924 requestInfo.setInstanceName(e2eSir.getService().getName());
927 requestInfo.setSource("UUI");
930 requestInfo.setSuppressRollback(true);
932 // setting requestInfo to requestDetails
933 requestDetails.setRequestInfo(requestInfo);
935 RequestParameters requestParameters = new RequestParameters();
937 // subscriptionServiceType
938 requestParameters.setSubscriptionServiceType("MOG");
941 List<Map<String, Object>> userParamList = new ArrayList<>();
942 Map<String, Object> userParamMap = new HashMap<>();
943 // complete json request updated in the camunda
944 userParamMap.put("UUIRequest", requestJSON);
945 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
948 userParamList.add(userParamMap);
949 requestParameters.setUserParams(userParamList);
951 // setting requestParameters to requestDetails
952 requestDetails.setRequestParameters(requestParameters);
954 sir.setRequestDetails(requestDetails);
960 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
961 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
962 int reqVersion = Integer.parseInt(version.substring(1));
964 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
965 } catch (Exception e) {
966 ErrorLoggerInfo errorLoggerInfo =
967 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
968 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
969 ValidateException validateException =
970 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
971 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
973 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
974 ModelType.service.name(), requestJSON);
976 throw validateException;
980 private String convertToString(ServiceInstancesRequest sir) {
981 String returnString = null;
982 // converting to string
983 ObjectMapper mapper = new ObjectMapper();
985 returnString = mapper.writeValueAsString(sir);
986 } catch (IOException e) {
987 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);