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;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.DELETE;
34 import javax.ws.rs.GET;
35 import javax.ws.rs.POST;
36 import javax.ws.rs.PUT;
37 import javax.ws.rs.Path;
38 import javax.ws.rs.PathParam;
39 import javax.ws.rs.Produces;
40 import javax.ws.rs.core.MediaType;
41 import javax.ws.rs.core.Response;
43 import org.apache.http.HttpResponse;
44 import org.apache.http.HttpStatus;
45 import org.json.JSONObject;
46 import org.onap.so.apihandler.common.ErrorNumbers;
47 import org.onap.so.apihandler.common.RequestClient;
48 import org.onap.so.apihandler.common.RequestClientFactory;
49 import org.onap.so.apihandler.common.RequestClientParameter;
50 import org.onap.so.apihandler.common.ResponseBuilder;
51 import org.onap.so.apihandler.common.ResponseHandler;
52 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.CompareModelsRequest;
53 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
54 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
55 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceScaleRequest;
56 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
57 import org.onap.so.apihandlerinfra.exceptions.ApiException;
58 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
59 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
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;
68 import org.onap.so.serviceinstancebeans.ModelInfo;
69 import org.onap.so.serviceinstancebeans.ModelType;
70 import org.onap.so.serviceinstancebeans.RequestDetails;
71 import org.onap.so.serviceinstancebeans.RequestInfo;
72 import org.onap.so.serviceinstancebeans.RequestParameters;
73 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
74 import org.onap.so.serviceinstancebeans.SubscriberInfo;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.stereotype.Component;
80 import com.fasterxml.jackson.databind.ObjectMapper;
82 import io.swagger.annotations.Api;
83 import io.swagger.annotations.ApiOperation;
87 @Path("/onap/so/infra/e2eServiceInstances")
88 @Api(value = "/onap/so/infra/e2eServiceInstances", description = "API Requests for E2E Service Instances")
89 public class E2EServiceInstances {
91 private HashMap<String, String> instanceIdMap = new HashMap<>();
92 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
94 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
96 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
99 private MsoRequest msoRequest;
102 private RequestClientFactory requestClientFactory;
105 private RequestsDbClient requestsDbClient;
108 private CatalogDbClient catalogDbClient;
111 private ResponseBuilder builder;
114 * POST Requests for E2E Service create Instance on a version provided
115 * @throws ApiException
119 @Path("/{version:[vV][3-5]}")
120 @Consumes(MediaType.APPLICATION_JSON)
121 @Produces(MediaType.APPLICATION_JSON)
122 @ApiOperation(value = "Create an E2E Service Instance on a version provided", response = Response.class)
123 public Response createE2EServiceInstance(String request,
124 @PathParam("version") String version) throws ApiException {
126 return processE2EserviceInstances(request, Action.createInstance, null,
131 * PUT Requests for E2E Service update Instance on a version provided
132 * @throws ApiException
136 @Path("/{version:[vV][3-5]}/{serviceId}")
137 @Consumes(MediaType.APPLICATION_JSON)
138 @Produces(MediaType.APPLICATION_JSON)
139 @ApiOperation(value = "Update an E2E Service Instance on a version provided and serviceId", response = Response.class)
140 public Response updateE2EServiceInstance(String request,
141 @PathParam("version") String version,
142 @PathParam("serviceId") String serviceId) throws ApiException {
144 instanceIdMap.put("serviceId", serviceId);
146 return updateE2EserviceInstances(request, Action.updateInstance, instanceIdMap,
151 * DELETE Requests for E2E Service delete Instance on a specified version
153 * @throws ApiException
157 @Path("/{version:[vV][3-5]}/{serviceId}")
158 @Consumes(MediaType.APPLICATION_JSON)
159 @Produces(MediaType.APPLICATION_JSON)
160 @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
161 public Response deleteE2EServiceInstance(String request,
162 @PathParam("version") String version,
163 @PathParam("serviceId") String serviceId) throws ApiException {
165 instanceIdMap.put("serviceId", serviceId);
167 return deleteE2EserviceInstances(request, Action.deleteInstance,
168 instanceIdMap, version);
172 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
173 @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId", response = Response.class)
174 @Produces(MediaType.APPLICATION_JSON)
175 public Response getE2EServiceInstances(
176 @PathParam("serviceId") String serviceId,
177 @PathParam("version") String version,
178 @PathParam("operationId") String operationId) {
179 return getE2EServiceInstance(serviceId, operationId, version);
183 * Scale Requests for E2E Service scale Instance on a specified version
184 * @throws ApiException
188 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
189 @Consumes(MediaType.APPLICATION_JSON)
190 @Produces(MediaType.APPLICATION_JSON)
191 @ApiOperation(value="Scale E2E Service Instance on a specified version",response=Response.class)
192 public Response scaleE2EServiceInstance(String request,
193 @PathParam("version") String version,
194 @PathParam("serviceId") String serviceId) throws ApiException {
196 logger.debug("------------------scale begin------------------");
197 instanceIdMap.put("serviceId", serviceId);
198 return scaleE2EserviceInstances(request, Action.scaleInstance, instanceIdMap, version);
201 * GET Requests for Comparing model of service instance with target version
202 * @throws ApiException
206 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
207 @Consumes(MediaType.APPLICATION_JSON)
208 @Produces(MediaType.APPLICATION_JSON)
209 @ApiOperation(value = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ", response = Response.class)
210 public Response compareModelwithTargetVersion(String request,
211 @PathParam("serviceId") String serviceId,
212 @PathParam("version") String version) throws ApiException {
214 instanceIdMap.put("serviceId", serviceId);
216 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
219 private Response compareModelwithTargetVersion(String requestJSON, Action action,
220 HashMap<String, String> instanceIdMap, String version) throws ApiException {
222 String requestId = UUID.randomUUID().toString();
223 long startTime = System.currentTimeMillis();
225 CompareModelsRequest e2eCompareModelReq;
227 ObjectMapper mapper = new ObjectMapper();
229 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
231 } catch (Exception e) {
233 logger.debug("Mapping of request to JSON object failed : ", e);
234 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
235 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
236 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
237 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
238 ErrorCode.SchemaError.getValue(), requestJSON, e);
239 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
244 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, startTime, action, version);
248 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq,
249 String requestJSON, String requestId, long startTime, Action action, String version) throws ApiException {
251 // Define RecipeLookupResult info here instead of query DB for efficiency
252 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
253 int recipeTimeout = 180;
255 RequestClient requestClient;
256 HttpResponse response;
258 long subStartTime = System.currentTimeMillis();
261 requestClient = requestClientFactory.getRequestClient(workflowUrl);
263 JSONObject jjo = new JSONObject(requestJSON);
264 String bpmnRequest = jjo.toString();
266 // Capture audit event
267 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
268 String serviceId = instanceIdMap.get("serviceId");
269 String serviceType = e2eCompareModelReq.getServiceType();
270 RequestClientParameter postParam = new RequestClientParameter.Builder()
271 .setRequestId(requestId)
272 .setBaseVfModule(false)
273 .setRecipeTimeout(recipeTimeout)
274 .setRequestAction(action.name())
275 .setServiceInstanceId(serviceId)
276 .setServiceType(serviceType)
277 .setRequestDetails(bpmnRequest)
278 .setALaCarte(false).build();
279 response = requestClient.post(postParam);
280 } catch (Exception e) {
281 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
282 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
283 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
284 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
285 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine",e);
286 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
290 if (response == null) {
291 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
292 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
293 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
294 ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
295 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
299 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
300 int bpelStatus = respHandler.getStatus();
302 return beplStatusUpdate(requestId, startTime, requestClient, respHandler, bpelStatus, action,
303 instanceIdMap, version);
306 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
308 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
310 String apiVersion = version.substring(1);
312 long startTime = System.currentTimeMillis();
314 OperationStatus operationStatus;
317 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId,
319 } catch (Exception e) {
320 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
321 ErrorCode.AvailabilityError.getValue(),
322 "Exception while communciate with Request DB - Infra Request Lookup", e);
323 Response response = msoRequest.buildServiceErrorResponse(
324 HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
326 ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
327 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
332 if (operationStatus == null) {
333 Response resp = msoRequest.buildServiceErrorResponse(
334 HttpStatus.SC_NO_CONTENT, MsoException.ServiceException,
335 "E2E serviceId " + serviceId + " is not found in DB",
336 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
337 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
338 ErrorCode.BusinessProcesssError.getValue(),
339 "Null response from RequestDB when searching by serviceId");
340 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
345 e2eServiceResponse.setOperation(operationStatus);
347 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
350 private Response deleteE2EserviceInstances(String requestJSON,
351 Action action, HashMap<String, String> instanceIdMap, String version) throws ApiException {
352 // TODO should be a new one or the same service instance Id
353 long startTime = System.currentTimeMillis();
354 E2EServiceInstanceDeleteRequest e2eDelReq;
356 ObjectMapper mapper = new ObjectMapper();
358 e2eDelReq = mapper.readValue(requestJSON,
359 E2EServiceInstanceDeleteRequest.class);
361 } catch (Exception e) {
363 logger.debug("Mapping of request to JSON object failed : ", e);
364 Response response = msoRequest.buildServiceErrorResponse(
365 HttpStatus.SC_BAD_REQUEST,
366 MsoException.ServiceException,
367 "Mapping of request to JSON object failed. "
368 + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER,
370 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
371 ErrorCode.SchemaError.getValue(), requestJSON, e);
372 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
376 String requestId = UUID.randomUUID().toString();
377 RecipeLookupResult recipeLookupResult;
379 //TODO Get the service template model version uuid from AAI.
380 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
381 } catch (Exception e) {
382 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
383 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
385 Response response = msoRequest.buildServiceErrorResponse(
386 HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
387 "No communication to catalog DB " + e.getMessage(),
388 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
390 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Exception while communciate with "
391 + "Catalog DB", action,
392 ModelType.service.name(), requestJSON);
393 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
396 if (recipeLookupResult == null) {
397 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(), MSO_PROP_APIHANDLER_INFRA,
398 ErrorCode.DataError.getValue(), "No recipe found in DB");
399 Response response = msoRequest.buildServiceErrorResponse(
400 HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
401 "Recipe does not exist in catalog DB",
402 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
404 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,"Recipe does not exist in catalog DB", action, ModelType.service.name(), requestJSON);
405 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
409 RequestClient requestClient;
410 HttpResponse response;
412 long subStartTime = System.currentTimeMillis();
414 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
416 JSONObject jjo = new JSONObject(requestJSON);
417 jjo.put("operationId", requestId);
419 String bpmnRequest = jjo.toString();
421 // Capture audit event
422 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
423 String serviceId = instanceIdMap.get("serviceId");
424 String serviceInstanceType = e2eDelReq.getServiceType();
425 RequestClientParameter clientParam = new RequestClientParameter.Builder()
426 .setRequestId(requestId)
427 .setBaseVfModule(false)
428 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
429 .setRequestAction(action.name())
430 .setServiceInstanceId(serviceId)
431 .setServiceType(serviceInstanceType)
432 .setRequestDetails(bpmnRequest)
433 .setApiVersion(version)
435 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
436 response = requestClient.post(clientParam);
438 } catch (Exception e) {
439 Response resp = msoRequest.buildServiceErrorResponse(
440 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
441 "Failed calling bpmn " + e.getMessage(),
442 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
443 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
444 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with BPMN engine");
445 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
449 if (response == null) {
450 Response resp = msoRequest.buildServiceErrorResponse(
451 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
452 "bpelResponse is null",
453 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
454 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
455 ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
456 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
460 ResponseHandler respHandler = new ResponseHandler(response,
461 requestClient.getType());
462 int bpelStatus = respHandler.getStatus();
464 return beplStatusUpdate(requestId, startTime, requestClient, respHandler,
465 bpelStatus, action, instanceIdMap, version);
468 private Response updateE2EserviceInstances(String requestJSON, Action action,
469 HashMap<String, String> instanceIdMap, String version) throws ApiException {
471 String requestId = UUID.randomUUID().toString();
472 long startTime = System.currentTimeMillis();
473 E2EServiceInstanceRequest e2eSir;
474 String serviceId = instanceIdMap.get("serviceId");
476 ObjectMapper mapper = new ObjectMapper();
478 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
480 } catch (Exception e) {
482 logger.debug("Mapping of request to JSON object failed : ", e);
483 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
484 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
485 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
486 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
487 ErrorCode.SchemaError.getValue(), requestJSON, e);
488 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
492 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
493 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
495 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
496 } catch (Exception e) {
497 logger.debug("Validation failed: ", e);
498 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
499 MsoException.ServiceException, "Error parsing request. " + e.getMessage(),
500 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
501 if (requestId != null) {
502 logger.debug("Logging failed message to the database");
504 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
505 ErrorCode.SchemaError.getValue(), requestJSON, e);
506 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
510 RecipeLookupResult recipeLookupResult;
512 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
513 } catch (Exception e) {
514 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
515 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
516 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
517 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
518 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
520 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
525 if (recipeLookupResult == null) {
526 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(), MSO_PROP_APIHANDLER_INFRA,
527 ErrorCode.DataError.getValue(), "No recipe found in DB");
528 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
529 MsoException.ServiceException, "Recipe does not exist in catalog DB",
530 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
531 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
536 String serviceInstanceType = e2eSir.getService().getServiceType();
538 RequestClient requestClient;
539 HttpResponse response;
541 long subStartTime = System.currentTimeMillis();
542 String sirRequestJson = convertToString(sir);
545 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
547 // Capture audit event
548 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
549 RequestClientParameter postParam = new RequestClientParameter.Builder()
550 .setRequestId(requestId)
551 .setBaseVfModule(false)
552 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
553 .setRequestAction(action.name())
554 .setServiceInstanceId(serviceId)
555 .setServiceType(serviceInstanceType)
556 .setRequestDetails(sirRequestJson)
557 .setApiVersion(version)
559 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
560 response = requestClient.post(postParam);
561 } catch (Exception e) {
562 logger.debug("Exception while communicate with BPMN engine", e);
563 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
564 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
565 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
567 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
568 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with BPMN engine");
569 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
574 if (response == null) {
575 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
576 MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
577 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
578 ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
579 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
583 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
584 int bpelStatus = respHandler.getStatus();
586 return beplStatusUpdate(serviceId, startTime, requestClient, respHandler,
587 bpelStatus, action, instanceIdMap, version);
590 private Response processE2EserviceInstances(String requestJSON, Action action,
591 HashMap<String, String> instanceIdMap, String version) throws ApiException {
593 String requestId = UUID.randomUUID().toString();
594 long startTime = System.currentTimeMillis();
595 E2EServiceInstanceRequest e2eSir;
597 MsoRequest msoRequest = new MsoRequest();
598 ObjectMapper mapper = new ObjectMapper();
600 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
602 } catch (Exception e) {
604 logger.debug("Mapping of request to JSON object failed : ", e);
605 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
606 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
607 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
608 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
609 ErrorCode.SchemaError.getValue(), requestJSON, e);
610 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
614 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
615 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
617 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
618 } catch (Exception e) {
619 logger.debug("Validation failed: ", e);
620 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
621 MsoException.ServiceException, "Error parsing request. " + e.getMessage(),
622 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
623 if (requestId != null) {
624 logger.debug("Logging failed message to the database");
626 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
627 ErrorCode.SchemaError.getValue(), requestJSON, e);
628 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
632 RecipeLookupResult recipeLookupResult;
634 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
635 } catch (Exception e) {
636 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
637 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
638 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
639 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
640 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
641 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
645 if (recipeLookupResult == null) {
646 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(), MSO_PROP_APIHANDLER_INFRA,
647 ErrorCode.DataError.getValue(), "No recipe found in DB");
648 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
649 MsoException.ServiceException, "Recipe does not exist in catalog DB",
650 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
651 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
655 String serviceInstanceType = e2eSir.getService().getServiceType();
657 String serviceId = "";
658 RequestClient requestClient;
659 HttpResponse response;
661 long subStartTime = System.currentTimeMillis();
662 String sirRequestJson = convertToString(sir);
665 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
667 // Capture audit event
668 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
669 RequestClientParameter parameter = new RequestClientParameter.Builder()
670 .setRequestId(requestId)
671 .setBaseVfModule(false)
672 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
673 .setRequestAction(action.name())
674 .setServiceInstanceId(serviceId)
675 .setServiceType(serviceInstanceType)
676 .setRequestDetails(sirRequestJson)
677 .setApiVersion(version)
679 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
680 response = requestClient.post(parameter);
681 } catch (Exception e) {
682 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
683 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
684 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
686 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
687 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with BPMN engine");
688 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
692 if (response == null) {
693 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
694 MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
695 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
696 ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
697 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
701 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
702 int bpelStatus = respHandler.getStatus();
704 return beplStatusUpdate(requestId, startTime, requestClient, respHandler,
705 bpelStatus, action, instanceIdMap, version);
708 private Response scaleE2EserviceInstances(String requestJSON,
709 Action action, HashMap<String, String> instanceIdMap, String version) throws ApiException {
711 String requestId = UUID.randomUUID().toString();
712 long startTime = System.currentTimeMillis();
713 E2EServiceInstanceScaleRequest e2eScaleReq;
715 ObjectMapper mapper = new ObjectMapper();
717 e2eScaleReq = mapper.readValue(requestJSON,
718 E2EServiceInstanceScaleRequest.class);
720 } catch (Exception e) {
722 logger.debug("Mapping of request to JSON object failed : ", e);
723 Response response = msoRequest.buildServiceErrorResponse(
724 HttpStatus.SC_BAD_REQUEST,
725 MsoException.ServiceException,
726 "Mapping of request to JSON object failed. "
727 + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER,
729 logger.error("{} {} {} {}", MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
730 ErrorCode.SchemaError.getValue(), requestJSON, e);
731 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
735 RecipeLookupResult recipeLookupResult;
737 //TODO Get the service template model version uuid from AAI.
738 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
739 } catch (Exception e) {
740 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
741 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
743 Response response = msoRequest.buildServiceErrorResponse(
744 HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
745 "No communication to catalog DB " + e.getMessage(),
746 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
748 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
749 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
752 if (recipeLookupResult == null) {
753 logger.error("{} {} {} {}", MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(), MSO_PROP_APIHANDLER_INFRA,
754 ErrorCode.DataError.getValue(), "No recipe found in DB");
756 Response response = msoRequest.buildServiceErrorResponse(
757 HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
758 "Recipe does not exist in catalog DB",
759 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
760 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action, ModelType.service.name(), requestJSON);
761 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
765 RequestClient requestClient;
766 HttpResponse response;
768 long subStartTime = System.currentTimeMillis();
770 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
772 JSONObject jjo = new JSONObject(requestJSON);
773 jjo.put("operationId", requestId);
775 String bpmnRequest = jjo.toString();
777 // Capture audit event
778 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
779 String serviceId = instanceIdMap.get("serviceId");
780 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
781 RequestClientParameter postParam = new RequestClientParameter.Builder()
782 .setRequestId(requestId)
783 .setBaseVfModule(false)
784 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
785 .setRequestAction(action.name())
786 .setServiceInstanceId(serviceId)
787 .setServiceType(serviceInstanceType)
788 .setRequestDetails(bpmnRequest)
789 .setApiVersion(version)
791 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
792 response = requestClient.post(postParam);
793 } catch (Exception e) {
794 Response resp = msoRequest.buildServiceErrorResponse(
795 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
796 "Failed calling bpmn " + e.getMessage(),
797 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
799 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
800 ErrorCode.AvailabilityError.getValue(), "Exception while communicate with BPMN engine", e);
801 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
805 if (response == null) {
806 Response resp = msoRequest.buildServiceErrorResponse(
807 HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
808 "bpelResponse is null",
809 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
810 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(), MSO_PROP_APIHANDLER_INFRA,
811 ErrorCode.BusinessProcesssError.getValue(), "Null response from BPEL");
812 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
816 ResponseHandler respHandler = new ResponseHandler(response,
817 requestClient.getType());
818 int bpelStatus = respHandler.getStatus();
820 return beplStatusUpdate(requestId, startTime, requestClient, respHandler,
821 bpelStatus, action, instanceIdMap, version);
824 private Response beplStatusUpdate(String serviceId, long startTime,
825 RequestClient requestClient,
826 ResponseHandler respHandler, int bpelStatus, Action action,
827 HashMap<String, String> instanceIdMap, String version) {
829 String apiVersion = version.substring(1);
831 // BPMN accepted the request, the request is in progress
832 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
833 String camundaJSONResponseBody = respHandler.getResponseBody();
834 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
835 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
836 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
838 List<String> variables = new ArrayList<>();
839 variables.add(bpelStatus + "");
840 String camundaJSONResponseBody = respHandler.getResponseBody();
841 if (camundaJSONResponseBody != null
842 && !camundaJSONResponseBody.isEmpty()) {
843 Response resp = msoRequest.buildServiceErrorResponse(
844 bpelStatus, MsoException.ServiceException,
845 "Request Failed due to BPEL error with HTTP Status= %1 "
846 + '\n' + camundaJSONResponseBody,
847 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
848 logger.error("{} {} {} {}", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
849 ErrorCode.BusinessProcesssError.getValue(),
850 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
851 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
854 Response resp = msoRequest
855 .buildServiceErrorResponse(
857 MsoException.ServiceException,
858 "Request Failed due to BPEL error with HTTP Status= %1",
859 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
861 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
862 ErrorCode.BusinessProcesssError.getValue(),
863 "Response from BPEL engine is empty");
864 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
871 * Getting recipes from catalogDb
873 * @param serviceModelUUID the service model version uuid
874 * @param action the action for the service
875 * @return the service recipe result
877 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
879 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
881 if (recipeLookupResult != null) {
883 "Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: " + Integer
884 .toString(recipeLookupResult.getRecipeTimeout()));
886 logger.debug("No matching recipe record found");
888 return recipeLookupResult;
892 * Getting recipes from catalogDb
893 * If Service recipe is not set, use default recipe, if set , use special recipe.
894 * @param serviceModelUUID the service version uuid
895 * @param action the action of the service.
896 * @return the service recipe result.
898 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
900 String defaultServiceModelName = "UUI_DEFAULT";
902 Service defaultServiceRecord = catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
903 //set recipe as default generic recipe
904 ServiceRecipe recipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
905 //check the service special recipe
906 if(null != serviceModelUUID && ! serviceModelUUID.isEmpty()){
907 ServiceRecipe serviceSpecialRecipe = catalogDbClient.getFirstByServiceModelUUIDAndAction(
908 serviceModelUUID, action.name());
909 if(null != serviceSpecialRecipe){
910 //set service special recipe.
911 recipe = serviceSpecialRecipe;
915 if (recipe == null) {
918 return new RecipeLookupResult(recipe.getOrchestrationUri(),
919 recipe.getRecipeTimeout(), recipe.getParamXsd());
924 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
925 * passing it to camunda engine.
930 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir,
931 String requestJSON) {
933 ServiceInstancesRequest sir = new ServiceInstancesRequest();
935 String returnString = null;
936 RequestDetails requestDetails = new RequestDetails();
937 ModelInfo modelInfo = new ModelInfo();
940 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
942 // modelNameVersionId
943 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
945 // String modelInfoValue =
946 // e2eSir.getService().getParameters().getNodeTemplateName();
947 // String[] arrayOfInfo = modelInfoValue.split(":");
948 // String modelName = arrayOfInfo[0];
949 // String modelVersion = arrayOfInfo[1];
951 // TODO: To ensure, if we dont get the values from the UUI
952 String modelName = "voLTE";
953 String modelVersion = "1.0";
955 modelInfo.setModelName(modelName);
958 modelInfo.setModelVersion(modelVersion);
961 modelInfo.setModelType(ModelType.service);
963 // setting modelInfo to requestDetails
964 requestDetails.setModelInfo(modelInfo);
966 SubscriberInfo subscriberInfo = new SubscriberInfo();
968 // globalsubscriberId
969 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
971 // setting subscriberInfo to requestDetails
972 requestDetails.setSubscriberInfo(subscriberInfo);
974 RequestInfo requestInfo = new RequestInfo();
977 requestInfo.setInstanceName(e2eSir.getService().getName());
980 requestInfo.setSource("UUI");
983 requestInfo.setSuppressRollback(true);
985 // setting requestInfo to requestDetails
986 requestDetails.setRequestInfo(requestInfo);
988 RequestParameters requestParameters = new RequestParameters();
990 // subscriptionServiceType
991 requestParameters.setSubscriptionServiceType("MOG");
994 //List<E2EUserParam> userParams;
996 // e2eSir.getService().getParameters().getRequestParameters().getUserParams();
997 List<Map<String, Object>> userParamList = new ArrayList<>();
998 Map<String, Object> userParamMap = new HashMap<>();
999 // complete json request updated in the camunda
1000 userParamMap.put("UUIRequest", requestJSON);
1001 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
1003 // Map<String, String> userParamMap3 = null;
1004 // for (E2EUserParam userp : userParams) {
1005 // userParamMap.put(userp.getName(), userp.getValue());
1008 userParamList.add(userParamMap);
1009 requestParameters.setUserParams(userParamList);
1011 // setting requestParameters to requestDetails
1012 requestDetails.setRequestParameters(requestParameters);
1014 sir.setRequestDetails(requestDetails);
1020 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action, String version,
1021 String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
1022 int reqVersion = Integer.parseInt(version.substring(1));
1024 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
1025 } catch (Exception e) {
1026 ErrorLoggerInfo errorLoggerInfo = new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError).errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
1027 ValidateException validateException = new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST, ErrorNumbers.SVC_BAD_PARAMETER).cause(e)
1028 .errorInfo(errorLoggerInfo).build();
1030 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action, ModelType.service.name(), requestJSON);
1032 throw validateException;
1036 private String convertToString(ServiceInstancesRequest sir) {
1037 String returnString = null;
1038 // converting to string
1039 ObjectMapper mapper = new ObjectMapper();
1041 returnString = mapper.writeValueAsString(sir);
1042 } catch (IOException e) {
1043 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);
1046 return returnString;