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.v3.oas.annotations.OpenAPIDefinition;
80 import io.swagger.v3.oas.annotations.Operation;
81 import io.swagger.v3.oas.annotations.info.Info;
82 import io.swagger.v3.oas.annotations.media.ArraySchema;
83 import io.swagger.v3.oas.annotations.media.Content;
84 import io.swagger.v3.oas.annotations.media.Schema;
85 import io.swagger.v3.oas.annotations.responses.ApiResponse;
88 @Path("/onap/so/infra/e2eServiceInstances")
89 @OpenAPIDefinition(info = @Info(title = "/onap/so/infra/e2eServiceInstances",
90 description = "API Requests for E2E Service Instances"))
92 public class E2EServiceInstances {
94 private HashMap<String, String> instanceIdMap = new HashMap<>();
95 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
97 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
99 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
101 private static final String SERVICE_ID = "serviceId";
104 private MsoRequest msoRequest;
107 private RequestClientFactory requestClientFactory;
110 private RequestsDbClient requestsDbClient;
113 private CatalogDbClient catalogDbClient;
116 private ResponseBuilder builder;
119 * POST Requests for E2E Service create Instance on a version provided
121 * @throws ApiException
125 @Path("/{version:[vV][3-5]}")
126 @Consumes(MediaType.APPLICATION_JSON)
127 @Produces(MediaType.APPLICATION_JSON)
128 @Operation(description = "Create an E2E Service Instance on a version provided", responses = @ApiResponse(
129 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
130 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
132 return processE2EserviceInstances(request, Action.createInstance, null, version);
136 * PUT Requests for E2E Service update Instance on a version provided
138 * @throws ApiException
142 @Path("/{version:[vV][3-5]}/{serviceId}")
143 @Consumes(MediaType.APPLICATION_JSON)
144 @Produces(MediaType.APPLICATION_JSON)
145 @Operation(description = "Update an E2E Service Instance on a version provided and serviceId",
146 responses = @ApiResponse(
147 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
148 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
149 @PathParam("serviceId") String serviceId) throws ApiException {
151 instanceIdMap.put(SERVICE_ID, serviceId);
153 return updateE2EserviceInstances(request, Action.updateInstance, version);
157 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
159 * @throws ApiException
163 @Path("/{version:[vV][3-5]}/{serviceId}")
164 @Consumes(MediaType.APPLICATION_JSON)
165 @Produces(MediaType.APPLICATION_JSON)
166 @Operation(description = "Delete E2E Service Instance on a specified version and serviceId",
167 responses = @ApiResponse(
168 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
169 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
170 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
172 instanceIdMap.put(SERVICE_ID, serviceId);
174 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
178 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
179 @Operation(description = "Find e2eServiceInstances Requests for a given serviceId and operationId",
180 responses = @ApiResponse(
181 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
182 @Produces(MediaType.APPLICATION_JSON)
183 public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
184 @PathParam("version") String version, @PathParam("operationId") String operationId) {
185 return getE2EServiceInstance(serviceId, operationId, version);
189 * Scale Requests for E2E Service scale Instance on a specified version
191 * @throws ApiException
195 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
196 @Consumes(MediaType.APPLICATION_JSON)
197 @Produces(MediaType.APPLICATION_JSON)
198 @Operation(description = "Scale E2E Service Instance on a specified version", responses = @ApiResponse(
199 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
200 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
201 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
203 logger.debug("------------------scale begin------------------");
204 instanceIdMap.put(SERVICE_ID, serviceId);
205 return scaleE2EserviceInstances(request, Action.scaleInstance, version);
209 * GET Requests for Comparing model of service instance with target version
211 * @throws ApiException
215 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
216 @Consumes(MediaType.APPLICATION_JSON)
217 @Produces(MediaType.APPLICATION_JSON)
219 description = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
220 responses = @ApiResponse(
221 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
222 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
223 @PathParam("version") String version) throws ApiException {
225 instanceIdMap.put(SERVICE_ID, serviceId);
227 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
230 private Response compareModelwithTargetVersion(String requestJSON, Action action,
231 HashMap<String, String> instanceIdMap, String version) throws ApiException {
233 String requestId = UUID.randomUUID().toString();
235 CompareModelsRequest e2eCompareModelReq;
237 ObjectMapper mapper = new ObjectMapper();
239 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
241 } catch (Exception e) {
243 logger.debug("Mapping of request to JSON object failed : ", e);
244 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
245 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
246 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
247 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
248 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
249 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
254 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
258 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
259 String requestId, Action action, String version) throws ApiException {
261 // Define RecipeLookupResult info here instead of query DB for efficiency
262 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
263 int recipeTimeout = 180;
265 RequestClient requestClient;
266 HttpResponse response;
269 requestClient = requestClientFactory.getRequestClient(workflowUrl);
271 JSONObject jjo = new JSONObject(requestJSON);
272 String bpmnRequest = jjo.toString();
274 // Capture audit event
275 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
276 String serviceId = instanceIdMap.get(SERVICE_ID);
277 String serviceType = e2eCompareModelReq.getServiceType();
278 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
279 .setBaseVfModule(false).setRecipeTimeout(recipeTimeout).setRequestAction(action.name())
280 .setServiceInstanceId(serviceId).setServiceType(serviceType).setRequestDetails(bpmnRequest)
281 .setALaCarte(false).build();
282 response = requestClient.post(postParam);
283 } catch (Exception e) {
284 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
285 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
286 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
287 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
288 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
289 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
293 if (response == null) {
295 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
296 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
297 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
298 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
299 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
303 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
304 int bpelStatus = respHandler.getStatus();
306 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
309 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
311 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
313 String apiVersion = version.substring(1);
315 OperationStatus operationStatus;
318 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
319 } catch (Exception e) {
320 logger.error(LoggingAnchor.FOUR, 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);
324 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
325 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
326 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
331 if (operationStatus == null) {
332 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
333 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
334 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
335 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
336 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(),
337 "Null response from RequestDB when searching by serviceId");
338 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
343 e2eServiceResponse.setOperation(operationStatus);
345 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
348 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
349 String version) throws ApiException {
350 // TODO should be a new one or the same service instance Id
351 E2EServiceInstanceDeleteRequest e2eDelReq;
353 ObjectMapper mapper = new ObjectMapper();
355 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
357 } catch (Exception e) {
359 logger.debug("Mapping of request to JSON object failed : ", e);
360 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
361 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
362 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
363 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
364 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
365 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
369 String requestId = UUID.randomUUID().toString();
370 RecipeLookupResult recipeLookupResult;
372 // TODO Get the service template model version uuid from AAI.
373 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
374 } catch (Exception e) {
375 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
376 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
378 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
379 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
380 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
382 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
383 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
384 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
387 if (recipeLookupResult == null) {
388 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
389 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
390 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
391 MsoException.ServiceException, "Recipe does not exist in catalog DB",
392 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
394 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
395 ModelType.service.name(), requestJSON);
396 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
400 RequestClient requestClient;
401 HttpResponse response;
404 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
406 JSONObject jjo = new JSONObject(requestJSON);
407 jjo.put("operationId", requestId);
409 String bpmnRequest = jjo.toString();
411 // Capture audit event
412 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
413 String serviceId = instanceIdMap.get(SERVICE_ID);
414 String serviceInstanceType = e2eDelReq.getServiceType();
415 RequestClientParameter clientParam = new RequestClientParameter.Builder().setRequestId(requestId)
416 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
417 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
418 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
419 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
420 response = requestClient.post(clientParam);
422 } catch (Exception e) {
423 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
424 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
425 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
426 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
427 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
428 "Exception while communicate with BPMN engine");
429 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
433 if (response == null) {
435 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
436 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
437 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
438 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
439 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
443 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
444 int bpelStatus = respHandler.getStatus();
446 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
449 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
451 String requestId = UUID.randomUUID().toString();
452 E2EServiceInstanceRequest e2eSir;
453 String serviceId = instanceIdMap.get(SERVICE_ID);
455 ObjectMapper mapper = new ObjectMapper();
457 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
459 } catch (Exception e) {
461 logger.debug("Mapping of request to JSON object failed : ", e);
462 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
463 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
464 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
465 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
466 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
467 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
471 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
472 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
474 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
475 } catch (Exception e) {
476 logger.debug("Validation failed: ", e);
478 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
479 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
480 if (requestId != null) {
481 logger.debug("Logging failed message to the database");
483 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
484 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
485 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
489 RecipeLookupResult recipeLookupResult;
491 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
492 } catch (Exception e) {
493 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
494 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
495 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
496 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
497 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
499 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
504 if (recipeLookupResult == null) {
505 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
506 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
507 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
508 MsoException.ServiceException, "Recipe does not exist in catalog DB",
509 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
510 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
515 String serviceInstanceType = e2eSir.getService().getServiceType();
517 RequestClient requestClient;
518 HttpResponse response;
520 String sirRequestJson = convertToString(sir);
523 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
525 // Capture audit event
526 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
527 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
528 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
529 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
530 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
531 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
532 response = requestClient.post(postParam);
533 } catch (Exception e) {
534 logger.debug("Exception while communicate with BPMN engine", e);
535 Response getBPMNResp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
536 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
537 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
539 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
540 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
541 "Exception while communicate with BPMN engine");
542 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
547 if (response == null) {
548 Response getBPMNResp =
549 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
550 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
551 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
552 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
553 logger.debug(END_OF_THE_TRANSACTION + getBPMNResp.getEntity());
557 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
558 int bpelStatus = respHandler.getStatus();
560 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
563 private Response processE2EserviceInstances(String requestJSON, Action action,
564 HashMap<String, String> instanceIdMap, String version) throws ApiException {
566 String requestId = UUID.randomUUID().toString();
567 E2EServiceInstanceRequest e2eSir;
569 MsoRequest msoRequest = new MsoRequest();
570 ObjectMapper mapper = new ObjectMapper();
572 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
574 } catch (Exception e) {
576 logger.debug("Mapping of request to JSON object failed : ", e);
577 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
578 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
579 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
580 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
581 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
582 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
586 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
587 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
589 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
590 } catch (Exception e) {
591 logger.debug("Validation failed: ", e);
593 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
594 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
595 if (requestId != null) {
596 logger.debug("Logging failed message to the database");
598 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
599 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
600 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
604 RecipeLookupResult recipeLookupResult;
606 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
607 } catch (Exception e) {
608 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
609 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
610 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
611 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
612 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
613 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
617 if (recipeLookupResult == null) {
618 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
619 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
620 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
621 MsoException.ServiceException, "Recipe does not exist in catalog DB",
622 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
623 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
627 String serviceInstanceType = e2eSir.getService().getServiceType();
629 String serviceId = e2eSir.getService().getServiceId();
630 RequestClient requestClient;
631 HttpResponse response;
633 String sirRequestJson = convertToString(sir);
636 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
638 // Capture audit event
639 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
640 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
641 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
642 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
643 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
644 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
645 response = requestClient.post(parameter);
646 } catch (Exception e) {
647 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
648 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
649 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
651 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
652 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
653 "Exception while communicate with BPMN engine");
654 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
658 if (response == null) {
660 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
661 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
662 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
663 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
664 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
668 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
669 int bpelStatus = respHandler.getStatus();
671 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
674 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
676 String requestId = UUID.randomUUID().toString();
677 E2EServiceInstanceScaleRequest e2eScaleReq;
679 ObjectMapper mapper = new ObjectMapper();
681 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
683 } catch (Exception e) {
685 logger.debug("Mapping of request to JSON object failed : ", e);
686 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
687 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
688 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
689 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
690 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
691 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
695 RecipeLookupResult recipeLookupResult;
697 // TODO Get the service template model version uuid from AAI.
698 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
699 } catch (Exception e) {
700 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
701 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
703 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
704 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
705 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
707 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
708 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
709 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
712 if (recipeLookupResult == null) {
713 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
714 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
716 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
717 MsoException.ServiceException, "Recipe does not exist in catalog DB",
718 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
719 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
720 ModelType.service.name(), requestJSON);
721 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
725 RequestClient requestClient;
726 HttpResponse response;
729 requestClient = requestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI());
731 JSONObject jjo = new JSONObject(requestJSON);
732 jjo.put("operationId", requestId);
734 String bpmnRequest = jjo.toString();
736 // Capture audit event
737 logger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
738 String serviceId = instanceIdMap.get(SERVICE_ID);
739 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
740 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
741 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
742 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
743 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
744 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
745 response = requestClient.post(postParam);
746 } catch (Exception e) {
747 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
748 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
749 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
751 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
752 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
753 "Exception while communicate with BPMN engine", e);
754 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
758 if (response == null) {
760 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
761 "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
762 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
763 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(), "Null response from BPEL");
764 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
768 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
769 int bpelStatus = respHandler.getStatus();
771 return beplStatusUpdate(requestClient, respHandler, bpelStatus, version);
774 private Response beplStatusUpdate(RequestClient requestClient, ResponseHandler respHandler, int bpelStatus,
777 String apiVersion = version.substring(1);
779 // BPMN accepted the request, the request is in progress
780 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
781 String camundaJSONResponseBody = respHandler.getResponseBody();
782 logger.debug("Received from Camunda: " + camundaJSONResponseBody);
783 logger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
784 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, camundaJSONResponseBody, apiVersion);
786 List<String> variables = new ArrayList<>();
787 variables.add(bpelStatus + "");
788 String camundaJSONResponseBody = respHandler.getResponseBody();
789 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
790 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
791 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
792 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
793 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(),
794 requestClient.getUrl(), ErrorCode.BusinessProcessError.getValue(),
795 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
796 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
799 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
800 "Request Failed due to BPEL error with HTTP Status= %1",
801 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables, version);
802 logger.error("", MessageEnum.APIH_BPEL_RESPONSE_ERROR.toString(), requestClient.getUrl(),
803 ErrorCode.BusinessProcessError.getValue(), "Response from BPEL engine is empty");
804 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
811 * Getting recipes from catalogDb
813 * @param serviceModelUUID the service model version uuid
814 * @param action the action for the service
815 * @return the service recipe result
817 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
819 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
821 if (recipeLookupResult != null) {
822 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
823 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
825 logger.debug("No matching recipe record found");
827 return recipeLookupResult;
831 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
833 * @param serviceModelUUID the service version uuid
834 * @param action the action of the service.
835 * @return the service recipe result.
837 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
839 String defaultServiceModelName = "UUI_DEFAULT";
841 Service defaultServiceRecord =
842 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
843 // set recipe as default generic recipe
844 ServiceRecipe recipe =
845 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
846 // check the service special recipe
847 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
848 ServiceRecipe serviceSpecialRecipe =
849 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
850 if (null != serviceSpecialRecipe) {
851 // set service special recipe.
852 recipe = serviceSpecialRecipe;
856 if (recipe == null) {
859 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
864 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
869 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
871 ServiceInstancesRequest sir = new ServiceInstancesRequest();
873 RequestDetails requestDetails = new RequestDetails();
874 ModelInfo modelInfo = new ModelInfo();
877 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
879 // modelNameVersionId
880 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
882 // String modelInfoValue =
883 // e2eSir.getService().getParameters().getNodeTemplateName();
884 // String[] arrayOfInfo = modelInfoValue.split(":");
885 // String modelName = arrayOfInfo[0];
886 // String modelVersion = arrayOfInfo[1];
888 // TODO: To ensure, if we dont get the values from the UUI
889 String modelName = "voLTE";
890 String modelVersion = "1.0";
892 modelInfo.setModelName(modelName);
895 modelInfo.setModelVersion(modelVersion);
898 modelInfo.setModelType(ModelType.service);
900 // setting modelInfo to requestDetails
901 requestDetails.setModelInfo(modelInfo);
903 SubscriberInfo subscriberInfo = new SubscriberInfo();
905 // globalsubscriberId
906 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
908 // setting subscriberInfo to requestDetails
909 requestDetails.setSubscriberInfo(subscriberInfo);
911 RequestInfo requestInfo = new RequestInfo();
914 requestInfo.setInstanceName(e2eSir.getService().getName());
917 requestInfo.setSource("UUI");
920 requestInfo.setSuppressRollback(true);
922 // setting requestInfo to requestDetails
923 requestDetails.setRequestInfo(requestInfo);
925 RequestParameters requestParameters = new RequestParameters();
927 // subscriptionServiceType
928 requestParameters.setSubscriptionServiceType("MOG");
931 List<Map<String, Object>> userParamList = new ArrayList<>();
932 Map<String, Object> userParamMap = new HashMap<>();
933 // complete json request updated in the camunda
934 userParamMap.put("UUIRequest", requestJSON);
935 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
938 userParamList.add(userParamMap);
939 requestParameters.setUserParams(userParamList);
941 // setting requestParameters to requestDetails
942 requestDetails.setRequestParameters(requestParameters);
944 sir.setRequestDetails(requestDetails);
950 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
951 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
952 int reqVersion = Integer.parseInt(version.substring(1));
954 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
955 } catch (Exception e) {
956 ErrorLoggerInfo errorLoggerInfo =
957 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
958 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
959 ValidateException validateException =
960 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
961 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
963 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
964 ModelType.service.name(), requestJSON);
966 throw validateException;
970 private String convertToString(ServiceInstancesRequest sir) {
971 String returnString = null;
972 // converting to string
973 ObjectMapper mapper = new ObjectMapper();
975 returnString = mapper.writeValueAsString(sir);
976 } catch (IOException e) {
977 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);