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: ";
96 private MsoRequest msoRequest;
99 private RequestClientFactory requestClientFactory;
102 private RequestsDbClient requestsDbClient;
105 private CatalogDbClient catalogDbClient;
108 private ResponseBuilder builder;
111 * POST Requests for E2E Service create Instance on a version provided
113 * @throws ApiException
117 @Path("/{version:[vV][3-5]}")
118 @Consumes(MediaType.APPLICATION_JSON)
119 @Produces(MediaType.APPLICATION_JSON)
120 @ApiOperation(value = "Create an E2E Service Instance on a version provided", response = Response.class)
121 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
123 return processE2EserviceInstances(request, Action.createInstance, null, version);
127 * PUT Requests for E2E Service update Instance on a version provided
129 * @throws ApiException
133 @Path("/{version:[vV][3-5]}/{serviceId}")
134 @Consumes(MediaType.APPLICATION_JSON)
135 @Produces(MediaType.APPLICATION_JSON)
136 @ApiOperation(value = "Update an E2E Service Instance on a version provided and serviceId",
137 response = Response.class)
138 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
139 @PathParam("serviceId") String serviceId) throws ApiException {
141 instanceIdMap.put("serviceId", serviceId);
143 return updateE2EserviceInstances(request, Action.updateInstance, instanceIdMap, version);
147 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
149 * @throws ApiException
153 @Path("/{version:[vV][3-5]}/{serviceId}")
154 @Consumes(MediaType.APPLICATION_JSON)
155 @Produces(MediaType.APPLICATION_JSON)
156 @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
157 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
158 @PathParam("serviceId") String serviceId) throws ApiException {
160 instanceIdMap.put("serviceId", serviceId);
162 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
166 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
167 @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId",
168 response = Response.class)
169 @Produces(MediaType.APPLICATION_JSON)
170 public Response getE2EServiceInstances(@PathParam("serviceId") String serviceId,
171 @PathParam("version") String version, @PathParam("operationId") String operationId) {
172 return getE2EServiceInstance(serviceId, operationId, version);
176 * Scale Requests for E2E Service scale Instance on a specified version
178 * @throws ApiException
182 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
183 @Consumes(MediaType.APPLICATION_JSON)
184 @Produces(MediaType.APPLICATION_JSON)
185 @ApiOperation(value = "Scale E2E Service Instance on a specified version", response = Response.class)
186 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
187 @PathParam("serviceId") String serviceId) throws ApiException {
189 logger.debug("------------------scale begin------------------");
190 instanceIdMap.put("serviceId", serviceId);
191 return scaleE2EserviceInstances(request, Action.scaleInstance, instanceIdMap, version);
195 * GET Requests for Comparing model of service instance with target version
197 * @throws ApiException
201 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
202 @Consumes(MediaType.APPLICATION_JSON)
203 @Produces(MediaType.APPLICATION_JSON)
205 value = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
206 response = Response.class)
207 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
208 @PathParam("version") String version) throws ApiException {
210 instanceIdMap.put("serviceId", serviceId);
212 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
215 private Response compareModelwithTargetVersion(String requestJSON, Action action,
216 HashMap<String, String> instanceIdMap, String version) throws ApiException {
218 String requestId = UUID.randomUUID().toString();
219 long startTime = System.currentTimeMillis();
221 CompareModelsRequest e2eCompareModelReq;
223 ObjectMapper mapper = new ObjectMapper();
225 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
227 } catch (Exception e) {
229 logger.debug("Mapping of request to JSON object failed : ", e);
230 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
231 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
232 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
233 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
234 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
235 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
240 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, startTime, action, version);
244 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
245 String requestId, long startTime, Action action, String version) throws ApiException {
247 // Define RecipeLookupResult info here instead of query DB for efficiency
248 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
249 int recipeTimeout = 180;
251 RequestClient requestClient;
252 HttpResponse response;
254 long subStartTime = System.currentTimeMillis();
257 requestClient = requestClientFactory.getRequestClient(workflowUrl);
259 JSONObject jjo = new JSONObject(requestJSON);
260 String bpmnRequest = jjo.toString();
262 // Capture audit event
263 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
264 String serviceId = instanceIdMap.get("serviceId");
265 String serviceType = e2eCompareModelReq.getServiceType();
266 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
267 .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
268 .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
269 .setALaCarte(false).build();
270 response = requestClient.post(postParam);
271 } catch (Exception e) {
272 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
273 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
274 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
275 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
276 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
277 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
281 if (response == null) {
283 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
284 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
285 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
286 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
287 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
291 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
292 int bpelStatus = respHandler.getStatus();
294 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
298 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
300 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
302 String apiVersion = version.substring(1);
304 long startTime = System.currentTimeMillis();
306 OperationStatus operationStatus;
309 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
310 } catch (Exception e) {
311 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
312 ErrorCode.AvailabilityError.getValue(),
313 "Exception while communciate with Request DB - Infra Request Lookup", e);
315 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
316 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
317 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
322 if (operationStatus == null) {
323 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
324 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
325 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
326 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
327 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(),
328 "Null response from RequestDB when searching by serviceId");
329 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
334 e2eServiceResponse.setOperation(operationStatus);
336 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
339 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
340 String version) throws ApiException {
341 // TODO should be a new one or the same service instance Id
342 long startTime = System.currentTimeMillis();
343 E2EServiceInstanceDeleteRequest e2eDelReq;
345 ObjectMapper mapper = new ObjectMapper();
347 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
349 } catch (Exception e) {
351 logger.debug("Mapping of request to JSON object failed : ", e);
352 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
353 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
354 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
355 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
356 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
357 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
361 String requestId = UUID.randomUUID().toString();
362 RecipeLookupResult recipeLookupResult;
364 // TODO Get the service template model version uuid from AAI.
365 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
366 } catch (Exception e) {
367 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
368 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
370 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
371 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
372 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
374 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
375 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
376 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
379 if (recipeLookupResult == null) {
380 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
381 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
382 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
383 MsoException.ServiceException, "Recipe does not exist in catalog DB",
384 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
386 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
387 ModelType.service.name(), requestJSON);
388 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
392 RequestClient requestClient;
393 HttpResponse response;
395 long subStartTime = System.currentTimeMillis();
397 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
399 JSONObject jjo = new JSONObject(requestJSON);
400 jjo.put("operationId", requestId);
402 String bpmnRequest = jjo.toString();
404 // Capture audit event
405 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
406 String serviceId = instanceIdMap.get("serviceId");
407 String serviceInstanceType = e2eDelReq.getServiceType();
408 RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
409 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
410 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
411 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
412 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
413 response = requestClient.post(clientParam);
415 } catch (Exception e) {
416 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
417 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
418 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
419 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
420 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
421 "Exception while communicate with BPMN engine");
422 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
426 if (response == null) {
428 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
429 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
430 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
431 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
432 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
436 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
437 int bpelStatus = respHandler.getStatus();
439 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
443 private Response updateE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
444 String version) throws ApiException {
446 String requestId = UUID.randomUUID().toString();
447 long startTime = System.currentTimeMillis();
448 E2EServiceInstanceRequest e2eSir;
449 String serviceId = instanceIdMap.get("serviceId");
451 ObjectMapper mapper = new ObjectMapper();
453 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
455 } catch (Exception e) {
457 logger.debug("Mapping of request to JSON object failed : ", e);
458 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
459 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
460 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
461 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
462 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
463 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
467 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
468 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
470 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
471 } catch (Exception e) {
472 logger.debug("Validation failed: ", e);
474 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
475 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
476 if (requestId != null) {
477 logger.debug("Logging failed message to the database");
479 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
480 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
481 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
485 RecipeLookupResult recipeLookupResult;
487 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
488 } catch (Exception e) {
489 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
490 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
491 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
492 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
493 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
495 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
500 if (recipeLookupResult == null) {
501 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
502 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
503 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
504 MsoException.ServiceException, "Recipe does not exist in catalog DB",
505 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
506 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
511 String serviceInstanceType = e2eSir.getService().getServiceType();
513 RequestClient requestClient;
514 HttpResponse response;
516 long subStartTime = System.currentTimeMillis();
517 String sirRequestJson = convertToString(sir);
520 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
522 // Capture audit event
523 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
524 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
525 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
526 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
527 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
528 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
529 response = requestClient.post(postParam);
530 } catch (Exception e) {
531 logger.debug("Exception while communicate with BPMN engine", e);
532 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
533 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
534 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
536 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
537 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
538 "Exception while communicate with BPMN engine");
539 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
544 if (response == null) {
545 Response getBPMNResp =
546 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
547 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
548 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
549 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
550 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
554 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
555 int bpelStatus = respHandler.getStatus();
557 return beplStatusUpdate(serviceId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
561 private Response processE2EserviceInstances(String requestJSON, Action action,
562 HashMap<String, String> instanceIdMap, String version) throws ApiException {
564 String requestId = UUID.randomUUID().toString();
565 long startTime = System.currentTimeMillis();
566 E2EServiceInstanceRequest e2eSir;
568 MsoRequest msoRequest = new MsoRequest();
569 ObjectMapper mapper = new ObjectMapper();
571 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
573 } catch (Exception e) {
575 logger.debug("Mapping of request to JSON object failed : ", e);
576 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
577 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
578 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
579 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
580 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
581 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
585 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
586 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
588 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
589 } catch (Exception e) {
590 logger.debug("Validation failed: ", e);
592 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
593 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
594 if (requestId != null) {
595 logger.debug("Logging failed message to the database");
597 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
598 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
599 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
603 RecipeLookupResult recipeLookupResult;
605 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
606 } catch (Exception e) {
607 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
608 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
609 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
610 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
611 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
612 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
616 if (recipeLookupResult == null) {
617 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
618 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
619 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
620 MsoException.ServiceException, "Recipe does not exist in catalog DB",
621 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
622 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
626 String serviceInstanceType = e2eSir.getService().getServiceType();
628 String serviceId = "";
629 RequestClient requestClient;
630 HttpResponse response;
632 long subStartTime = System.currentTimeMillis();
633 String sirRequestJson = convertToString(sir);
636 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
638 // Capture audit event
639 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
640 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
641 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
642 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
643 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
644 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
645 response = requestClient.post(parameter);
646 } catch (Exception e) {
647 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
648 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
649 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
651 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
652 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
653 "Exception while communicate with BPMN engine");
654 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
658 if (response == null) {
660 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
661 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
662 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
663 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
664 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
668 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
669 int bpelStatus = respHandler.getStatus();
671 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
675 private Response scaleE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
676 String version) throws ApiException {
678 String requestId = UUID.randomUUID().toString();
679 long startTime = System.currentTimeMillis();
680 E2EServiceInstanceScaleRequest e2eScaleReq;
682 ObjectMapper mapper = new ObjectMapper();
684 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
686 } catch (Exception e) {
688 logger.debug("Mapping of request to JSON object failed : ", e);
689 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
690 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
691 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
692 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
693 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
694 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
698 RecipeLookupResult recipeLookupResult;
700 // TODO Get the service template model version uuid from AAI.
701 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
702 } catch (Exception e) {
703 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
704 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
706 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
707 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
708 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
710 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
711 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
712 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
715 if (recipeLookupResult == null) {
716 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
717 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
719 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
720 MsoException.ServiceException, "Recipe does not exist in catalog DB",
721 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
722 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
723 ModelType.service.name(), requestJSON);
724 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
728 RequestClient requestClient;
729 HttpResponse response;
731 long subStartTime = System.currentTimeMillis();
733 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
735 JSONObject jjo = new JSONObject(requestJSON);
736 jjo.put("operationId", requestId);
738 String bpmnRequest = jjo.toString();
740 // Capture audit event
741 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
742 String serviceId = instanceIdMap.get("serviceId");
743 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
744 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
745 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
746 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
747 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
748 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
749 response = requestClient.post(postParam);
750 } catch (Exception e) {
751 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
752 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
753 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
755 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
756 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
757 "Exception while communicate with BPMN engine", e);
758 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
762 if (response == null) {
764 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
765 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
766 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
767 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
768 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
772 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
773 int bpelStatus = respHandler.getStatus();
775 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
779 private Response beplStatusUpdate(String serviceId, long startTime, RequestClient requestClient,
780 ResponseHandler respHandler, int bpelStatus, Action action, HashMap<String, String> instanceIdMap,
783 String apiVersion = version.substring(1);
785 // BPMN accepted the request, the request is in progress
786 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
787 String camundaJSONResponseBody = respHandler.getResponseBody();
788 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
789 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
790 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
792 List<String> variables = new ArrayList<>();
793 variables.add(bpelStatus + "");
794 String camundaJSONResponseBody = respHandler.getResponseBody();
795 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
796 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
797 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
798 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
799 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
800 requestClient.getUrl(), ErrorCode.BusinessProcesssError.getValue(),
801 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
802 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
805 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
806 "Request Failed due to BPEL error with HTTP Status= %1",
807 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
808 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
809 ErrorCode.BusinessProcesssError.getValue(), "Response from BPEL engine is empty");
810 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
817 * Getting recipes from catalogDb
819 * @param serviceModelUUID the service model version uuid
820 * @param action the action for the service
821 * @return the service recipe result
823 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
825 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
827 if (recipeLookupResult != null) {
828 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
829 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
831 logger.debug("No matching recipe record found");
833 return recipeLookupResult;
837 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
839 * @param serviceModelUUID the service version uuid
840 * @param action the action of the service.
841 * @return the service recipe result.
843 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
845 String defaultServiceModelName = "UUI_DEFAULT";
847 Service defaultServiceRecord =
848 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
849 // set recipe as default generic recipe
850 ServiceRecipe recipe =
851 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
852 // check the service special recipe
853 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
854 ServiceRecipe serviceSpecialRecipe =
855 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
856 if (null != serviceSpecialRecipe) {
857 // set service special recipe.
858 recipe = serviceSpecialRecipe;
862 if (recipe == null) {
865 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
870 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
875 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
877 ServiceInstancesRequest sir = new ServiceInstancesRequest();
879 String returnString = null;
880 RequestDetails requestDetails = new RequestDetails();
881 ModelInfo modelInfo = new ModelInfo();
884 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
886 // modelNameVersionId
887 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
889 // String modelInfoValue =
890 // e2eSir.getService().getParameters().getNodeTemplateName();
891 // String[] arrayOfInfo = modelInfoValue.split(":");
892 // String modelName = arrayOfInfo[0];
893 // String modelVersion = arrayOfInfo[1];
895 // TODO: To ensure, if we dont get the values from the UUI
896 String modelName = "voLTE";
897 String modelVersion = "1.0";
899 modelInfo.setModelName(modelName);
902 modelInfo.setModelVersion(modelVersion);
905 modelInfo.setModelType(ModelType.service);
907 // setting modelInfo to requestDetails
908 requestDetails.setModelInfo(modelInfo);
910 SubscriberInfo subscriberInfo = new SubscriberInfo();
912 // globalsubscriberId
913 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
915 // setting subscriberInfo to requestDetails
916 requestDetails.setSubscriberInfo(subscriberInfo);
918 RequestInfo requestInfo = new RequestInfo();
921 requestInfo.setInstanceName(e2eSir.getService().getName());
924 requestInfo.setSource("UUI");
927 requestInfo.setSuppressRollback(true);
929 // setting requestInfo to requestDetails
930 requestDetails.setRequestInfo(requestInfo);
932 RequestParameters requestParameters = new RequestParameters();
934 // subscriptionServiceType
935 requestParameters.setSubscriptionServiceType("MOG");
938 List<Map<String, Object>> userParamList = new ArrayList<>();
939 Map<String, Object> userParamMap = new HashMap<>();
940 // complete json request updated in the camunda
941 userParamMap.put("UUIRequest", requestJSON);
942 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
945 userParamList.add(userParamMap);
946 requestParameters.setUserParams(userParamList);
948 // setting requestParameters to requestDetails
949 requestDetails.setRequestParameters(requestParameters);
951 sir.setRequestDetails(requestDetails);
957 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
958 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
959 int reqVersion = Integer.parseInt(version.substring(1));
961 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
962 } catch (Exception e) {
963 ErrorLoggerInfo errorLoggerInfo =
964 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
965 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
966 ValidateException validateException =
967 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
968 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
970 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
971 ModelType.service.name(), requestJSON);
973 throw validateException;
977 private String convertToString(ServiceInstancesRequest sir) {
978 String returnString = null;
979 // converting to string
980 ObjectMapper mapper = new ObjectMapper();
982 returnString = mapper.writeValueAsString(sir);
983 } catch (IOException e) {
984 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);