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;
27 import javax.ws.rs.Consumes;
28 import javax.ws.rs.DELETE;
29 import javax.ws.rs.GET;
30 import javax.ws.rs.POST;
31 import javax.ws.rs.PUT;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.core.MediaType;
36 import javax.ws.rs.core.Response;
37 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.*;
38 import org.onap.aai.domain.yang.v16.ServiceInstance;
39 import org.onap.so.client.aai.AAIObjectType;
40 import org.onap.so.client.aai.AAIResourcesClient;
41 import org.onap.so.client.aai.entities.uri.AAIResourceUri;
42 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
43 import org.apache.http.HttpStatus;
44 import org.json.JSONObject;
45 import org.onap.logging.filter.base.ErrorCode;
46 import org.onap.so.apihandler.camundabeans.CamundaResponse;
47 import org.onap.so.apihandler.common.CamundaClient;
48 import org.onap.so.apihandler.common.ErrorNumbers;
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.BPMNFailureException;
59 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
60 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
61 import org.onap.so.constants.Status;
62 import org.onap.so.db.catalog.beans.Service;
63 import org.onap.so.db.catalog.beans.ServiceRecipe;
64 import org.onap.so.db.catalog.client.CatalogDbClient;
65 import org.onap.so.db.request.beans.OperationStatus;
66 import org.onap.so.db.request.client.RequestsDbClient;
67 import org.onap.so.logger.LoggingAnchor;
68 import org.onap.so.logger.MessageEnum;
69 import org.onap.so.serviceinstancebeans.ModelInfo;
70 import org.onap.so.serviceinstancebeans.ModelType;
71 import org.onap.so.serviceinstancebeans.RequestDetails;
72 import org.onap.so.serviceinstancebeans.RequestInfo;
73 import org.onap.so.serviceinstancebeans.RequestParameters;
74 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
75 import org.onap.so.serviceinstancebeans.SubscriberInfo;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78 import org.springframework.beans.factory.annotation.Autowired;
79 import org.springframework.http.ResponseEntity;
80 import org.springframework.stereotype.Component;
81 import com.fasterxml.jackson.databind.ObjectMapper;
82 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
83 import io.swagger.v3.oas.annotations.Operation;
84 import io.swagger.v3.oas.annotations.info.Info;
85 import io.swagger.v3.oas.annotations.media.ArraySchema;
86 import io.swagger.v3.oas.annotations.media.Content;
87 import io.swagger.v3.oas.annotations.media.Schema;
88 import io.swagger.v3.oas.annotations.responses.ApiResponse;
91 @Path("/onap/so/infra/e2eServiceInstances")
92 @OpenAPIDefinition(info = @Info(title = "/onap/so/infra/e2eServiceInstances",
93 description = "API Requests for E2E Service Instances"))
95 public class E2EServiceInstances {
97 private HashMap<String, String> instanceIdMap = new HashMap<>();
98 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
100 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
102 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
104 private static final String SERVICE_ID = "serviceId";
107 private MsoRequest msoRequest;
110 private RequestsDbClient requestsDbClient;
113 private CatalogDbClient catalogDbClient;
116 private ResponseBuilder builder;
119 private CamundaClient camundaClient;
122 private ResponseHandler responseHandler;
125 * POST Requests for E2E Service create Instance on a version provided
127 * @throws ApiException
131 @Path("/{version:[vV][3-5]}")
132 @Consumes(MediaType.APPLICATION_JSON)
133 @Produces(MediaType.APPLICATION_JSON)
134 @Operation(description = "Create an E2E Service Instance on a version provided", responses = @ApiResponse(
135 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
136 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
138 return processE2EserviceInstances(request, Action.createInstance, null, version);
142 * PUT Requests for E2E Service update Instance on a version provided
144 * @throws ApiException
148 @Path("/{version:[vV][3-5]}/{serviceId}")
149 @Consumes(MediaType.APPLICATION_JSON)
150 @Produces(MediaType.APPLICATION_JSON)
151 @Operation(description = "Update an E2E Service Instance on a version provided and serviceId",
152 responses = @ApiResponse(
153 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
154 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
155 @PathParam("serviceId") String serviceId) throws ApiException {
157 instanceIdMap.put(SERVICE_ID, serviceId);
159 return updateE2EserviceInstances(request, Action.updateInstance, version);
163 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
165 * @throws ApiException
169 @Path("/{version:[vV][3-5]}/{serviceId}")
170 @Consumes(MediaType.APPLICATION_JSON)
171 @Produces(MediaType.APPLICATION_JSON)
172 @Operation(description = "Delete E2E Service Instance on a specified version and serviceId",
173 responses = @ApiResponse(
174 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
175 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
176 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
178 instanceIdMap.put(SERVICE_ID, serviceId);
180 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
184 * Activate Requests for 5G slice Service on a specified version and serviceId
186 * @throws ApiException
190 @Path("/{version:[vV][3-5]}/{serviceId}/{operationType}")
191 @Consumes(MediaType.APPLICATION_JSON)
192 @Produces(MediaType.APPLICATION_JSON)
193 @Operation(description = "Activate 5G slice Service on a specified version and serviceId", responses = @ApiResponse(
194 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
195 public Response Activate5GSliceServiceInstance(String request, @PathParam("version") String version,
196 @PathParam("operationType") String operationType, @PathParam(SERVICE_ID) String serviceId)
197 throws ApiException {
198 if (operationType.equals("activate")) {
199 instanceIdMap.put("operationType", "activation");
201 instanceIdMap.put("operationType", "deactivation");
203 instanceIdMap.put(SERVICE_ID, serviceId);
204 return Activate5GSliceServiceInstances(request, Action.activateInstance, instanceIdMap, version);
208 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
209 @Operation(description = "Find e2eServiceInstances Requests for a given serviceId and operationId",
210 responses = @ApiResponse(
211 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
212 @Produces(MediaType.APPLICATION_JSON)
213 public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
214 @PathParam("version") String version, @PathParam("operationId") String operationId) {
215 return getE2EServiceInstance(serviceId, operationId, version);
219 * Scale Requests for E2E Service scale Instance on a specified version
221 * @throws ApiException
225 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
226 @Consumes(MediaType.APPLICATION_JSON)
227 @Produces(MediaType.APPLICATION_JSON)
228 @Operation(description = "Scale E2E Service Instance on a specified version", responses = @ApiResponse(
229 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
230 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
231 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
233 logger.debug("------------------scale begin------------------");
234 instanceIdMap.put(SERVICE_ID, serviceId);
235 return scaleE2EserviceInstances(request, Action.scaleInstance, version);
239 * GET Requests for Comparing model of service instance with target version
241 * @throws ApiException
245 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
246 @Consumes(MediaType.APPLICATION_JSON)
247 @Produces(MediaType.APPLICATION_JSON)
249 description = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
250 responses = @ApiResponse(
251 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
252 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
253 @PathParam("version") String version) throws ApiException {
255 instanceIdMap.put(SERVICE_ID, serviceId);
257 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
260 private Response compareModelwithTargetVersion(String requestJSON, Action action,
261 HashMap<String, String> instanceIdMap, String version) throws ApiException {
263 String requestId = UUID.randomUUID().toString();
265 CompareModelsRequest e2eCompareModelReq;
267 ObjectMapper mapper = new ObjectMapper();
269 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
271 } catch (Exception e) {
273 logger.debug("Mapping of request to JSON object failed : ", e);
274 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
275 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
276 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
277 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
278 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
279 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
284 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
288 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
289 String requestId, Action action, String version) throws ApiException {
291 // Define RecipeLookupResult info here instead of query DB for efficiency
292 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
293 int recipeTimeout = 180;
295 String bpmnRequest = null;
296 RequestClientParameter postParam = null;
298 JSONObject jjo = new JSONObject(requestJSON);
299 bpmnRequest = jjo.toString();
300 String serviceId = instanceIdMap.get(SERVICE_ID);
301 String serviceType = e2eCompareModelReq.getServiceType();
302 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
303 .setRecipeTimeout(recipeTimeout).setRequestAction(action.name()).setServiceInstanceId(serviceId)
304 .setServiceType(serviceType).setRequestDetails(bpmnRequest).setALaCarte(false).build();
305 } catch (Exception e) {
306 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
307 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
308 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
309 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
310 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
311 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
314 return postRequest(workflowUrl, postParam, version);
317 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
319 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
321 String apiVersion = version.substring(1);
323 OperationStatus operationStatus;
326 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
327 } catch (Exception e) {
328 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
329 ErrorCode.AvailabilityError.getValue(),
330 "Exception while communciate with Request DB - Infra Request Lookup", e);
332 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
333 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
334 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
339 if (operationStatus == null) {
340 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
341 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
342 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
343 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
344 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(),
345 "Null response from RequestDB when searching by serviceId");
346 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
351 e2eServiceResponse.setOperation(operationStatus);
353 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
356 private Response Activate5GSliceServiceInstances(String requestJSON, Action action,
357 HashMap<String, String> instanceIdMap, String version) throws ApiException {
358 // TODO should be a new one or the same service instance Id
359 E2ESliceServiceActivateRequest e2eActReq;
361 ObjectMapper mapper = new ObjectMapper();
363 e2eActReq = mapper.readValue(requestJSON, E2ESliceServiceActivateRequest.class);
365 } catch (Exception e) {
367 logger.debug("Mapping of request to JSON object failed : ", e);
368 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
369 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
370 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
371 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
372 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
373 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
377 String requestId = UUID.randomUUID().toString();
378 RecipeLookupResult recipeLookupResult;
380 // TODO Get the service template model version uuid from AAI.
381 String modelVersionId = null;
382 AAIResourcesClient client = new AAIResourcesClient();
383 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE,
384 e2eActReq.getGlobalSubscriberId(), e2eActReq.getServiceType(), instanceIdMap.get(SERVICE_ID));
385 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
386 if (serviceInstanceOpt.isPresent()) {
387 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
389 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
390 } catch (Exception e) {
391 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
392 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
394 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
395 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
396 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
398 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
399 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
400 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
403 if (recipeLookupResult == null) {
404 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
405 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
406 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
407 MsoException.ServiceException, "Recipe does not exist in catalog DB",
408 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
410 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
411 ModelType.service.name(), requestJSON);
412 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
416 String bpmnRequest = null;
417 RequestClientParameter postParam = null;
420 JSONObject jjo = new JSONObject(requestJSON);
421 jjo.put("operationId", requestId);
422 bpmnRequest = jjo.toString();
423 String serviceId = instanceIdMap.get(SERVICE_ID);
424 String operationType = instanceIdMap.get("operationType");
425 String serviceInstanceType = e2eActReq.getServiceType();
426 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
427 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
428 .setServiceInstanceId(serviceId).setOperationType(operationType).setServiceType(serviceInstanceType)
429 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
430 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
431 } catch (Exception e) {
432 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
433 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
434 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
435 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
436 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
437 "Exception while communicate with BPMN engine");
438 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
441 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
444 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
445 String version) throws ApiException {
446 // TODO should be a new one or the same service instance Id
447 E2EServiceInstanceDeleteRequest e2eDelReq;
449 ObjectMapper mapper = new ObjectMapper();
451 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
453 } catch (Exception e) {
455 logger.debug("Mapping of request to JSON object failed : ", e);
456 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
457 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
458 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
459 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
460 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
461 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
465 String requestId = UUID.randomUUID().toString();
466 RecipeLookupResult recipeLookupResult;
468 // TODO Get the service template model version uuid from AAI.
469 String modelVersionId = null;
470 AAIResourcesClient client = new AAIResourcesClient();
471 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE,
472 e2eDelReq.getGlobalSubscriberId(), e2eDelReq.getServiceType(), instanceIdMap.get(SERVICE_ID));
473 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
474 if (serviceInstanceOpt.isPresent()) {
475 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
477 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
478 } catch (Exception e) {
479 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
480 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
482 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
483 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
484 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
486 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
487 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON);
488 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
491 if (recipeLookupResult == null) {
492 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
493 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
494 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
495 MsoException.ServiceException, "Recipe does not exist in catalog DB",
496 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
498 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
499 ModelType.service.name(), requestJSON);
500 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
503 String bpmnRequest = null;
504 RequestClientParameter clientParam = null;
506 JSONObject jjo = new JSONObject(requestJSON);
507 jjo.put("operationId", requestId);
508 bpmnRequest = jjo.toString();
509 String serviceId = instanceIdMap.get(SERVICE_ID);
510 String serviceInstanceType = e2eDelReq.getServiceType();
511 clientParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
512 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
513 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
514 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
516 } catch (Exception e) {
517 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
518 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
519 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
520 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
521 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
522 "Exception while communicate with BPMN engine");
523 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
527 return postRequest(recipeLookupResult.getOrchestrationURI(), clientParam, version);
530 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
532 String requestId = UUID.randomUUID().toString();
533 E2EServiceInstanceRequest e2eSir;
534 String serviceId = instanceIdMap.get(SERVICE_ID);
536 ObjectMapper mapper = new ObjectMapper();
538 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
540 } catch (Exception e) {
542 logger.debug("Mapping of request to JSON object failed : ", e);
543 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
544 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
545 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
546 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
547 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
548 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
552 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
553 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
555 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
556 } catch (Exception e) {
557 logger.debug("Validation failed: ", e);
559 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
560 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
561 if (requestId != null) {
562 logger.debug("Logging failed message to the database");
564 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
565 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
566 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
570 RecipeLookupResult recipeLookupResult;
572 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
573 } catch (Exception e) {
574 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
575 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
576 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
577 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
578 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
580 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
585 if (recipeLookupResult == null) {
586 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
587 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
588 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
589 MsoException.ServiceException, "Recipe does not exist in catalog DB",
590 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
591 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
596 String serviceInstanceType = e2eSir.getService().getServiceType();
597 String sirRequestJson = convertToString(sir);
598 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
599 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
600 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
601 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
602 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
604 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
607 private Response processE2EserviceInstances(String requestJSON, Action action,
608 HashMap<String, String> instanceIdMap, String version) throws ApiException {
610 String requestId = UUID.randomUUID().toString();
611 E2EServiceInstanceRequest e2eSir;
613 MsoRequest msoRequest = new MsoRequest();
614 ObjectMapper mapper = new ObjectMapper();
616 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
618 } catch (Exception e) {
620 logger.debug("Mapping of request to JSON object failed : ", e);
621 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
622 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
623 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
624 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
625 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
626 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
630 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
631 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
633 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
634 } catch (Exception e) {
635 logger.debug("Validation failed: ", e);
637 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
638 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
639 if (requestId != null) {
640 logger.debug("Logging failed message to the database");
642 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
643 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
644 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
648 RecipeLookupResult recipeLookupResult;
650 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
651 } catch (Exception e) {
652 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
653 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
654 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
655 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
656 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
657 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
661 if (recipeLookupResult == null) {
662 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
663 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
664 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
665 MsoException.ServiceException, "Recipe does not exist in catalog DB",
666 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
667 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
671 String serviceInstanceType = e2eSir.getService().getServiceType();
673 String serviceId = e2eSir.getService().getServiceId();
674 String sirRequestJson = convertToString(sir);
675 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
676 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
677 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
678 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
679 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
681 return postRequest(recipeLookupResult.getOrchestrationURI(), parameter, version);
684 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
686 String requestId = UUID.randomUUID().toString();
687 E2EServiceInstanceScaleRequest e2eScaleReq;
689 ObjectMapper mapper = new ObjectMapper();
691 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
693 } catch (Exception e) {
695 logger.debug("Mapping of request to JSON object failed : ", e);
696 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
697 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
698 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
699 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
700 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
701 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
705 RecipeLookupResult recipeLookupResult;
707 // TODO Get the service template model version uuid from AAI.
708 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
709 } catch (Exception e) {
710 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
711 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
713 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
714 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
715 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
717 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
718 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON);
719 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
722 if (recipeLookupResult == null) {
723 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
724 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
726 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
727 MsoException.ServiceException, "Recipe does not exist in catalog DB",
728 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
729 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
730 ModelType.service.name(), requestJSON);
731 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
734 String bpmnRequest = null;
735 RequestClientParameter postParam = null;
737 JSONObject jjo = new JSONObject(requestJSON);
738 jjo.put("operationId", requestId);
739 bpmnRequest = jjo.toString();
740 String serviceId = instanceIdMap.get(SERVICE_ID);
741 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
742 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
743 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
744 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
745 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
747 } catch (Exception e) {
748 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
749 MsoException.ServiceException, "Failed creating bpmnRequest " + e.getMessage(),
750 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
752 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
753 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
754 "Exception while creating bpmnRequest", e);
755 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
758 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
761 protected Response postRequest(String orchestrationURI, RequestClientParameter postParam, String version)
762 throws ApiException {
763 ResponseEntity<String> response = null;
765 response = camundaClient.post(postParam, orchestrationURI);
766 } catch (BPMNFailureException e) {
767 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
768 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
769 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
770 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
771 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
772 "Exception while communicate with BPMN engine");
773 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
775 } catch (Exception e) {
776 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
777 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
778 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
779 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
780 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
781 "Exception while communicate with BPMN engine");
782 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
785 return bpelStatusUpdate(response, version);
788 private Response bpelStatusUpdate(ResponseEntity<String> responseEntity, String version) throws ApiException {
789 String apiVersion = version.substring(1);
790 responseHandler.acceptedResponse(responseEntity);
791 CamundaResponse camundaResponse = responseHandler.getCamundaResponse(responseEntity);
792 String response = camundaResponse.getResponse();
793 logger.debug(END_OF_THE_TRANSACTION + response);
794 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, response, apiVersion);
798 * Getting recipes from catalogDb
800 * @param serviceModelUUID the service model version uuid
801 * @param action the action for the service
802 * @return the service recipe result
804 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
806 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
808 if (recipeLookupResult != null) {
809 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
810 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
812 logger.debug("No matching recipe record found");
814 return recipeLookupResult;
818 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
820 * @param serviceModelUUID the service version uuid
821 * @param action the action of the service.
822 * @return the service recipe result.
824 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
826 String defaultServiceModelName = "UUI_DEFAULT";
828 Service defaultServiceRecord =
829 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
830 // set recipe as default generic recipe
831 ServiceRecipe recipe =
832 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
833 // check the service special recipe
834 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
835 ServiceRecipe serviceSpecialRecipe =
836 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
837 if (null != serviceSpecialRecipe) {
838 // set service special recipe.
839 recipe = serviceSpecialRecipe;
843 if (recipe == null) {
846 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
851 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
856 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
858 ServiceInstancesRequest sir = new ServiceInstancesRequest();
860 RequestDetails requestDetails = new RequestDetails();
861 ModelInfo modelInfo = new ModelInfo();
864 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
866 // modelNameVersionId
867 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
869 // String modelInfoValue =
870 // e2eSir.getService().getParameters().getNodeTemplateName();
871 // String[] arrayOfInfo = modelInfoValue.split(":");
872 // String modelName = arrayOfInfo[0];
873 // String modelVersion = arrayOfInfo[1];
875 // TODO: To ensure, if we dont get the values from the UUI
876 String modelName = "voLTE";
877 String modelVersion = "1.0";
879 modelInfo.setModelName(modelName);
882 modelInfo.setModelVersion(modelVersion);
885 modelInfo.setModelType(ModelType.service);
887 // setting modelInfo to requestDetails
888 requestDetails.setModelInfo(modelInfo);
890 SubscriberInfo subscriberInfo = new SubscriberInfo();
892 // globalsubscriberId
893 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
895 // setting subscriberInfo to requestDetails
896 requestDetails.setSubscriberInfo(subscriberInfo);
898 RequestInfo requestInfo = new RequestInfo();
901 requestInfo.setInstanceName(e2eSir.getService().getName());
904 requestInfo.setSource("UUI");
907 requestInfo.setSuppressRollback(true);
909 // setting requestInfo to requestDetails
910 requestDetails.setRequestInfo(requestInfo);
912 RequestParameters requestParameters = new RequestParameters();
914 // subscriptionServiceType
915 requestParameters.setSubscriptionServiceType("MOG");
918 List<Map<String, Object>> userParamList = new ArrayList<>();
919 Map<String, Object> userParamMap = new HashMap<>();
920 // complete json request updated in the camunda
921 userParamMap.put("UUIRequest", requestJSON);
922 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
925 userParamList.add(userParamMap);
926 requestParameters.setUserParams(userParamList);
928 // setting requestParameters to requestDetails
929 requestDetails.setRequestParameters(requestParameters);
931 sir.setRequestDetails(requestDetails);
937 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
938 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
939 int reqVersion = Integer.parseInt(version.substring(1));
941 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
942 } catch (Exception e) {
943 ErrorLoggerInfo errorLoggerInfo =
944 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
945 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
946 ValidateException validateException =
947 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
948 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
950 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
951 ModelType.service.name(), requestJSON);
953 throw validateException;
957 private String convertToString(ServiceInstancesRequest sir) {
958 String returnString = null;
959 // converting to string
960 ObjectMapper mapper = new ObjectMapper();
962 returnString = mapper.writeValueAsString(sir);
963 } catch (IOException e) {
964 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);