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.Optional;
31 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;
42 import org.apache.http.HttpStatus;
43 import org.json.JSONObject;
44 import org.onap.aai.domain.yang.v16.ServiceInstance;
45 import org.onap.aaiclient.client.aai.AAIResourcesClient;
46 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
47 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
48 import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder;
49 import org.onap.logging.filter.base.ErrorCode;
50 import org.onap.so.apihandler.camundabeans.CamundaResponse;
51 import org.onap.so.apihandler.common.CamundaClient;
52 import org.onap.so.apihandler.common.ErrorNumbers;
53 import org.onap.so.apihandler.common.RequestClientParameter;
54 import org.onap.so.apihandler.common.ResponseBuilder;
55 import org.onap.so.apihandler.common.ResponseHandler;
56 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.CompareModelsRequest;
57 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
58 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
59 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceScaleRequest;
60 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.E2ESliceServiceActivateRequest;
61 import org.onap.so.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
62 import org.onap.so.apihandlerinfra.exceptions.ApiException;
63 import org.onap.so.apihandlerinfra.exceptions.BPMNFailureException;
64 import org.onap.so.apihandlerinfra.exceptions.ValidateException;
65 import org.onap.so.apihandlerinfra.logging.ErrorLoggerInfo;
66 import org.onap.so.constants.Status;
67 import org.onap.so.db.catalog.beans.Service;
68 import org.onap.so.db.catalog.beans.ServiceRecipe;
69 import org.onap.so.db.catalog.client.CatalogDbClient;
70 import org.onap.so.db.request.beans.OperationStatus;
71 import org.onap.so.db.request.client.RequestsDbClient;
72 import org.onap.so.logger.LoggingAnchor;
73 import org.onap.so.logger.MessageEnum;
74 import org.onap.so.serviceinstancebeans.ModelInfo;
75 import org.onap.so.serviceinstancebeans.ModelType;
76 import org.onap.so.serviceinstancebeans.RequestDetails;
77 import org.onap.so.serviceinstancebeans.RequestInfo;
78 import org.onap.so.serviceinstancebeans.RequestParameters;
79 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
80 import org.onap.so.serviceinstancebeans.SubscriberInfo;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83 import org.springframework.beans.factory.annotation.Autowired;
84 import org.springframework.http.ResponseEntity;
85 import org.springframework.stereotype.Component;
86 import com.fasterxml.jackson.databind.ObjectMapper;
87 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
88 import io.swagger.v3.oas.annotations.Operation;
89 import io.swagger.v3.oas.annotations.info.Info;
90 import io.swagger.v3.oas.annotations.media.ArraySchema;
91 import io.swagger.v3.oas.annotations.media.Content;
92 import io.swagger.v3.oas.annotations.media.Schema;
93 import io.swagger.v3.oas.annotations.responses.ApiResponse;
96 @Path("/onap/so/infra/e2eServiceInstances")
97 @OpenAPIDefinition(info = @Info(title = "/onap/so/infra/e2eServiceInstances",
98 description = "API Requests for E2E Service Instances"))
100 public class E2EServiceInstances {
102 private HashMap<String, String> instanceIdMap = new HashMap<>();
103 private static final Logger logger = LoggerFactory.getLogger(E2EServiceInstances.class);
104 private static final ObjectMapper mapper = new ObjectMapper();
106 private static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
108 private static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
110 private static final String SERVICE_ID = "serviceId";
113 private MsoRequest msoRequest;
116 private RequestsDbClient requestsDbClient;
119 private CatalogDbClient catalogDbClient;
122 private ResponseBuilder builder;
125 private CamundaClient camundaClient;
128 private ResponseHandler responseHandler;
131 * POST Requests for E2E Service create Instance on a version provided
133 * @throws ApiException
137 @Path("/{version:[vV][3-5]}")
138 @Consumes(MediaType.APPLICATION_JSON)
139 @Produces(MediaType.APPLICATION_JSON)
140 @Operation(description = "Create an E2E Service Instance on a version provided", responses = @ApiResponse(
141 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
142 public Response createE2EServiceInstance(String request, @PathParam("version") String version) throws ApiException {
144 return processE2EserviceInstances(request, Action.createInstance, null, version);
148 * PUT Requests for E2E Service update Instance on a version provided
150 * @throws ApiException
154 @Path("/{version:[vV][3-5]}/{serviceId}")
155 @Consumes(MediaType.APPLICATION_JSON)
156 @Produces(MediaType.APPLICATION_JSON)
157 @Operation(description = "Update an E2E Service Instance on a version provided and serviceId",
158 responses = @ApiResponse(
159 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
160 public Response updateE2EServiceInstance(String request, @PathParam("version") String version,
161 @PathParam("serviceId") String serviceId) throws ApiException {
163 instanceIdMap.put(SERVICE_ID, serviceId);
165 return updateE2EserviceInstances(request, Action.updateInstance, version);
169 * DELETE Requests for E2E Service delete Instance on a specified version and serviceId
171 * @throws ApiException
175 @Path("/{version:[vV][3-5]}/{serviceId}")
176 @Consumes(MediaType.APPLICATION_JSON)
177 @Produces(MediaType.APPLICATION_JSON)
178 @Operation(description = "Delete E2E Service Instance on a specified version and serviceId",
179 responses = @ApiResponse(
180 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
181 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
182 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
184 instanceIdMap.put(SERVICE_ID, serviceId);
186 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
190 * Activate Requests for 5G slice Service on a specified version and serviceId
192 * @throws ApiException
196 @Path("/{version:[vV][3-5]}/{serviceId}/{operationType}")
197 @Consumes(MediaType.APPLICATION_JSON)
198 @Produces(MediaType.APPLICATION_JSON)
199 @Operation(description = "Activate 5G slice Service on a specified version and serviceId", responses = @ApiResponse(
200 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
201 public Response Activate5GSliceServiceInstance(String request, @PathParam("version") String version,
202 @PathParam("operationType") String operationType, @PathParam(SERVICE_ID) String serviceId)
203 throws ApiException {
204 if (operationType.equals("activate")) {
205 instanceIdMap.put("operationType", "activation");
207 instanceIdMap.put("operationType", "deactivation");
209 instanceIdMap.put(SERVICE_ID, serviceId);
210 return Activate5GSliceServiceInstances(request, Action.activateInstance, instanceIdMap, version);
214 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
215 @Operation(description = "Find e2eServiceInstances Requests for a given serviceId and operationId",
216 responses = @ApiResponse(
217 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
218 @Produces(MediaType.APPLICATION_JSON)
219 public Response getE2EServiceInstances(@PathParam(SERVICE_ID) String serviceId,
220 @PathParam("version") String version, @PathParam("operationId") String operationId) {
221 return getE2EServiceInstance(serviceId, operationId, version);
225 * Scale Requests for E2E Service scale Instance on a specified version
227 * @throws ApiException
231 @Path("/{version:[vV][3-5]}/{serviceId}/scale")
232 @Consumes(MediaType.APPLICATION_JSON)
233 @Produces(MediaType.APPLICATION_JSON)
234 @Operation(description = "Scale E2E Service Instance on a specified version", responses = @ApiResponse(
235 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
236 public Response scaleE2EServiceInstance(String request, @PathParam("version") String version,
237 @PathParam(SERVICE_ID) String serviceId) throws ApiException {
239 logger.debug("------------------scale begin------------------");
240 instanceIdMap.put(SERVICE_ID, serviceId);
241 return scaleE2EserviceInstances(request, Action.scaleInstance, version);
245 * GET Requests for Comparing model of service instance with target version
247 * @throws ApiException
251 @Path("/{version:[vV][3-5]}/{serviceId}/modeldifferences")
252 @Consumes(MediaType.APPLICATION_JSON)
253 @Produces(MediaType.APPLICATION_JSON)
255 description = "Find added and deleted resources of target model for the e2eserviceInstance on a given serviceId ",
256 responses = @ApiResponse(
257 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
258 public Response compareModelwithTargetVersion(String request, @PathParam("serviceId") String serviceId,
259 @PathParam("version") String version) throws ApiException {
261 instanceIdMap.put(SERVICE_ID, serviceId);
263 return compareModelwithTargetVersion(request, Action.compareModel, instanceIdMap, version);
266 private Response compareModelwithTargetVersion(String requestJSON, Action action,
267 HashMap<String, String> instanceIdMap, String version) throws ApiException {
269 String requestId = UUID.randomUUID().toString();
271 CompareModelsRequest e2eCompareModelReq;
274 e2eCompareModelReq = mapper.readValue(requestJSON, CompareModelsRequest.class);
276 } catch (Exception e) {
278 logger.debug("Mapping of request to JSON object failed : ", e);
279 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
280 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
281 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
282 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
283 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
284 logger.debug(END_OF_THE_TRANSACTION + response.getEntity().toString());
289 return runCompareModelBPMWorkflow(e2eCompareModelReq, requestJSON, requestId, action, version);
293 private Response runCompareModelBPMWorkflow(CompareModelsRequest e2eCompareModelReq, String requestJSON,
294 String requestId, Action action, String version) throws ApiException {
296 // Define RecipeLookupResult info here instead of query DB for efficiency
297 String workflowUrl = "/mso/async/services/CompareModelofE2EServiceInstance";
298 int recipeTimeout = 180;
300 String bpmnRequest = null;
301 RequestClientParameter postParam = null;
303 JSONObject jjo = new JSONObject(requestJSON);
304 bpmnRequest = jjo.toString();
305 String serviceId = instanceIdMap.get(SERVICE_ID);
306 String serviceType = e2eCompareModelReq.getServiceType();
307 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
308 .setRecipeTimeout(recipeTimeout).setRequestAction(action.name()).setServiceInstanceId(serviceId)
309 .setServiceType(serviceType).setRequestDetails(bpmnRequest).setALaCarte(false).build();
310 } catch (Exception e) {
311 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
312 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
313 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
314 logger.error("", MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
315 ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
316 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity().toString());
319 return postRequest(workflowUrl, postParam, version);
322 private Response getE2EServiceInstance(String serviceId, String operationId, String version) {
324 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
326 String apiVersion = version.substring(1);
328 OperationStatus operationStatus;
331 operationStatus = requestsDbClient.getOneByServiceIdAndOperationId(serviceId, operationId);
332 } catch (Exception e) {
333 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
334 ErrorCode.AvailabilityError.getValue(),
335 "Exception while communciate with Request DB - Infra Request Lookup", e);
337 msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
338 e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null, version);
339 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
344 if (operationStatus == null) {
345 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
346 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
347 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null, version);
348 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
349 MSO_PROP_APIHANDLER_INFRA, ErrorCode.BusinessProcessError.getValue(),
350 "Null response from RequestDB when searching by serviceId");
351 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
356 e2eServiceResponse.setOperation(operationStatus);
358 return builder.buildResponse(HttpStatus.SC_OK, null, e2eServiceResponse, apiVersion);
361 private Response Activate5GSliceServiceInstances(String requestJSON, Action action,
362 HashMap<String, String> instanceIdMap, String version) throws ApiException {
363 // TODO should be a new one or the same service instance Id
364 E2ESliceServiceActivateRequest e2eActReq;
367 e2eActReq = mapper.readValue(requestJSON, E2ESliceServiceActivateRequest.class);
369 } catch (Exception e) {
371 logger.debug("Mapping of request to JSON object failed : ", e);
372 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
373 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
374 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
375 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
376 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
377 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
381 String requestId = UUID.randomUUID().toString();
382 RecipeLookupResult recipeLookupResult;
384 // TODO Get the service template model version uuid from AAI.
385 String modelVersionId = null;
386 AAIResourcesClient client = new AAIResourcesClient();
387 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
388 .customer(e2eActReq.getGlobalSubscriberId()).serviceSubscription(e2eActReq.getServiceType())
389 .serviceInstance(instanceIdMap.get(SERVICE_ID)));
390 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
391 if (serviceInstanceOpt.isPresent()) {
392 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
394 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
395 } catch (Exception e) {
396 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
397 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
399 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
400 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
401 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
403 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
404 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON,
406 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
409 if (recipeLookupResult == null) {
410 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
411 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
412 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
413 MsoException.ServiceException, "Recipe does not exist in catalog DB",
414 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
416 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
417 ModelType.service.name(), requestJSON, null, null);
418 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
422 String bpmnRequest = null;
423 RequestClientParameter postParam = null;
426 JSONObject jjo = new JSONObject(requestJSON);
427 jjo.put("operationId", requestId);
428 bpmnRequest = jjo.toString();
429 String serviceId = instanceIdMap.get(SERVICE_ID);
430 String operationType = instanceIdMap.get("operationType");
431 String serviceInstanceType = e2eActReq.getServiceType();
432 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
433 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
434 .setServiceInstanceId(serviceId).setOperationType(operationType).setServiceType(serviceInstanceType)
435 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
436 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
437 } catch (Exception e) {
438 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
439 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
440 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
441 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
442 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
443 "Exception while communicate with BPMN engine");
444 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
447 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
450 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
451 String version) throws ApiException {
452 // TODO should be a new one or the same service instance Id
453 E2EServiceInstanceDeleteRequest e2eDelReq;
456 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
458 } catch (Exception e) {
460 logger.debug("Mapping of request to JSON object failed : ", e);
461 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
462 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
463 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
464 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
465 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
466 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
470 String requestId = UUID.randomUUID().toString();
471 RecipeLookupResult recipeLookupResult;
473 // TODO Get the service template model version uuid from AAI.
474 String modelVersionId = null;
475 AAIResourcesClient client = new AAIResourcesClient();
476 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.business()
477 .customer(e2eDelReq.getGlobalSubscriberId()).serviceSubscription(e2eDelReq.getServiceType())
478 .serviceInstance(instanceIdMap.get(SERVICE_ID)));
479 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
480 if (serviceInstanceOpt.isPresent()) {
481 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
483 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
484 } catch (Exception e) {
485 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
486 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
488 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
489 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
490 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
492 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
493 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON,
495 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
498 if (recipeLookupResult == null) {
499 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
500 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
501 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
502 MsoException.ServiceException, "Recipe does not exist in catalog DB",
503 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
505 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
506 ModelType.service.name(), requestJSON, null, null);
507 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
510 String bpmnRequest = null;
511 RequestClientParameter clientParam = null;
513 JSONObject jjo = new JSONObject(requestJSON);
514 jjo.put("operationId", requestId);
515 bpmnRequest = jjo.toString();
516 String serviceId = instanceIdMap.get(SERVICE_ID);
517 String serviceInstanceType = e2eDelReq.getServiceType();
518 clientParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
519 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
520 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
521 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
523 } catch (Exception e) {
524 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
525 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
526 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
527 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
528 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
529 "Exception while communicate with BPMN engine");
530 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
534 return postRequest(recipeLookupResult.getOrchestrationURI(), clientParam, version);
537 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
539 String requestId = UUID.randomUUID().toString();
540 E2EServiceInstanceRequest e2eSir;
541 String serviceId = instanceIdMap.get(SERVICE_ID);
544 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
546 } catch (Exception e) {
548 logger.debug("Mapping of request to JSON object failed : ", e);
549 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
550 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
551 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
552 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
553 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
554 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
558 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
559 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
561 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
562 } catch (Exception e) {
563 logger.debug("Validation failed: ", e);
565 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
566 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
567 if (requestId != null) {
568 logger.debug("Logging failed message to the database");
570 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
571 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
572 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
576 RecipeLookupResult recipeLookupResult;
578 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
579 } catch (Exception e) {
580 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
581 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
582 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
583 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
584 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
586 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
591 if (recipeLookupResult == null) {
592 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
593 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
594 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
595 MsoException.ServiceException, "Recipe does not exist in catalog DB",
596 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
597 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
602 String serviceInstanceType = e2eSir.getService().getServiceType();
603 String sirRequestJson = convertToString(sir);
604 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
605 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
606 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
607 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
608 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
610 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
613 private Response processE2EserviceInstances(String requestJSON, Action action,
614 HashMap<String, String> instanceIdMap, String version) throws ApiException {
616 String requestId = UUID.randomUUID().toString();
617 E2EServiceInstanceRequest e2eSir;
619 MsoRequest msoRequest = new MsoRequest();
622 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
624 } catch (Exception e) {
626 logger.debug("Mapping of request to JSON object failed : ", e);
627 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
628 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
629 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
630 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
631 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
632 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
636 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
637 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
639 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
640 } catch (Exception e) {
641 logger.debug("Validation failed: ", e);
643 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
644 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
645 if (requestId != null) {
646 logger.debug("Logging failed message to the database");
648 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
649 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
650 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
654 RecipeLookupResult recipeLookupResult;
656 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
657 } catch (Exception e) {
658 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
659 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
660 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
661 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
662 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
663 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
667 if (recipeLookupResult == null) {
668 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
669 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
670 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
671 MsoException.ServiceException, "Recipe does not exist in catalog DB",
672 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
673 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
677 String serviceInstanceType = e2eSir.getService().getServiceType();
679 String serviceId = e2eSir.getService().getServiceId();
680 String sirRequestJson = convertToString(sir);
681 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
682 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
683 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
684 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
685 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
687 return postRequest(recipeLookupResult.getOrchestrationURI(), parameter, version);
690 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
692 String requestId = UUID.randomUUID().toString();
693 E2EServiceInstanceScaleRequest e2eScaleReq;
696 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
698 } catch (Exception e) {
700 logger.debug("Mapping of request to JSON object failed : ", e);
701 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
702 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
703 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
704 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
705 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
706 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
710 RecipeLookupResult recipeLookupResult;
712 // TODO Get the service template model version uuid from AAI.
713 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
714 } catch (Exception e) {
715 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
716 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
718 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
719 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
720 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
722 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
723 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON,
725 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
728 if (recipeLookupResult == null) {
729 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
730 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
732 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
733 MsoException.ServiceException, "Recipe does not exist in catalog DB",
734 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
735 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
736 ModelType.service.name(), requestJSON, null, null);
737 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
740 String bpmnRequest = null;
741 RequestClientParameter postParam = null;
743 JSONObject jjo = new JSONObject(requestJSON);
744 jjo.put("operationId", requestId);
745 bpmnRequest = jjo.toString();
746 String serviceId = instanceIdMap.get(SERVICE_ID);
747 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
748 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
749 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
750 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
751 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
753 } catch (Exception e) {
754 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
755 MsoException.ServiceException, "Failed creating bpmnRequest " + e.getMessage(),
756 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
758 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
759 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
760 "Exception while creating bpmnRequest", e);
761 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
764 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
767 protected Response postRequest(String orchestrationURI, RequestClientParameter postParam, String version)
768 throws ApiException {
769 ResponseEntity<String> response = null;
771 response = camundaClient.post(postParam, orchestrationURI);
772 } catch (BPMNFailureException e) {
773 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
774 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
775 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
776 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
777 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
778 "Exception while communicate with BPMN engine");
779 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
781 } catch (Exception e) {
782 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
783 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
784 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
785 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
786 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
787 "Exception while communicate with BPMN engine");
788 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
791 return bpelStatusUpdate(response, version);
794 private Response bpelStatusUpdate(ResponseEntity<String> responseEntity, String version) throws ApiException {
795 String apiVersion = version.substring(1);
796 responseHandler.acceptedResponse(responseEntity);
797 CamundaResponse camundaResponse = responseHandler.getCamundaResponse(responseEntity);
798 String response = camundaResponse.getResponse();
799 logger.debug(END_OF_THE_TRANSACTION + response);
800 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, response, apiVersion);
804 * Getting recipes from catalogDb
806 * @param serviceModelUUID the service model version uuid
807 * @param action the action for the service
808 * @return the service recipe result
810 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
812 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
814 if (recipeLookupResult != null) {
815 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
816 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
818 logger.debug("No matching recipe record found");
820 return recipeLookupResult;
824 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
826 * @param serviceModelUUID the service version uuid
827 * @param action the action of the service.
828 * @return the service recipe result.
830 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
832 String defaultServiceModelName = "UUI_DEFAULT";
834 Service defaultServiceRecord =
835 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
836 // set recipe as default generic recipe
837 ServiceRecipe recipe =
838 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
839 // check the service special recipe
840 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
841 ServiceRecipe serviceSpecialRecipe =
842 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
843 if (null != serviceSpecialRecipe) {
844 // set service special recipe.
845 recipe = serviceSpecialRecipe;
849 if (recipe == null) {
852 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
857 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
862 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
864 ServiceInstancesRequest sir = new ServiceInstancesRequest();
866 RequestDetails requestDetails = new RequestDetails();
867 ModelInfo modelInfo = new ModelInfo();
870 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
872 // modelNameVersionId
873 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
875 // String modelInfoValue =
876 // e2eSir.getService().getParameters().getNodeTemplateName();
877 // String[] arrayOfInfo = modelInfoValue.split(":");
878 // String modelName = arrayOfInfo[0];
879 // String modelVersion = arrayOfInfo[1];
881 // TODO: To ensure, if we dont get the values from the UUI
882 String modelName = "voLTE";
883 String modelVersion = "1.0";
885 modelInfo.setModelName(modelName);
888 modelInfo.setModelVersion(modelVersion);
891 modelInfo.setModelType(ModelType.service);
893 // setting modelInfo to requestDetails
894 requestDetails.setModelInfo(modelInfo);
896 SubscriberInfo subscriberInfo = new SubscriberInfo();
898 // globalsubscriberId
899 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
901 // setting subscriberInfo to requestDetails
902 requestDetails.setSubscriberInfo(subscriberInfo);
904 RequestInfo requestInfo = new RequestInfo();
907 requestInfo.setInstanceName(e2eSir.getService().getName());
910 requestInfo.setSource("UUI");
913 requestInfo.setSuppressRollback(true);
915 // setting requestInfo to requestDetails
916 requestDetails.setRequestInfo(requestInfo);
918 RequestParameters requestParameters = new RequestParameters();
920 // subscriptionServiceType
921 requestParameters.setSubscriptionServiceType("MOG");
924 List<Map<String, Object>> userParamList = new ArrayList<>();
925 Map<String, Object> userParamMap = new HashMap<>();
926 // complete json request updated in the camunda
927 userParamMap.put("UUIRequest", requestJSON);
928 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
931 userParamList.add(userParamMap);
932 requestParameters.setUserParams(userParamList);
934 // setting requestParameters to requestDetails
935 requestDetails.setRequestParameters(requestParameters);
937 sir.setRequestDetails(requestDetails);
943 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
944 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
945 int reqVersion = Integer.parseInt(version.substring(1));
947 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
948 } catch (Exception e) {
949 ErrorLoggerInfo errorLoggerInfo =
950 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
951 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
952 ValidateException validateException =
953 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
954 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
956 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
957 ModelType.service.name(), requestJSON, null, null);
959 throw validateException;
963 private String convertToString(ServiceInstancesRequest sir) {
964 String returnString = null;
965 // converting to string
967 returnString = mapper.writeValueAsString(sir);
968 } catch (IOException e) {
969 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);