Service for VoLTE usecase
IssueId:SO-135
Change-Id: I7cd247400c91a4a9d2fa9b10b917d1657f27c361
Signed-off-by: Seshu-Kumar-M <seshu.kumar.m@huawei.com>
diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/openecomp/mso/apihandlerinfra/E2EServiceInstances.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/openecomp/mso/apihandlerinfra/E2EServiceInstances.java
new file mode 100644
index 0000000..bcab582
--- /dev/null
+++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/openecomp/mso/apihandlerinfra/E2EServiceInstances.java
@@ -0,0 +1,438 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.apihandlerinfra;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.openecomp.mso.apihandler.common.ErrorNumbers;
+import org.openecomp.mso.apihandler.common.RequestClient;
+import org.openecomp.mso.apihandler.common.RequestClientFactory;
+import org.openecomp.mso.apihandler.common.ResponseHandler;
+import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.E2EServiceInstanceRequest;
+import org.openecomp.mso.db.catalog.CatalogDatabase;
+import org.openecomp.mso.db.catalog.beans.Service;
+import org.openecomp.mso.db.catalog.beans.ServiceRecipe;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.properties.MsoJavaProperties;
+import org.openecomp.mso.requestsdb.InfraActiveRequests;
+import org.openecomp.mso.requestsdb.RequestsDatabase;
+import org.openecomp.mso.utils.UUIDChecker;
+
+@Path("/")
+public class E2EServiceInstances {
+
+ private HashMap<String, String> instanceIdMap = new HashMap<String, String>();
+
+ private static MsoLogger msoLogger = MsoLogger
+ .getMsoLogger(MsoLogger.Catalog.APIH);
+
+ private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
+
+ public final static String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
+
+ private static MsoJavaProperties props = MsoPropertiesUtils
+ .loadMsoProperties();
+
+ public E2EServiceInstances() {
+ }
+
+ @POST
+ @Path("e2eServiceInstances/{version:[vV][2-3]}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createE2EServiceInstance(String request,
+ @PathParam("version") String version) {
+
+ Response response = E2EserviceInstances(request, Action.createInstance,
+ null, version);
+
+ return response;
+ }
+
+ @DELETE
+ @Path("e2eServiceInstances/{version:[vV][2-3]}/{serviceId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response deleteE2EServiceInstance(String request,
+ @PathParam("version") String version) {
+
+ Response response = E2EserviceInstances(request, Action.deleteInstance,
+ null, version);
+
+ return response;
+ }
+
+ private Response E2EserviceInstances(String requestJSON, Action action,
+ HashMap<String, String> instanceIdMap, String version) {
+
+ String requestId = UUIDChecker.generateUUID(msoLogger);
+ long startTime = System.currentTimeMillis();
+ msoLogger.debug("requestId is: " + requestId);
+ E2EServiceInstanceRequest sir = null;
+ MsoRequest msoRequest = new MsoRequest(requestId);
+ ObjectMapper mapper = new ObjectMapper();
+ try {
+ sir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
+ } catch (Exception e) {
+
+ msoLogger.debug("Mapping of request to JSON object failed : ", e);
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_BAD_REQUEST,
+ MsoException.ServiceException,
+ "Mapping of request to JSON object failed. "
+ + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER,
+ null);
+ msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.SchemaError, requestJSON, e);
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.SchemaError,
+ "Mapping of request to JSON object failed");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ return response;
+ }
+
+ InfraActiveRequests dup = null;
+ String instanceName = sir.getService().getName();
+ String requestScope = sir.getService().getName();
+
+ try {
+ if (!(instanceName == null && requestScope.equals("E2EService") && action == Action.createInstance)) {
+ dup = (RequestsDatabase.getInstance())
+ .checkInstanceNameDuplicate(instanceIdMap,
+ instanceName, requestScope);
+ }
+ } catch (Exception e) {
+ msoLogger.error(MessageEnum.APIH_DUPLICATE_CHECK_EXC,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.DataError,
+ "Error during duplicate check ", e);
+
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_INTERNAL_SERVER_ERROR,
+ MsoException.ServiceException, e.getMessage(),
+ ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
+
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.DBAccessError,
+ "Error during duplicate check");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ return response;
+ }
+
+ if (dup != null) {
+ // Found the duplicate record. Return the appropriate error.
+ String instance = null;
+ if (instanceName != null) {
+ instance = instanceName;
+ } else {
+ instance = instanceIdMap.get(requestScope + "InstanceId");
+ }
+ String dupMessage = "Error: Locked instance - This "
+ + requestScope
+ + " ("
+ + instance
+ + ") "
+ + "already has a request being worked with a status of "
+ + dup.getRequestStatus()
+ + " (RequestId - "
+ + dup.getRequestId()
+ + "). The existing request must finish or be cleaned up before proceeding.";
+
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_CONFLICT, MsoException.ServiceException,
+ dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
+
+ msoLogger
+ .warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "",
+ MsoLogger.ErrorCode.SchemaError,
+ "Duplicate request - Subscriber already has a request for this service");
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.Conflict, dupMessage);
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ return response;
+ }
+
+ CatalogDatabase db = null;
+ try {
+ db = CatalogDatabase.getInstance();
+ ;
+ } catch (Exception e) {
+ msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.AvailabilityError,
+ "Exception while communciate with Catalog DB", e);
+ msoRequest
+ .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
+ "No communication to catalog DB " + e.getMessage(),
+ ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
+ alarmLogger.sendAlarm("MsoDatabaseAccessError",
+ MsoAlarmLogger.CRITICAL, Messages.errors
+ .get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.DBAccessError,
+ "Exception while communciate with DB");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ return response;
+ }
+
+ RecipeLookupResult recipeLookupResult = null;
+
+ try {
+ recipeLookupResult = getServiceInstanceOrchestrationURI(db, sir, action);
+
+ } catch (Exception e) {
+ msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.DataError,
+ "Exception while querying Catalog DB", e);
+ msoRequest
+ .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_NOT_FOUND,
+ MsoException.ServiceException,
+ "Recipe could not be retrieved from catalog DB "
+ + e.getMessage(),
+ ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
+ alarmLogger.sendAlarm("MsoDatabaseAccessError",
+ MsoAlarmLogger.CRITICAL,
+ Messages.errors.get(ErrorNumbers.ERROR_FROM_CATALOG_DB));
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.DBAccessError,
+ "Exception while querying Catalog DB");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ db.close();
+ return response;
+ }
+
+ if (recipeLookupResult == null) {
+ msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.DataError, "No recipe found in DB");
+ msoRequest
+ .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
+ Response response = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
+ "Recipe does not exist in catalog DB",
+ ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.DataNotFound,
+ "No recipe found in DB");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) response.getEntity());
+ db.close();
+ return response;
+ }
+
+ RequestClient requestClient = null;
+ HttpResponse response = null;
+ long subStartTime = System.currentTimeMillis();
+ try {
+ requestClient = RequestClientFactory.getRequestClient(
+ recipeLookupResult.getOrchestrationURI(), props);
+ // Capture audit event
+ msoLogger
+ .debug("MSO API Handler Posting call to BPEL engine for url: "
+ + requestClient.getUrl());
+
+ // System.out.println("URL : " + requestClient.getUrl());
+
+ response = requestClient
+ .post(requestId, false,
+ recipeLookupResult.getRecipeTimeout(),
+ action.name(), null, null, null, null, null, null,
+ null, null, null, requestJSON);
+
+ msoLogger.recordMetricEvent(subStartTime,
+ MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "Successfully received response from BPMN engine", "BPMN",
+ recipeLookupResult.getOrchestrationURI(), null);
+ } catch (Exception e) {
+ msoLogger.recordMetricEvent(subStartTime,
+ MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.CommunicationError,
+ "Exception while communicate with BPMN engine", "BPMN",
+ recipeLookupResult.getOrchestrationURI(), null);
+ Response resp = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
+ "Failed calling bpmn " + e.getMessage(),
+ ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
+ alarmLogger.sendAlarm("MsoConfigurationError",
+ MsoAlarmLogger.CRITICAL,
+ Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
+ msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.AvailabilityError,
+ "Exception while communicate with BPMN engine");
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.CommunicationError,
+ "Exception while communicate with BPMN engine");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) resp.getEntity());
+ return resp;
+ }
+
+ if (response == null) {
+ Response resp = msoRequest.buildServiceErrorResponse(
+ HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
+ "bpelResponse is null",
+ ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
+ msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
+ MSO_PROP_APIHANDLER_INFRA, "", "",
+ MsoLogger.ErrorCode.BusinessProcesssError,
+ "Null response from BPEL");
+ msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.InternalError,
+ "Null response from BPMN");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) resp.getEntity());
+ return resp;
+ }
+
+ ResponseHandler respHandler = new ResponseHandler(response,
+ requestClient.getType());
+ int bpelStatus = respHandler.getStatus();
+
+ // BPEL accepted the request, the request is in progress
+ if (bpelStatus == HttpStatus.SC_ACCEPTED) {
+ String camundaJSONResponseBody = respHandler.getResponseBody();
+ msoLogger.debug("Received from Camunda: " + camundaJSONResponseBody);
+ (RequestsDatabase.getInstance()).updateInfraStatus(requestId,
+ Status.IN_PROGRESS.toString(),
+ Constants.PROGRESS_REQUEST_IN_PROGRESS,
+ Constants.MODIFIED_BY_APIHANDLER);
+
+ msoLogger.recordAuditEvent(startTime,
+ MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
+ "BPMN accepted the request, the request is in progress");
+ msoLogger.debug("End of the transaction, the final response is: "
+ + (String) camundaJSONResponseBody);
+ return Response.status(HttpStatus.SC_ACCEPTED)
+ .entity(camundaJSONResponseBody).build();
+ } else {
+ List<String> variables = new ArrayList<String>();
+ variables.add(bpelStatus + "");
+ String camundaJSONResponseBody = respHandler.getResponseBody();
+ if (camundaJSONResponseBody != null
+ && !camundaJSONResponseBody.isEmpty()) {
+ Response resp = msoRequest.buildServiceErrorResponse(
+ bpelStatus, MsoException.ServiceException,
+ "Request Failed due to BPEL error with HTTP Status= %1 "
+ + '\n' + camundaJSONResponseBody,
+ ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
+ msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
+ requestClient.getUrl(), "", "",
+ MsoLogger.ErrorCode.BusinessProcesssError,
+ "Response from BPEL engine is failed with HTTP Status="
+ + bpelStatus);
+ msoLogger.recordAuditEvent(startTime,
+ MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.InternalError,
+ "Response from BPMN engine is failed");
+ msoLogger
+ .debug("End of the transaction, the final response is: "
+ + (String) resp.getEntity());
+ return resp;
+ } else {
+ Response resp = msoRequest
+ .buildServiceErrorResponse(
+ bpelStatus,
+ MsoException.ServiceException,
+ "Request Failed due to BPEL error with HTTP Status= %1",
+ ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
+ variables);
+ msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
+ requestClient.getUrl(), "", "",
+ MsoLogger.ErrorCode.BusinessProcesssError,
+ "Response from BPEL engine is empty");
+ msoLogger.recordAuditEvent(startTime,
+ MsoLogger.StatusCode.ERROR,
+ MsoLogger.ResponseCode.InternalError,
+ "Response from BPEL engine is empty");
+ msoLogger
+ .debug("End of the transaction, the final response is: "
+ + (String) resp.getEntity());
+ return resp;
+ }
+ }
+ }
+
+ private RecipeLookupResult getServiceInstanceOrchestrationURI(
+ CatalogDatabase db, E2EServiceInstanceRequest sir, Action action) {
+ RecipeLookupResult recipeLookupResult = null;
+
+ if (sir.getService().getName().equals("E2EService")) {
+ recipeLookupResult = getServiceURI(db, sir, action);
+ }
+ if (recipeLookupResult != null) {
+ msoLogger.debug("Orchestration URI is: "
+ + recipeLookupResult.getOrchestrationURI()
+ + ", recipe Timeout is: "
+ + Integer.toString(recipeLookupResult.getRecipeTimeout()));
+ } else {
+ msoLogger.debug("No matching recipe record found");
+ }
+ return recipeLookupResult;
+ }
+
+ private RecipeLookupResult getServiceURI(CatalogDatabase db,
+ E2EServiceInstanceRequest sir, Action action) {
+
+ Service serviceRecord = null;
+ ServiceRecipe recipe = null;
+
+ if (sir.getService().getName().equalsIgnoreCase("E2EService")) {
+ serviceRecord = db
+ .getServiceByModelName(sir.getService().getName());
+ recipe = db.getServiceRecipeByModelUUID(
+ serviceRecord.getModelUUID(), action.name());
+ }
+ if (recipe == null) {
+ return null;
+ }
+ return new RecipeLookupResult(recipe.getOrchestrationUri(),
+ recipe.getRecipeTimeout());
+
+ }
+}
\ No newline at end of file