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.aaiclient.client.aai.AAIObjectType;
40 import org.onap.aaiclient.client.aai.AAIResourcesClient;
41 import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
42 import org.onap.aaiclient.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,
401 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
404 if (recipeLookupResult == null) {
405 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
406 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
407 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
408 MsoException.ServiceException, "Recipe does not exist in catalog DB",
409 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
411 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
412 ModelType.service.name(), requestJSON, null);
413 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
417 String bpmnRequest = null;
418 RequestClientParameter postParam = null;
421 JSONObject jjo = new JSONObject(requestJSON);
422 jjo.put("operationId", requestId);
423 bpmnRequest = jjo.toString();
424 String serviceId = instanceIdMap.get(SERVICE_ID);
425 String operationType = instanceIdMap.get("operationType");
426 String serviceInstanceType = e2eActReq.getServiceType();
427 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
428 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
429 .setServiceInstanceId(serviceId).setOperationType(operationType).setServiceType(serviceInstanceType)
430 .setRequestDetails(bpmnRequest).setApiVersion(version).setALaCarte(false)
431 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
432 } catch (Exception e) {
433 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
434 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
435 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
436 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
437 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
438 "Exception while communicate with BPMN engine");
439 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
442 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
445 private Response deleteE2EserviceInstances(String requestJSON, Action action, HashMap<String, String> instanceIdMap,
446 String version) throws ApiException {
447 // TODO should be a new one or the same service instance Id
448 E2EServiceInstanceDeleteRequest e2eDelReq;
450 ObjectMapper mapper = new ObjectMapper();
452 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
454 } catch (Exception e) {
456 logger.debug("Mapping of request to JSON object failed : ", e);
457 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
458 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
459 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
460 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
461 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
462 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
466 String requestId = UUID.randomUUID().toString();
467 RecipeLookupResult recipeLookupResult;
469 // TODO Get the service template model version uuid from AAI.
470 String modelVersionId = null;
471 AAIResourcesClient client = new AAIResourcesClient();
472 AAIResourceUri url = AAIUriFactory.createResourceUri(AAIObjectType.SERVICE_INSTANCE,
473 e2eDelReq.getGlobalSubscriberId(), e2eDelReq.getServiceType(), instanceIdMap.get(SERVICE_ID));
474 Optional<ServiceInstance> serviceInstanceOpt = client.get(ServiceInstance.class, url);
475 if (serviceInstanceOpt.isPresent()) {
476 modelVersionId = serviceInstanceOpt.get().getModelVersionId();
478 recipeLookupResult = getServiceInstanceOrchestrationURI(modelVersionId, action);
479 } catch (Exception e) {
480 logger.error(MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
481 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
483 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
484 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
485 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
487 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
488 "Exception while communciate with " + "Catalog DB", action, ModelType.service.name(), requestJSON,
490 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
493 if (recipeLookupResult == null) {
494 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
495 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
496 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
497 MsoException.ServiceException, "Recipe does not exist in catalog DB",
498 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
500 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "Recipe does not exist in catalog DB", action,
501 ModelType.service.name(), requestJSON, null);
502 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
505 String bpmnRequest = null;
506 RequestClientParameter clientParam = null;
508 JSONObject jjo = new JSONObject(requestJSON);
509 jjo.put("operationId", requestId);
510 bpmnRequest = jjo.toString();
511 String serviceId = instanceIdMap.get(SERVICE_ID);
512 String serviceInstanceType = e2eDelReq.getServiceType();
513 clientParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
514 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
515 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
516 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
518 } catch (Exception e) {
519 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
520 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
521 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
522 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
523 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
524 "Exception while communicate with BPMN engine");
525 logger.debug("End of the transaction, the final response is: " + resp.getEntity());
529 return postRequest(recipeLookupResult.getOrchestrationURI(), clientParam, version);
532 private Response updateE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
534 String requestId = UUID.randomUUID().toString();
535 E2EServiceInstanceRequest e2eSir;
536 String serviceId = instanceIdMap.get(SERVICE_ID);
538 ObjectMapper mapper = new ObjectMapper();
540 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
542 } catch (Exception e) {
544 logger.debug("Mapping of request to JSON object failed : ", e);
545 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
546 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
547 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
548 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
549 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
550 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
554 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
555 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
557 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
558 } catch (Exception e) {
559 logger.debug("Validation failed: ", e);
561 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
562 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
563 if (requestId != null) {
564 logger.debug("Logging failed message to the database");
566 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
567 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
568 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
572 RecipeLookupResult recipeLookupResult;
574 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
575 } catch (Exception e) {
576 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
577 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
578 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
579 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
580 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
582 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
587 if (recipeLookupResult == null) {
588 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
589 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
590 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
591 MsoException.ServiceException, "Recipe does not exist in catalog DB",
592 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
593 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
598 String serviceInstanceType = e2eSir.getService().getServiceType();
599 String sirRequestJson = convertToString(sir);
600 RequestClientParameter postParam = new RequestClientParameter.Builder().setRequestId(requestId)
601 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
602 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
603 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
604 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
606 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
609 private Response processE2EserviceInstances(String requestJSON, Action action,
610 HashMap<String, String> instanceIdMap, String version) throws ApiException {
612 String requestId = UUID.randomUUID().toString();
613 E2EServiceInstanceRequest e2eSir;
615 MsoRequest msoRequest = new MsoRequest();
616 ObjectMapper mapper = new ObjectMapper();
618 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
620 } catch (Exception e) {
622 logger.debug("Mapping of request to JSON object failed : ", e);
623 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
624 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
625 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
626 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
627 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
628 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
632 ServiceInstancesRequest sir = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
633 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
635 parseRequest(sir, instanceIdMap, action, version, requestJSON, false, requestId);
636 } catch (Exception e) {
637 logger.debug("Validation failed: ", e);
639 msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST, MsoException.ServiceException,
640 "Error parsing request. " + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER, null, version);
641 if (requestId != null) {
642 logger.debug("Logging failed message to the database");
644 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
645 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
646 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
650 RecipeLookupResult recipeLookupResult;
652 recipeLookupResult = getServiceInstanceOrchestrationURI(e2eSir.getService().getServiceUuid(), action);
653 } catch (Exception e) {
654 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
655 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
656 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
657 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
658 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
659 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
663 if (recipeLookupResult == null) {
664 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
665 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
666 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
667 MsoException.ServiceException, "Recipe does not exist in catalog DB",
668 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
669 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
673 String serviceInstanceType = e2eSir.getService().getServiceType();
675 String serviceId = e2eSir.getService().getServiceId();
676 String sirRequestJson = convertToString(sir);
677 RequestClientParameter parameter = new RequestClientParameter.Builder().setRequestId(requestId)
678 .setBaseVfModule(false).setRecipeTimeout(recipeLookupResult.getRecipeTimeout())
679 .setRequestAction(action.name()).setServiceInstanceId(serviceId).setServiceType(serviceInstanceType)
680 .setRequestDetails(sirRequestJson).setApiVersion(version).setALaCarte(false)
681 .setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd()).build();
683 return postRequest(recipeLookupResult.getOrchestrationURI(), parameter, version);
686 private Response scaleE2EserviceInstances(String requestJSON, Action action, String version) throws ApiException {
688 String requestId = UUID.randomUUID().toString();
689 E2EServiceInstanceScaleRequest e2eScaleReq;
691 ObjectMapper mapper = new ObjectMapper();
693 e2eScaleReq = mapper.readValue(requestJSON, E2EServiceInstanceScaleRequest.class);
695 } catch (Exception e) {
697 logger.debug("Mapping of request to JSON object failed : ", e);
698 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
699 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
700 ErrorNumbers.SVC_BAD_PARAMETER, null, version);
701 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_REQUEST_VALIDATION_ERROR.toString(),
702 MSO_PROP_APIHANDLER_INFRA, ErrorCode.SchemaError.getValue(), requestJSON, e);
703 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
707 RecipeLookupResult recipeLookupResult;
709 // TODO Get the service template model version uuid from AAI.
710 recipeLookupResult = getServiceInstanceOrchestrationURI(null, action);
711 } catch (Exception e) {
712 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ACCESS_EXC.toString(), MSO_PROP_APIHANDLER_INFRA,
713 ErrorCode.AvailabilityError.getValue(), "Exception while communciate with Catalog DB", e);
715 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
716 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
717 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
719 msoRequest.createErrorRequestRecord(Status.FAILED, requestId,
720 "No communication to catalog DB " + e.getMessage(), action, ModelType.service.name(), requestJSON,
722 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
725 if (recipeLookupResult == null) {
726 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND.toString(),
727 MSO_PROP_APIHANDLER_INFRA, ErrorCode.DataError.getValue(), "No recipe found in DB");
729 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
730 MsoException.ServiceException, "Recipe does not exist in catalog DB",
731 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null, version);
732 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, "No recipe found in DB", action,
733 ModelType.service.name(), requestJSON, null);
734 logger.debug(END_OF_THE_TRANSACTION + response.getEntity());
737 String bpmnRequest = null;
738 RequestClientParameter postParam = null;
740 JSONObject jjo = new JSONObject(requestJSON);
741 jjo.put("operationId", requestId);
742 bpmnRequest = jjo.toString();
743 String serviceId = instanceIdMap.get(SERVICE_ID);
744 String serviceInstanceType = e2eScaleReq.getService().getServiceType();
745 postParam = new RequestClientParameter.Builder().setRequestId(requestId).setBaseVfModule(false)
746 .setRecipeTimeout(recipeLookupResult.getRecipeTimeout()).setRequestAction(action.name())
747 .setServiceInstanceId(serviceId).setServiceType(serviceInstanceType).setRequestDetails(bpmnRequest)
748 .setApiVersion(version).setALaCarte(false).setRecipeParamXsd(recipeLookupResult.getRecipeParamXsd())
750 } catch (Exception e) {
751 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
752 MsoException.ServiceException, "Failed creating bpmnRequest " + e.getMessage(),
753 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
755 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
756 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
757 "Exception while creating bpmnRequest", e);
758 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
761 return postRequest(recipeLookupResult.getOrchestrationURI(), postParam, version);
764 protected Response postRequest(String orchestrationURI, RequestClientParameter postParam, String version)
765 throws ApiException {
766 ResponseEntity<String> response = null;
768 response = camundaClient.post(postParam, orchestrationURI);
769 } catch (BPMNFailureException e) {
770 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
771 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
772 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
773 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
774 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
775 "Exception while communicate with BPMN engine");
776 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
778 } catch (Exception e) {
779 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
780 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
781 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null, version);
782 logger.error(LoggingAnchor.FOUR, MessageEnum.APIH_BPEL_COMMUNICATE_ERROR.toString(),
783 MSO_PROP_APIHANDLER_INFRA, ErrorCode.AvailabilityError.getValue(),
784 "Exception while communicate with BPMN engine");
785 logger.debug(END_OF_THE_TRANSACTION + resp.getEntity());
788 return bpelStatusUpdate(response, version);
791 private Response bpelStatusUpdate(ResponseEntity<String> responseEntity, String version) throws ApiException {
792 String apiVersion = version.substring(1);
793 responseHandler.acceptedResponse(responseEntity);
794 CamundaResponse camundaResponse = responseHandler.getCamundaResponse(responseEntity);
795 String response = camundaResponse.getResponse();
796 logger.debug(END_OF_THE_TRANSACTION + response);
797 return builder.buildResponse(HttpStatus.SC_ACCEPTED, null, response, apiVersion);
801 * Getting recipes from catalogDb
803 * @param serviceModelUUID the service model version uuid
804 * @param action the action for the service
805 * @return the service recipe result
807 private RecipeLookupResult getServiceInstanceOrchestrationURI(String serviceModelUUID, Action action) {
809 RecipeLookupResult recipeLookupResult = getServiceURI(serviceModelUUID, action);
811 if (recipeLookupResult != null) {
812 logger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI() + ", recipe Timeout is: "
813 + Integer.toString(recipeLookupResult.getRecipeTimeout()));
815 logger.debug("No matching recipe record found");
817 return recipeLookupResult;
821 * Getting recipes from catalogDb If Service recipe is not set, use default recipe, if set , use special recipe.
823 * @param serviceModelUUID the service version uuid
824 * @param action the action of the service.
825 * @return the service recipe result.
827 private RecipeLookupResult getServiceURI(String serviceModelUUID, Action action) {
829 String defaultServiceModelName = "UUI_DEFAULT";
831 Service defaultServiceRecord =
832 catalogDbClient.getFirstByModelNameOrderByModelVersionDesc(defaultServiceModelName);
833 // set recipe as default generic recipe
834 ServiceRecipe recipe =
835 catalogDbClient.getFirstByServiceModelUUIDAndAction(defaultServiceRecord.getModelUUID(), action.name());
836 // check the service special recipe
837 if (null != serviceModelUUID && !serviceModelUUID.isEmpty()) {
838 ServiceRecipe serviceSpecialRecipe =
839 catalogDbClient.getFirstByServiceModelUUIDAndAction(serviceModelUUID, action.name());
840 if (null != serviceSpecialRecipe) {
841 // set service special recipe.
842 recipe = serviceSpecialRecipe;
846 if (recipe == null) {
849 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout(), recipe.getParamXsd());
854 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and passing it to camunda engine.
859 private ServiceInstancesRequest mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
861 ServiceInstancesRequest sir = new ServiceInstancesRequest();
863 RequestDetails requestDetails = new RequestDetails();
864 ModelInfo modelInfo = new ModelInfo();
867 modelInfo.setModelInvariantId(e2eSir.getService().getServiceInvariantUuid());
869 // modelNameVersionId
870 modelInfo.setModelNameVersionId(e2eSir.getService().getServiceUuid());
872 // String modelInfoValue =
873 // e2eSir.getService().getParameters().getNodeTemplateName();
874 // String[] arrayOfInfo = modelInfoValue.split(":");
875 // String modelName = arrayOfInfo[0];
876 // String modelVersion = arrayOfInfo[1];
878 // TODO: To ensure, if we dont get the values from the UUI
879 String modelName = "voLTE";
880 String modelVersion = "1.0";
882 modelInfo.setModelName(modelName);
885 modelInfo.setModelVersion(modelVersion);
888 modelInfo.setModelType(ModelType.service);
890 // setting modelInfo to requestDetails
891 requestDetails.setModelInfo(modelInfo);
893 SubscriberInfo subscriberInfo = new SubscriberInfo();
895 // globalsubscriberId
896 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getGlobalSubscriberId());
898 // setting subscriberInfo to requestDetails
899 requestDetails.setSubscriberInfo(subscriberInfo);
901 RequestInfo requestInfo = new RequestInfo();
904 requestInfo.setInstanceName(e2eSir.getService().getName());
907 requestInfo.setSource("UUI");
910 requestInfo.setSuppressRollback(true);
912 // setting requestInfo to requestDetails
913 requestDetails.setRequestInfo(requestInfo);
915 RequestParameters requestParameters = new RequestParameters();
917 // subscriptionServiceType
918 requestParameters.setSubscriptionServiceType("MOG");
921 List<Map<String, Object>> userParamList = new ArrayList<>();
922 Map<String, Object> userParamMap = new HashMap<>();
923 // complete json request updated in the camunda
924 userParamMap.put("UUIRequest", requestJSON);
925 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
928 userParamList.add(userParamMap);
929 requestParameters.setUserParams(userParamList);
931 // setting requestParameters to requestDetails
932 requestDetails.setRequestParameters(requestParameters);
934 sir.setRequestDetails(requestDetails);
940 private void parseRequest(ServiceInstancesRequest sir, HashMap<String, String> instanceIdMap, Action action,
941 String version, String requestJSON, Boolean aLaCarte, String requestId) throws ValidateException {
942 int reqVersion = Integer.parseInt(version.substring(1));
944 msoRequest.parse(sir, instanceIdMap, action, version, requestJSON, reqVersion, aLaCarte);
945 } catch (Exception e) {
946 ErrorLoggerInfo errorLoggerInfo =
947 new ErrorLoggerInfo.Builder(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, ErrorCode.SchemaError)
948 .errorSource(Constants.MSO_PROP_APIHANDLER_INFRA).build();
949 ValidateException validateException =
950 new ValidateException.Builder("Error parsing request: " + e.getMessage(), HttpStatus.SC_BAD_REQUEST,
951 ErrorNumbers.SVC_BAD_PARAMETER).cause(e).errorInfo(errorLoggerInfo).build();
953 msoRequest.createErrorRequestRecord(Status.FAILED, requestId, validateException.getMessage(), action,
954 ModelType.service.name(), requestJSON, null);
956 throw validateException;
960 private String convertToString(ServiceInstancesRequest sir) {
961 String returnString = null;
962 // converting to string
963 ObjectMapper mapper = new ObjectMapper();
965 returnString = mapper.writeValueAsString(sir);
966 } catch (IOException e) {
967 logger.debug("Exception while converting ServiceInstancesRequest object to string", e);