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, 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, 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;
255 requestClient = requestClientFactory.getRequestClient(workflowUrl);
257 JSONObject jjo = new JSONObject(requestJSON);
258 String bpmnRequest = jjo.toString();
260 // Capture audit event
261 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
262 String serviceId = instanceIdMap.get("serviceId");
263 String serviceType = e2eCompareModelReq.getServiceType();
264 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
265 .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
266 .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
267 .setALaCarte(false).build();
268 response = requestClient.post(postParam);
269 } catch (Exception e) {
270 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
271 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
272 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
273 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
274 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
275 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
279 if (response == null) {
281 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
282 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
283 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
284 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
285 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
289 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
290 int bpelStatus = respHandler.getStatus();
292 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
295 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
297 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
299 String apiVersion = version.substring(1);
301 OperationStatus operationStatus;
304 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
305 } catch (Exception e) {
306 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
307 ErrorCode.AvailabilityError.getValue(),
308 "Exception while communciate with Request DB - Infra Request Lookup", e);
310 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
311 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
312 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
317 if (operationStatus == null) {
318 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
319 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
320 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
321 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
322 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(),
323 "Null response from RequestDB when searching by serviceId");
324 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
329 e2eServiceResponse.setOperation(operationStatus);
331 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
334 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
335 String version) throws ApiException {
336 // TODO should be a new one or the same service instance Id
337 long startTime = System.currentTimeMillis();
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("serviceId");
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 long startTime = System.currentTimeMillis();
440 E2EServiceInstanceRequest e2eSir;
441 String serviceId = instanceIdMap.get("serviceId");
443 ObjectMapper mapper = new ObjectMapper();
445 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
447 } catch (Exception e) {
449 logger.debug("Mapping of request to JSON object failed : ", e);
450 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
451 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
452 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
453 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
454 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
455 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
459 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
460 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
462 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
463 } catch (Exception e) {
464 logger.debug("Validation failed: ", e);
466 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
467 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
468 if (requestId != null) {
469 logger.debug("Logging failed message to the database");
471 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
472 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
473 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
477 RecipeLookupResult recipeLookupResult;
479 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
480 } catch (Exception e) {
481 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
482 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
483 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
484 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
485 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
487 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
492 if (recipeLookupResult == null) {
493 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
494 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
495 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
496 MsoException.ServiceException, "Recipe does not exist in catalog DB",
497 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
498 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
503 String serviceInstanceType = e2eSir.getService().getServiceType();
505 RequestClient requestClient;
506 HttpResponse response;
508 String sirRequestJson = convertToString(sir);
511 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
513 // Capture audit event
514 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
515 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
516 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
517 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
518 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
519 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
520 response = requestClient.post(postParam);
521 } catch (Exception e) {
522 logger.debug("Exception while communicate with BPMN engine", e);
523 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
524 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
525 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
527 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
528 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
529 "Exception while communicate with BPMN engine");
530 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
535 if (response == null) {
536 Response getBPMNResp =
537 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
538 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
539 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
540 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
541 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
545 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
546 int bpelStatus = respHandler.getStatus();
548 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
551 private Response processE2EserviceInstances(String requestJSON, Action action,
552 HashMap<String, String> instanceIdMap, String version) throws ApiException {
554 String requestId = UUID.randomUUID().toString();
555 long startTime = System.currentTimeMillis();
556 E2EServiceInstanceRequest e2eSir;
558 MsoRequest msoRequest = new MsoRequest();
559 ObjectMapper mapper = new ObjectMapper();
561 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
563 } catch (Exception e) {
565 logger.debug("Mapping of request to JSON object failed : ", e);
566 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
567 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
568 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
569 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
570 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
571 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
575 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
576 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
578 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
579 } catch (Exception e) {
580 logger.debug("Validation failed: ", e);
582 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
583 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
584 if (requestId != null) {
585 logger.debug("Logging failed message to the database");
587 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
588 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
589 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
593 RecipeLookupResult recipeLookupResult;
595 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
596 } catch (Exception e) {
597 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
598 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
599 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
600 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
601 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
602 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
606 if (recipeLookupResult == null) {
607 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
608 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
609 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
610 MsoException.ServiceException, "Recipe does not exist in catalog DB",
611 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
612 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
616 String serviceInstanceType = e2eSir.getService().getServiceType();
618 String serviceId = e2eSir.getService().getServiceId();
619 RequestClient requestClient;
620 HttpResponse response;
622 String sirRequestJson = convertToString(sir);
625 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
627 // Capture audit event
628 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
629 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
630 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
631 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
632 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
633 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
634 response = requestClient.post(parameter);
635 } catch (Exception e) {
636 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
637 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
638 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
640 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
641 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
642 "Exception while communicate with BPMN engine");
643 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
647 if (response == null) {
649 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
650 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
651 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
652 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
653 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
657 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
658 int bpelStatus = respHandler.getStatus();
660 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
663 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
665 String requestId = UUID.randomUUID().toString();
666 long startTime = System.currentTimeMillis();
667 E2EServiceInstanceScaleRequest e2eScaleReq;
669 ObjectMapper mapper = new ObjectMapper();
671 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
673 } catch (Exception e) {
675 logger.debug("Mapping of request to JSON object failed : ", e);
676 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
677 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
678 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
679 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
680 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
681 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
685 RecipeLookupResult recipeLookupResult;
687 // TODO Get the service template model version uuid from AAI.
688 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
689 } catch (Exception e) {
690 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
691 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
693 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
694 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
695 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
697 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
698 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
699 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
702 if (recipeLookupResult == null) {
703 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
704 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
706 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
707 MsoException.ServiceException, "Recipe does not exist in catalog DB",
708 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
709 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
710 ModelType.service.name(), requestJSON);
711 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
715 RequestClient requestClient;
716 HttpResponse response;
719 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
721 JSONObject jjo = new JSONObject(requestJSON);
722 jjo.put("operationId", requestId);
724 String bpmnRequest = jjo.toString();
726 // Capture audit event
727 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
728 String serviceId = instanceIdMap.get("serviceId");
729 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
730 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
731 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
732 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
733 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
734 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
735 response = requestClient.post(postParam);
736 } catch (Exception e) {
737 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
738 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
739 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
741 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
742 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
743 "Exception while communicate with BPMN engine", e);
744 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
748 if (response == null) {
750 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
751 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
752 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
753 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
754 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
758 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
759 int bpelStatus = respHandler.getStatus();
761 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
764 private Response beplStatusUpdate(RequestClient requestClient, ResponseHandler respHandler, int bpelStatus,
767 String apiVersion = version.substring(1);
769 // BPMN accepted the request, the request is in progress
770 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
771 String camundaJSONResponseBody = respHandler.getResponseBody();
772 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
773 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
774 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
776 List<String> variables = new ArrayList<>();
777 variables.add(bpelStatus + "");
778 String camundaJSONResponseBody = respHandler.getResponseBody();
779 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
780 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
781 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
782 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
783 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
784 requestClient.getUrl(), ErrorCode.BusinessProcesssError.getValue(),
785 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
786 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
789 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
790 "Request Failed due to BPEL error with HTTP Status= %1",
791 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
792 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
793 ErrorCode.BusinessProcesssError.getValue(), "Response from BPEL engine is empty");
794 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
801 * Getting recipes from catalogDb
803 * @param serviceModelUUID the service model version uuid
804 * @param action the action for the service
805 * @return the service recipe result
807 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
809 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
811 if (recipeLookupResult != null) {
812 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
813 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
815 logger.debug("No matching recipe record found");
817 return recipeLookupResult;
821 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
823 * @param serviceModelUUID the service version uuid
824 * @param action the action of the service.
825 * @return the service recipe result.
827 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
829 String defaultServiceModelName = "UUI_DEFAULT";
831 Service defaultServiceRecord =
832 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
833 // set recipe as default generic recipe
834 ServiceRecipe recipe =
835 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
836 // check the service special recipe
837 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
838 ServiceRecipe serviceSpecialRecipe =
839 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
840 if (null != serviceSpecialRecipe) {
841 // set service special recipe.
842 recipe = serviceSpecialRecipe;
846 if (recipe == null) {
849 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
854 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
859 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
861 ServiceInstancesRequest sir = new ServiceInstancesRequest();
863 RequestDetails requestDetails = new RequestDetails();
864 ModelInfo modelInfo = new ModelInfo();
867 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
869 // modelNameVersionId
870 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
872 // String modelInfoValue =
873 // e2eSir.getService().getParameters().getNodeTemplateName();
874 // String[] arrayOfInfo = modelInfoValue.split(":");
875 // String modelName = arrayOfInfo[0];
876 // String modelVersion = arrayOfInfo[1];
878 // TODO: To ensure, if we dont get the values from the UUI
879 String modelName = "voLTE";
880 String modelVersion = "1.0";
882 modelInfo.setModelName(modelName);
885 modelInfo.setModelVersion(modelVersion);
888 modelInfo.setModelType(ModelType.service);
890 // setting modelInfo to requestDetails
891 requestDetails.setModelInfo(modelInfo);
893 SubscriberInfo subscriberInfo = new SubscriberInfo();
895 // globalsubscriberId
896 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
898 // setting subscriberInfo to requestDetails
899 requestDetails.setSubscriberInfo(subscriberInfo);
901 RequestInfo requestInfo = new RequestInfo();
904 requestInfo.setInstanceName(e2eSir.getService().getName());
907 requestInfo.setSource("UUI");
910 requestInfo.setSuppressRollback(true);
912 // setting requestInfo to requestDetails
913 requestDetails.setRequestInfo(requestInfo);
915 RequestParameters requestParameters = new RequestParameters();
917 // subscriptionServiceType
918 requestParameters.setSubscriptionServiceType("MOG");
921 List<Map<String, Object>> userParamList = new ArrayList<>();
922 Map<String, Object> userParamMap = new HashMap<>();
923 // complete json request updated in the camunda
924 userParamMap.put("UUIRequest", requestJSON);
925 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
928 userParamList.add(userParamMap);
929 requestParameters.setUserParams(userParamList);
931 // setting requestParameters to requestDetails
932 requestDetails.setRequestParameters(requestParameters);
934 sir.setRequestDetails(requestDetails);
940 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
941 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
942 int reqVersion = Integer.parseInt(version.substring(1));
944 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
945 } catch (Exception e) {
946 ErrorLoggerInfo errorLoggerInfo =
947 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
948 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
949 ValidateException validateException =
950 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
951 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
953 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
954 ModelType.service.name(), requestJSON);
956 throw validateException;
960 private String convertToString(ServiceInstancesRequest sir) {
961 String returnString = null;
962 // converting to string
963 ObjectMapper mapper = new ObjectMapper();
965 returnString = mapper.writeValueAsString(sir);
966 } catch (IOException e) {
967 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);