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.db.catalog.beans.Service;
60 import org.onap.so.db.catalog.beans.ServiceRecipe;
61 import org.onap.so.db.catalog.client.CatalogDbClient;
62 import org.onap.so.db.request.beans.OperationStatus;
63 import org.onap.so.db.request.client.RequestsDbClient;
64 import org.onap.so.logger.ErrorCode;
65 import org.onap.so.logger.MessageEnum;
66 import org.onap.so.serviceinstancebeans.ModelInfo;
67 import org.onap.so.serviceinstancebeans.ModelType;
68 import org.onap.so.serviceinstancebeans.RequestDetails;
69 import org.onap.so.serviceinstancebeans.RequestInfo;
70 import org.onap.so.serviceinstancebeans.RequestParameters;
71 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
72 import org.onap.so.serviceinstancebeans.SubscriberInfo;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75 import org.springframework.beans.factory.annotation.Autowired;
76 import org.springframework.stereotype.Component;
77 import com.fasterxml.jackson.databind.ObjectMapper;
78 import io.swagger.annotations.Api;
79 import io.swagger.annotations.ApiOperation;
83 @Path("/onap/so/infra/e2eServiceInstances")
84 @Api(value = "/onap/so/infra/e2eServiceInstances", description = "API Requests for E2E Service Instances")
85 public class E2EServiceInstances {
87 private HashMap<String, String> instanceIdMap = new HashMap<>();
88 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
90 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
92 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
95 private MsoRequest msoRequest;
98 private RequestClientFactory requestClientFactory;
101 private RequestsDbClient requestsDbClient;
104 private CatalogDbClient catalogDbClient;
107 private ResponseBuilder builder;
110 * POST Requests for E2E Service create Instance on a version provided
112 * @throws ApiException
116 @Path("/{version:[vV][3-5]}")
117 @Consumes(MediaType.APPLICATION_JSON)
118 @Produces(MediaType.APPLICATION_JSON)
119 @ApiOperation(value = "Create an E2E Service Instance on a version provided", response = Response.class)
120 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
122 return processE2EserviceInstances(request, Action.createInstance, null, version);
126 * PUT Requests for E2E Service update Instance on a version provided
128 * @throws ApiException
132 @Path("/{version:[vV][3-5]}/{serviceId}")
133 @Consumes(MediaType.APPLICATION_JSON)
134 @Produces(MediaType.APPLICATION_JSON)
135 @ApiOperation(value = "Update an E2E Service Instance on a version provided and serviceId",
136 response = Response.class)
137 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
138 @PathParam("serviceId") String serviceId) throws ApiException {
140 instanceIdMap.put("serviceId", serviceId);
142 return updateE2EserviceInstances(request, Action.updateInstance, instanceIdMap, version);
146 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
148 * @throws ApiException
152 @Path("/{version:[vV][3-5]}/{serviceId}")
153 @Consumes(MediaType.APPLICATION_JSON)
154 @Produces(MediaType.APPLICATION_JSON)
155 @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
156 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
157 @PathParam("serviceId") String serviceId) throws ApiException {
159 instanceIdMap.put("serviceId", serviceId);
161 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
165 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
166 @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId",
167 response = Response.class)
168 @Produces(MediaType.APPLICATION_JSON)
169 public Response getE2EServiceInstances(@PathParam("serviceId") String serviceId,
170 @PathParam("version") String version, @PathParam("operationId") String operationId) {
171 return getE2EServiceInstance(serviceId, operationId, version);
175 * Scale Requests for E2E Service scale Instance on a specified version
177 * @throws ApiException
181 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
182 @Consumes(MediaType.APPLICATION_JSON)
183 @Produces(MediaType.APPLICATION_JSON)
184 @ApiOperation(value = "Scale E2E Service Instance on a specified version", response = Response.class)
185 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
186 @PathParam("serviceId") String serviceId) throws ApiException {
188 logger.debug("------------------scale begin------------------");
189 instanceIdMap.put("serviceId", serviceId);
190 return scaleE2EserviceInstances(request, Action.scaleInstance, instanceIdMap, version);
194 * GET Requests for Comparing model of service instance with target version
196 * @throws ApiException
200 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
201 @Consumes(MediaType.APPLICATION_JSON)
202 @Produces(MediaType.APPLICATION_JSON)
204 value = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
205 response = Response.class)
206 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
207 @PathParam("version") String version) throws ApiException {
209 instanceIdMap.put("serviceId", serviceId);
211 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
214 private Response compareModelwithTargetVersion(String requestJSON, Action action,
215 HashMap<String, String> instanceIdMap, String version) throws ApiException {
217 String requestId = UUID.randomUUID().toString();
218 long startTime = System.currentTimeMillis();
220 CompareModelsRequest e2eCompareModelReq;
222 ObjectMapper mapper = new ObjectMapper();
224 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
226 } catch (Exception e) {
228 logger.debug("Mapping of request to JSON object failed : ", e);
229 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
230 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
231 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
232 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
233 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
234 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
239 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, startTime, action, version);
243 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
244 String requestId, long startTime, Action action, String version) throws ApiException {
246 // Define RecipeLookupResult info here instead of query DB for efficiency
247 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
248 int recipeTimeout = 180;
250 RequestClient requestClient;
251 HttpResponse response;
253 long subStartTime = System.currentTimeMillis();
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("serviceId");
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(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
297 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
299 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
301 String apiVersion = version.substring(1);
303 long startTime = System.currentTimeMillis();
305 OperationStatus operationStatus;
308 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
309 } catch (Exception e) {
310 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
311 ErrorCode.AvailabilityError.getValue(),
312 "Exception while communciate with Request DB - Infra Request Lookup", e);
314 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
315 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
316 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
321 if (operationStatus == null) {
322 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
323 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
324 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
325 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
326 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(),
327 "Null response from RequestDB when searching by serviceId");
328 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
333 e2eServiceResponse.setOperation(operationStatus);
335 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
338 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
339 String version) throws ApiException {
340 // TODO should be a new one or the same service instance Id
341 long startTime = System.currentTimeMillis();
342 E2EServiceInstanceDeleteRequest e2eDelReq;
344 ObjectMapper mapper = new ObjectMapper();
346 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
348 } catch (Exception e) {
350 logger.debug("Mapping of request to JSON object failed : ", e);
351 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
352 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
353 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
354 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
355 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
356 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
360 String requestId = UUID.randomUUID().toString();
361 RecipeLookupResult recipeLookupResult;
363 // TODO Get the service template model version uuid from AAI.
364 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
365 } catch (Exception e) {
366 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
367 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
369 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
370 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
371 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
373 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
374 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
375 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
378 if (recipeLookupResult == null) {
379 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
380 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
381 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
382 MsoException.ServiceException, "Recipe does not exist in catalog DB",
383 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
385 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
386 ModelType.service.name(), requestJSON);
387 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
391 RequestClient requestClient;
392 HttpResponse response;
394 long subStartTime = System.currentTimeMillis();
396 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
398 JSONObject jjo = new JSONObject(requestJSON);
399 jjo.put("operationId", requestId);
401 String bpmnRequest = jjo.toString();
403 // Capture audit event
404 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
405 String serviceId = instanceIdMap.get("serviceId");
406 String serviceInstanceType = e2eDelReq.getServiceType();
407 RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
408 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
409 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
410 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
411 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
412 response = requestClient.post(clientParam);
414 } catch (Exception e) {
415 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
416 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
417 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
418 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
419 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
420 "Exception while communicate with BPMN engine");
421 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
425 if (response == null) {
427 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
428 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
429 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
430 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
431 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
435 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
436 int bpelStatus = respHandler.getStatus();
438 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
442 private Response updateE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
443 String version) throws ApiException {
445 String requestId = UUID.randomUUID().toString();
446 long startTime = System.currentTimeMillis();
447 E2EServiceInstanceRequest e2eSir;
448 String serviceId = instanceIdMap.get("serviceId");
450 ObjectMapper mapper = new ObjectMapper();
452 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
454 } catch (Exception e) {
456 logger.debug("Mapping of request to JSON object failed : ", e);
457 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
458 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
459 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
460 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
461 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
462 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
466 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
467 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
469 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
470 } catch (Exception e) {
471 logger.debug("Validation failed: ", e);
473 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
474 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
475 if (requestId != null) {
476 logger.debug("Logging failed message to the database");
478 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
479 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
480 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
484 RecipeLookupResult recipeLookupResult;
486 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
487 } catch (Exception e) {
488 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
489 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
490 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
491 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
492 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
494 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
499 if (recipeLookupResult == null) {
500 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
501 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
502 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
503 MsoException.ServiceException, "Recipe does not exist in catalog DB",
504 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
505 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
510 String serviceInstanceType = e2eSir.getService().getServiceType();
512 RequestClient requestClient;
513 HttpResponse response;
515 long subStartTime = System.currentTimeMillis();
516 String sirRequestJson = convertToString(sir);
519 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
521 // Capture audit event
522 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
523 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
524 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
525 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
526 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
527 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
528 response = requestClient.post(postParam);
529 } catch (Exception e) {
530 logger.debug("Exception while communicate with BPMN engine", e);
531 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
532 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
533 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
535 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
536 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
537 "Exception while communicate with BPMN engine");
538 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
543 if (response == null) {
544 Response getBPMNResp =
545 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
546 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
547 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
548 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
549 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
553 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
554 int bpelStatus = respHandler.getStatus();
556 return beplStatusUpdate(serviceId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
560 private Response processE2EserviceInstances(String requestJSON, Action action,
561 HashMap<String, String> instanceIdMap, String version) throws ApiException {
563 String requestId = UUID.randomUUID().toString();
564 long startTime = System.currentTimeMillis();
565 E2EServiceInstanceRequest e2eSir;
567 MsoRequest msoRequest = new MsoRequest();
568 ObjectMapper mapper = new ObjectMapper();
570 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
572 } catch (Exception e) {
574 logger.debug("Mapping of request to JSON object failed : ", e);
575 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
576 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
577 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
578 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
579 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
580 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
584 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
585 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
587 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
588 } catch (Exception e) {
589 logger.debug("Validation failed: ", e);
591 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
592 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
593 if (requestId != null) {
594 logger.debug("Logging failed message to the database");
596 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
597 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
598 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
602 RecipeLookupResult recipeLookupResult;
604 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
605 } catch (Exception e) {
606 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
607 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
608 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
609 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
610 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
611 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
615 if (recipeLookupResult == null) {
616 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
617 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
618 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
619 MsoException.ServiceException, "Recipe does not exist in catalog DB",
620 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
621 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
625 String serviceInstanceType = e2eSir.getService().getServiceType();
627 String serviceId = "";
628 RequestClient requestClient;
629 HttpResponse response;
631 long subStartTime = System.currentTimeMillis();
632 String sirRequestJson = convertToString(sir);
635 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
637 // Capture audit event
638 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
639 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
640 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
641 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
642 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
643 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
644 response = requestClient.post(parameter);
645 } catch (Exception e) {
646 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
647 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
648 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
650 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
651 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
652 "Exception while communicate with BPMN engine");
653 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
657 if (response == null) {
659 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
660 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
661 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
662 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
663 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
667 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
668 int bpelStatus = respHandler.getStatus();
670 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
674 private Response scaleE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
675 String version) throws ApiException {
677 String requestId = UUID.randomUUID().toString();
678 long startTime = System.currentTimeMillis();
679 E2EServiceInstanceScaleRequest e2eScaleReq;
681 ObjectMapper mapper = new ObjectMapper();
683 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
685 } catch (Exception e) {
687 logger.debug("Mapping of request to JSON object failed : ", e);
688 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
689 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
690 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
691 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
692 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
693 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
697 RecipeLookupResult recipeLookupResult;
699 // TODO Get the service template model version uuid from AAI.
700 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
701 } catch (Exception e) {
702 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
703 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
705 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
706 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
707 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
709 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
710 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
711 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
714 if (recipeLookupResult == null) {
715 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
716 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
718 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
719 MsoException.ServiceException, "Recipe does not exist in catalog DB",
720 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
721 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
722 ModelType.service.name(), requestJSON);
723 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
727 RequestClient requestClient;
728 HttpResponse response;
730 long subStartTime = System.currentTimeMillis();
732 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
734 JSONObject jjo = new JSONObject(requestJSON);
735 jjo.put("operationId", requestId);
737 String bpmnRequest = jjo.toString();
739 // Capture audit event
740 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
741 String serviceId = instanceIdMap.get("serviceId");
742 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
743 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
744 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
745 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
746 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
747 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
748 response = requestClient.post(postParam);
749 } catch (Exception e) {
750 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
751 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
752 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
754 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
755 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
756 "Exception while communicate with BPMN engine", e);
757 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
761 if (response == null) {
763 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
764 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
765 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
766 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
767 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
771 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
772 int bpelStatus = respHandler.getStatus();
774 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action, instanceIdMap,
778 private Response beplStatusUpdate(String serviceId, long startTime, RequestClient requestClient,
779 ResponseHandler respHandler, int bpelStatus, Action action, HashMap<String, String> instanceIdMap,
782 String apiVersion = version.substring(1);
784 // BPMN accepted the request, the request is in progress
785 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
786 String camundaJSONResponseBody = respHandler.getResponseBody();
787 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
788 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
789 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
791 List<String> variables = new ArrayList<>();
792 variables.add(bpelStatus + "");
793 String camundaJSONResponseBody = respHandler.getResponseBody();
794 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
795 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
796 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
797 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
798 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
799 requestClient.getUrl(), ErrorCode.BusinessProcesssError.getValue(),
800 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
801 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
804 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
805 "Request Failed due to BPEL error with HTTP Status= %1",
806 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
807 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
808 ErrorCode.BusinessProcesssError.getValue(), "Response from BPEL engine is empty");
809 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
816 * Getting recipes from catalogDb
818 * @param serviceModelUUID the service model version uuid
819 * @param action the action for the service
820 * @return the service recipe result
822 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
824 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
826 if (recipeLookupResult != null) {
827 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
828 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
830 logger.debug("No matching recipe record found");
832 return recipeLookupResult;
836 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
838 * @param serviceModelUUID the service version uuid
839 * @param action the action of the service.
840 * @return the service recipe result.
842 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
844 String defaultServiceModelName = "UUI_DEFAULT";
846 Service defaultServiceRecord =
847 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
848 // set recipe as default generic recipe
849 ServiceRecipe recipe =
850 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
851 // check the service special recipe
852 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
853 ServiceRecipe serviceSpecialRecipe =
854 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
855 if (null != serviceSpecialRecipe) {
856 // set service special recipe.
857 recipe = serviceSpecialRecipe;
861 if (recipe == null) {
864 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
869 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
874 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
876 ServiceInstancesRequest sir = new ServiceInstancesRequest();
878 String returnString = null;
879 RequestDetails requestDetails = new RequestDetails();
880 ModelInfo modelInfo = new ModelInfo();
883 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
885 // modelNameVersionId
886 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
888 // String modelInfoValue =
889 // e2eSir.getService().getParameters().getNodeTemplateName();
890 // String[] arrayOfInfo = modelInfoValue.split(":");
891 // String modelName = arrayOfInfo[0];
892 // String modelVersion = arrayOfInfo[1];
894 // TODO: To ensure, if we dont get the values from the UUI
895 String modelName = "voLTE";
896 String modelVersion = "1.0";
898 modelInfo.setModelName(modelName);
901 modelInfo.setModelVersion(modelVersion);
904 modelInfo.setModelType(ModelType.service);
906 // setting modelInfo to requestDetails
907 requestDetails.setModelInfo(modelInfo);
909 SubscriberInfo subscriberInfo = new SubscriberInfo();
911 // globalsubscriberId
912 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
914 // setting subscriberInfo to requestDetails
915 requestDetails.setSubscriberInfo(subscriberInfo);
917 RequestInfo requestInfo = new RequestInfo();
920 requestInfo.setInstanceName(e2eSir.getService().getName());
923 requestInfo.setSource("UUI");
926 requestInfo.setSuppressRollback(true);
928 // setting requestInfo to requestDetails
929 requestDetails.setRequestInfo(requestInfo);
931 RequestParameters requestParameters = new RequestParameters();
933 // subscriptionServiceType
934 requestParameters.setSubscriptionServiceType("MOG");
937 List<Map<String, Object>> userParamList = new ArrayList<>();
938 Map<String, Object> userParamMap = new HashMap<>();
939 // complete json request updated in the camunda
940 userParamMap.put("UUIRequest", requestJSON);
941 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
944 userParamList.add(userParamMap);
945 requestParameters.setUserParams(userParamList);
947 // setting requestParameters to requestDetails
948 requestDetails.setRequestParameters(requestParameters);
950 sir.setRequestDetails(requestDetails);
956 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
957 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
958 int reqVersion = Integer.parseInt(version.substring(1));
960 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
961 } catch (Exception e) {
962 ErrorLoggerInfo errorLoggerInfo =
963 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
964 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
965 ValidateException validateException =
966 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
967 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
969 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
970 ModelType.service.name(), requestJSON);
972 throw validateException;
976 private String convertToString(ServiceInstancesRequest sir) {
977 String returnString = null;
978 // converting to string
979 ObjectMapper mapper = new ObjectMapper();
981 returnString = mapper.writeValueAsString(sir);
982 } catch (IOException e) {
983 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);