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;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.UUID;
31 import javax.ws.rs.Consumes;
32 import javax.ws.rs.DELETE;
33 import javax.ws.rs.GET;
34 import javax.ws.rs.POST;
35 import javax.ws.rs.PUT;
36 import javax.ws.rs.Path;
37 import javax.ws.rs.PathParam;
38 import javax.ws.rs.Produces;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import org.onap.so.logger.LoggingAnchor;
42 import org.apache.http.HttpResponse;
43 import org.apache.http.HttpStatus;
44 import org.json.JSONObject;
45 import org.onap.so.apihandler.common.ErrorNumbers;
46 import org.onap.so.apihandler.common.RequestClient;
47 import org.onap.so.apihandler.common.RequestClientFactory;
48 import org.onap.so.apihandler.common.RequestClientParameter;
49 import org.onap.so.apihandler.common.ResponseBuilder;
50 import org.onap.so.apihandler.common.ResponseHandler;
51 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.CompareModelsRequest;
52 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
53 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
54 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceScaleRequest;
55 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
56 import org.onap.so.apihandlerinfra.exceptions.ApiException;
57 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
58 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
59 import org.onap.so.constants.Status;
60 import org.onap.so.db.catalog.beans.Service;
61 import org.onap.so.db.catalog.beans.ServiceRecipe;
62 import org.onap.so.db.catalog.client.CatalogDbClient;
63 import org.onap.so.db.request.beans.OperationStatus;
64 import org.onap.so.db.request.client.RequestsDbClient;
65 import org.onap.so.logger.ErrorCode;
66 import org.onap.so.logger.MessageEnum;
67 import org.onap.so.serviceinstancebeans.ModelInfo;
68 import org.onap.so.serviceinstancebeans.ModelType;
69 import org.onap.so.serviceinstancebeans.RequestDetails;
70 import org.onap.so.serviceinstancebeans.RequestInfo;
71 import org.onap.so.serviceinstancebeans.RequestParameters;
72 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
73 import org.onap.so.serviceinstancebeans.SubscriberInfo;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.stereotype.Component;
78 import com.fasterxml.jackson.databind.ObjectMapper;
79 import io.swagger.annotations.Api;
80 import io.swagger.annotations.ApiOperation;
84 @Path("/onap/so/infra/e2eServiceInstances")
85 @Api(value = "/onap/so/infra/e2eServiceInstances", description = "API Requests for E2E Service Instances")
86 public class E2EServiceInstances {
88 private HashMap<String, String> instanceIdMap = new HashMap<>();
89 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
91 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
93 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
95 private static final String SERVICE_ID = "serviceId";
98 private MsoRequest msoRequest;
101 private RequestClientFactory requestClientFactory;
104 private RequestsDbClient requestsDbClient;
107 private CatalogDbClient catalogDbClient;
110 private ResponseBuilder builder;
113 * POST Requests for E2E Service create Instance on a version provided
115 * @throws ApiException
119 @Path("/{version:[vV][3-5]}")
120 @Consumes(MediaType.APPLICATION_JSON)
121 @Produces(MediaType.APPLICATION_JSON)
122 @ApiOperation(value = "Create an E2E Service Instance on a version provided", response = Response.class)
123 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
125 return processE2EserviceInstances(request, Action.createInstance, null, version);
129 * PUT Requests for E2E Service update Instance on a version provided
131 * @throws ApiException
135 @Path("/{version:[vV][3-5]}/{serviceId}")
136 @Consumes(MediaType.APPLICATION_JSON)
137 @Produces(MediaType.APPLICATION_JSON)
138 @ApiOperation(value = "Update an E2E Service Instance on a version provided and serviceId",
139 response = Response.class)
140 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
141 @PathParam("serviceId") String serviceId) throws ApiException {
143 instanceIdMap.put(SERVICE_ID, serviceId);
145 return updateE2EserviceInstances(request, Action.updateInstance, version);
149 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
151 * @throws ApiException
155 @Path("/{version:[vV][3-5]}/{serviceId}")
156 @Consumes(MediaType.APPLICATION_JSON)
157 @Produces(MediaType.APPLICATION_JSON)
158 @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
159 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
160 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
162 instanceIdMap.put(SERVICE_ID, serviceId);
164 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
168 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
169 @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId",
170 response = Response.class)
171 @Produces(MediaType.APPLICATION_JSON)
172 public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
173 @PathParam("version") String version, @PathParam("operationId") String operationId) {
174 return getE2EServiceInstance(serviceId, operationId, version);
178 * Scale Requests for E2E Service scale Instance on a specified version
180 * @throws ApiException
184 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
185 @Consumes(MediaType.APPLICATION_JSON)
186 @Produces(MediaType.APPLICATION_JSON)
187 @ApiOperation(value = "Scale E2E Service Instance on a specified version", response = Response.class)
188 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
189 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
191 logger.debug("------------------scale begin------------------");
192 instanceIdMap.put(SERVICE_ID, serviceId);
193 return scaleE2EserviceInstances(request, Action.scaleInstance, version);
197 * GET Requests for Comparing model of service instance with target version
199 * @throws ApiException
203 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
204 @Consumes(MediaType.APPLICATION_JSON)
205 @Produces(MediaType.APPLICATION_JSON)
207 value = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
208 response = Response.class)
209 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
210 @PathParam("version") String version) throws ApiException {
212 instanceIdMap.put(SERVICE_ID, serviceId);
214 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
217 private Response compareModelwithTargetVersion(String requestJSON, Action action,
218 HashMap<String, String> instanceIdMap, String version) throws ApiException {
220 String requestId = UUID.randomUUID().toString();
222 CompareModelsRequest e2eCompareModelReq;
224 ObjectMapper mapper = new ObjectMapper();
226 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
228 } catch (Exception e) {
230 logger.debug("Mapping of request to JSON object failed : ", e);
231 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
232 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
233 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
234 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
235 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
236 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
241 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
245 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
246 String requestId, Action action, String version) throws ApiException {
248 // Define RecipeLookupResult info here instead of query DB for efficiency
249 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
250 int recipeTimeout = 180;
252 RequestClient requestClient;
253 HttpResponse response;
256 requestClient = requestClientFactory.getRequestClient(workflowUrl);
258 JSONObject jjo = new JSONObject(requestJSON);
259 String bpmnRequest = jjo.toString();
261 // Capture audit event
262 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
263 String serviceId = instanceIdMap.get(SERVICE_ID);
264 String serviceType = e2eCompareModelReq.getServiceType();
265 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
266 .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
267 .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
268 .setALaCarte(false).build();
269 response = requestClient.post(postParam);
270 } catch (Exception e) {
271 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
272 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
273 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
274 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
275 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
276 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
280 if (response == null) {
282 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
283 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
284 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
285 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
286 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
290 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
291 int bpelStatus = respHandler.getStatus();
293 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
296 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
298 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
300 String apiVersion = version.substring(1);
302 OperationStatus operationStatus;
305 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
306 } catch (Exception e) {
307 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
308 ErrorCode.AvailabilityError.getValue(),
309 "Exception while communciate with Request DB - Infra Request Lookup", e);
311 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
312 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
313 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
318 if (operationStatus == null) {
319 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
320 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
321 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
322 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
323 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(),
324 "Null response from RequestDB when searching by serviceId");
325 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
330 e2eServiceResponse.setOperation(operationStatus);
332 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
335 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
336 String version) throws ApiException {
337 // TODO should be a new one or the same service instance Id
338 E2EServiceInstanceDeleteRequest e2eDelReq;
340 ObjectMapper mapper = new ObjectMapper();
342 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
344 } catch (Exception e) {
346 logger.debug("Mapping of request to JSON object failed : ", e);
347 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
348 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
349 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
350 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
351 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
352 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
356 String requestId = UUID.randomUUID().toString();
357 RecipeLookupResult recipeLookupResult;
359 // TODO Get the service template model version uuid from AAI.
360 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
361 } catch (Exception e) {
362 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
363 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
365 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
366 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
367 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
369 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
370 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
371 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
374 if (recipeLookupResult == null) {
375 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
376 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
377 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
378 MsoException.ServiceException, "Recipe does not exist in catalog DB",
379 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
381 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
382 ModelType.service.name(), requestJSON);
383 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
387 RequestClient requestClient;
388 HttpResponse response;
391 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
393 JSONObject jjo = new JSONObject(requestJSON);
394 jjo.put("operationId", requestId);
396 String bpmnRequest = jjo.toString();
398 // Capture audit event
399 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
400 String serviceId = instanceIdMap.get(SERVICE_ID);
401 String serviceInstanceType = e2eDelReq.getServiceType();
402 RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
403 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
404 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
405 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
406 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
407 response = requestClient.post(clientParam);
409 } catch (Exception e) {
410 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
411 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
412 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
413 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
414 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
415 "Exception while communicate with BPMN engine");
416 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
420 if (response == null) {
422 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
423 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
424 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
425 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
426 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
430 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
431 int bpelStatus = respHandler.getStatus();
433 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
436 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
438 String requestId = UUID.randomUUID().toString();
439 E2EServiceInstanceRequest e2eSir;
440 String serviceId = instanceIdMap.get(SERVICE_ID);
442 ObjectMapper mapper = new ObjectMapper();
444 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
446 } catch (Exception e) {
448 logger.debug("Mapping of request to JSON object failed : ", e);
449 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
450 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
451 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
452 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
453 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
454 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
458 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
459 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
461 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
462 } catch (Exception e) {
463 logger.debug("Validation failed: ", e);
465 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
466 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
467 if (requestId != null) {
468 logger.debug("Logging failed message to the database");
470 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
471 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
472 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
476 RecipeLookupResult recipeLookupResult;
478 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
479 } catch (Exception e) {
480 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
481 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
482 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
483 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
484 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
486 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
491 if (recipeLookupResult == null) {
492 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
493 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
494 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
495 MsoException.ServiceException, "Recipe does not exist in catalog DB",
496 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
497 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
502 String serviceInstanceType = e2eSir.getService().getServiceType();
504 RequestClient requestClient;
505 HttpResponse response;
507 String sirRequestJson = convertToString(sir);
510 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
512 // Capture audit event
513 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
514 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
515 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
516 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
517 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
518 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
519 response = requestClient.post(postParam);
520 } catch (Exception e) {
521 logger.debug("Exception while communicate with BPMN engine", e);
522 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
523 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
524 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
526 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
527 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
528 "Exception while communicate with BPMN engine");
529 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
534 if (response == null) {
535 Response getBPMNResp =
536 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
537 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
538 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
539 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
540 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
544 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
545 int bpelStatus = respHandler.getStatus();
547 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
550 private Response processE2EserviceInstances(String requestJSON, Action action,
551 HashMap<String, String> instanceIdMap, String version) throws ApiException {
553 String requestId = UUID.randomUUID().toString();
554 E2EServiceInstanceRequest e2eSir;
556 MsoRequest msoRequest = new MsoRequest();
557 ObjectMapper mapper = new ObjectMapper();
559 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
561 } catch (Exception e) {
563 logger.debug("Mapping of request to JSON object failed : ", e);
564 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
565 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
566 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
567 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
568 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
569 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
573 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
574 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
576 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
577 } catch (Exception e) {
578 logger.debug("Validation failed: ", e);
580 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
581 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
582 if (requestId != null) {
583 logger.debug("Logging failed message to the database");
585 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
586 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
587 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
591 RecipeLookupResult recipeLookupResult;
593 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
594 } catch (Exception e) {
595 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
596 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
597 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
598 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
599 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
600 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
604 if (recipeLookupResult == null) {
605 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
606 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
607 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
608 MsoException.ServiceException, "Recipe does not exist in catalog DB",
609 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
610 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
614 String serviceInstanceType = e2eSir.getService().getServiceType();
616 String serviceId = e2eSir.getService().getServiceId();
617 RequestClient requestClient;
618 HttpResponse response;
620 String sirRequestJson = convertToString(sir);
623 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
625 // Capture audit event
626 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
627 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
628 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
629 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
630 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
631 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
632 response = requestClient.post(parameter);
633 } catch (Exception e) {
634 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
635 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
636 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
638 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
639 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
640 "Exception while communicate with BPMN engine");
641 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
645 if (response == null) {
647 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
648 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
649 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
650 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
651 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
655 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
656 int bpelStatus = respHandler.getStatus();
658 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
661 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
663 String requestId = UUID.randomUUID().toString();
664 E2EServiceInstanceScaleRequest e2eScaleReq;
666 ObjectMapper mapper = new ObjectMapper();
668 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
670 } catch (Exception e) {
672 logger.debug("Mapping of request to JSON object failed : ", e);
673 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
674 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
675 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
676 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
677 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
678 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
682 RecipeLookupResult recipeLookupResult;
684 // TODO Get the service template model version uuid from AAI.
685 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
686 } catch (Exception e) {
687 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
688 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
690 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
691 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
692 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
694 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
695 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
696 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
699 if (recipeLookupResult == null) {
700 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
701 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
703 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
704 MsoException.ServiceException, "Recipe does not exist in catalog DB",
705 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
706 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
707 ModelType.service.name(), requestJSON);
708 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
712 RequestClient requestClient;
713 HttpResponse response;
716 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
718 JSONObject jjo = new JSONObject(requestJSON);
719 jjo.put("operationId", requestId);
721 String bpmnRequest = jjo.toString();
723 // Capture audit event
724 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
725 String serviceId = instanceIdMap.get(SERVICE_ID);
726 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
727 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
728 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
729 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
730 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
731 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
732 response = requestClient.post(postParam);
733 } catch (Exception e) {
734 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
735 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
736 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
738 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
739 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
740 "Exception while communicate with BPMN engine", e);
741 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
745 if (response == null) {
747 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
748 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
749 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
750 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
751 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
755 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
756 int bpelStatus = respHandler.getStatus();
758 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
761 private Response beplStatusUpdate(RequestClient requestClient, ResponseHandler respHandler, int bpelStatus,
764 String apiVersion = version.substring(1);
766 // BPMN accepted the request, the request is in progress
767 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
768 String camundaJSONResponseBody = respHandler.getResponseBody();
769 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
770 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
771 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
773 List<String> variables = new ArrayList<>();
774 variables.add(bpelStatus + "");
775 String camundaJSONResponseBody = respHandler.getResponseBody();
776 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
777 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
778 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
779 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
780 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
781 requestClient.getUrl(), ErrorCode.BusinessProcesssError.getValue(),
782 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
783 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
786 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
787 "Request Failed due to BPEL error with HTTP Status= %1",
788 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
789 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
790 ErrorCode.BusinessProcesssError.getValue(), "Response from BPEL engine is empty");
791 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
798 * Getting recipes from catalogDb
800 * @param serviceModelUUID the service model version uuid
801 * @param action the action for the service
802 * @return the service recipe result
804 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
806 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
808 if (recipeLookupResult != null) {
809 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
810 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
812 logger.debug("No matching recipe record found");
814 return recipeLookupResult;
818 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
820 * @param serviceModelUUID the service version uuid
821 * @param action the action of the service.
822 * @return the service recipe result.
824 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
826 String defaultServiceModelName = "UUI_DEFAULT";
828 Service defaultServiceRecord =
829 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
830 // set recipe as default generic recipe
831 ServiceRecipe recipe =
832 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
833 // check the service special recipe
834 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
835 ServiceRecipe serviceSpecialRecipe =
836 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
837 if (null != serviceSpecialRecipe) {
838 // set service special recipe.
839 recipe = serviceSpecialRecipe;
843 if (recipe == null) {
846 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
851 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
856 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
858 ServiceInstancesRequest sir = new ServiceInstancesRequest();
860 RequestDetails requestDetails = new RequestDetails();
861 ModelInfo modelInfo = new ModelInfo();
864 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
866 // modelNameVersionId
867 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
869 // String modelInfoValue =
870 // e2eSir.getService().getParameters().getNodeTemplateName();
871 // String[] arrayOfInfo = modelInfoValue.split(":");
872 // String modelName = arrayOfInfo[0];
873 // String modelVersion = arrayOfInfo[1];
875 // TODO: To ensure, if we dont get the values from the UUI
876 String modelName = "voLTE";
877 String modelVersion = "1.0";
879 modelInfo.setModelName(modelName);
882 modelInfo.setModelVersion(modelVersion);
885 modelInfo.setModelType(ModelType.service);
887 // setting modelInfo to requestDetails
888 requestDetails.setModelInfo(modelInfo);
890 SubscriberInfo subscriberInfo = new SubscriberInfo();
892 // globalsubscriberId
893 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
895 // setting subscriberInfo to requestDetails
896 requestDetails.setSubscriberInfo(subscriberInfo);
898 RequestInfo requestInfo = new RequestInfo();
901 requestInfo.setInstanceName(e2eSir.getService().getName());
904 requestInfo.setSource("UUI");
907 requestInfo.setSuppressRollback(true);
909 // setting requestInfo to requestDetails
910 requestDetails.setRequestInfo(requestInfo);
912 RequestParameters requestParameters = new RequestParameters();
914 // subscriptionServiceType
915 requestParameters.setSubscriptionServiceType("MOG");
918 List<Map<String, Object>> userParamList = new ArrayList<>();
919 Map<String, Object> userParamMap = new HashMap<>();
920 // complete json request updated in the camunda
921 userParamMap.put("UUIRequest", requestJSON);
922 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
925 userParamList.add(userParamMap);
926 requestParameters.setUserParams(userParamList);
928 // setting requestParameters to requestDetails
929 requestDetails.setRequestParameters(requestParameters);
931 sir.setRequestDetails(requestDetails);
937 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
938 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
939 int reqVersion = Integer.parseInt(version.substring(1));
941 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
942 } catch (Exception e) {
943 ErrorLoggerInfo errorLoggerInfo =
944 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
945 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
946 ValidateException validateException =
947 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
948 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
950 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
951 ModelType.service.name(), requestJSON);
953 throw validateException;
957 private String convertToString(ServiceInstancesRequest sir) {
958 String returnString = null;
959 // converting to string
960 ObjectMapper mapper = new ObjectMapper();
962 returnString = mapper.writeValueAsString(sir);
963 } catch (IOException e) {
964 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);