2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.apihandlerinfra;
23 import java.io.IOException;
24 import java.sql.Timestamp;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
30 import javax.ws.rs.Consumes;
31 import javax.ws.rs.DELETE;
32 import javax.ws.rs.GET;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
40 import org.apache.http.HttpResponse;
41 import org.apache.http.HttpStatus;
42 import org.codehaus.jackson.map.ObjectMapper;
43 import org.eclipse.jetty.io.RuntimeIOException;
44 import org.hibernate.Session;
45 import org.json.JSONObject;
46 import org.openecomp.mso.apihandler.common.ErrorNumbers;
47 import org.openecomp.mso.apihandler.common.RequestClient;
48 import org.openecomp.mso.apihandler.common.RequestClientFactory;
49 import org.openecomp.mso.apihandler.common.ResponseHandler;
50 import org.openecomp.mso.apihandlerinfra.Messages;
51 import org.openecomp.mso.apihandlerinfra.MsoException;
52 import org.openecomp.mso.apihandlerinfra.MsoRequest;
53 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.DelE2ESvcResp;
54 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
55 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
56 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EUserParam;
57 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
58 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ModelInfo;
59 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestDetails;
60 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestInfo;
61 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestParameters;
62 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ServiceInstancesRequest;
63 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.SubscriberInfo;
64 import org.openecomp.mso.db.AbstractSessionFactoryManager;
65 import org.openecomp.mso.db.catalog.CatalogDatabase;
66 import org.openecomp.mso.db.catalog.beans.Service;
67 import org.openecomp.mso.db.catalog.beans.ServiceRecipe;
68 import org.openecomp.mso.logger.MessageEnum;
69 import org.openecomp.mso.logger.MsoAlarmLogger;
70 import org.openecomp.mso.logger.MsoLogger;
71 import org.openecomp.mso.properties.MsoDatabaseException;
72 import org.openecomp.mso.requestsdb.InfraActiveRequests;
73 import org.openecomp.mso.requestsdb.OperationStatus;
74 import org.openecomp.mso.requestsdb.RequestsDatabase;
75 import org.openecomp.mso.requestsdb.RequestsDbSessionFactoryManager;
76 import org.openecomp.mso.utils.UUIDChecker;
78 import com.wordnik.swagger.annotations.Api;
79 import com.wordnik.swagger.annotations.ApiOperation;
81 @Path("/e2eServiceInstances")
82 @Api(value = "/e2eServiceInstances", description = "API Requests for E2E Service Instances")
83 public class E2EServiceInstances {
85 private HashMap<String, String> instanceIdMap = new HashMap<>();
86 private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.APIH);
87 private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
88 public static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
89 private ServiceInstancesRequest sir = null;
91 public static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
92 public static final String EXCEPTION_CREATING_DB_RECORD = "Exception while creating record in DB";
93 public static final String EXCEPTION_COMMUNICATE_BPMN_ENGINE = "Exception while communicate with BPMN engine";
96 * POST Requests for E2E Service create Instance on a version provided
100 @Path("/{version:[vV][3-5]}")
101 @Consumes(MediaType.APPLICATION_JSON)
102 @Produces(MediaType.APPLICATION_JSON)
103 @ApiOperation(value = "Create a E2E Service Instance on a version provided", response = Response.class)
104 public Response createE2EServiceInstance(String request, @PathParam("version") String version) {
106 return processE2EserviceInstances(request, Action.createInstance, null, version);
110 * DELETE Requests for E2E Service delete Instance on a specified version
115 @Path("/{version:[vV][3-5]}/{serviceId}")
116 @Consumes(MediaType.APPLICATION_JSON)
117 @Produces(MediaType.APPLICATION_JSON)
118 @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
119 public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
120 @PathParam("serviceId") String serviceId) {
122 instanceIdMap.put("serviceId", serviceId);
124 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
128 @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
129 @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId", response = Response.class)
130 @Produces(MediaType.APPLICATION_JSON)
131 public Response getE2EServiceInstances(@PathParam("serviceId") String serviceId,
132 @PathParam("version") String version, @PathParam("operationId") String operationId) {
133 RequestsDatabase requestsDB = RequestsDatabase.getInstance();
135 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
137 MsoRequest msoRequest = new MsoRequest(serviceId);
139 long startTime = System.currentTimeMillis();
141 OperationStatus operationStatus = null;
144 operationStatus = requestsDB.getOperationStatus(serviceId, operationId);
146 } catch (Exception e) {
147 msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
148 MsoLogger.ErrorCode.AvailabilityError,
149 "Exception while communciate with Request DB - Infra Request Lookup", e);
150 msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
151 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
152 MsoException.ServiceException, e.getMessage(), ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null);
153 alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
154 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
155 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
156 "Exception while communciate with Request DB");
157 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
162 if (operationStatus == null) {
163 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NO_CONTENT,
164 MsoException.ServiceException, "E2E serviceId " + serviceId + " is not found in DB",
165 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
166 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
167 MsoLogger.ErrorCode.BusinessProcesssError,
168 "Null response from RequestDB when searching by serviceId");
169 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
170 "Null response from RequestDB when searching by serviceId");
171 msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
176 e2eServiceResponse.setE2eRequest(operationStatus);
178 return Response.status(200).entity(e2eServiceResponse).build();
181 private Response deleteE2EserviceInstances(String requestJSON, Action action,
182 HashMap<String, String> instanceIdMap, String version) {
183 //TODO should be a new one or the same service instance Id
184 String requestId = instanceIdMap.get("serviceId");
185 long startTime = System.currentTimeMillis();
186 msoLogger.debug("requestId is: " + requestId);
187 E2EServiceInstanceDeleteRequest e2eDelReq = null;
189 MsoRequest msoRequest = new MsoRequest(requestId);
191 ObjectMapper mapper = new ObjectMapper();
193 e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
195 } catch (Exception e) {
197 msoLogger.debug("Mapping of request to JSON object failed : ", e);
198 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
199 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
200 ErrorNumbers.SVC_BAD_PARAMETER, null);
201 msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
202 MsoLogger.ErrorCode.SchemaError, requestJSON, e);
203 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
204 "Mapping of request to JSON object failed");
205 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
206 createOperationStatusRecordForError(action, requestId);
210 CatalogDatabase db = null;
211 RecipeLookupResult recipeLookupResult = null;
213 db = CatalogDatabase.getInstance();
214 recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
215 } catch (Exception e) {
216 msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
217 MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
218 msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
219 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
220 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
221 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
222 alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
223 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
224 msoRequest.createRequestRecord(Status.FAILED, action);
225 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
226 "Exception while communciate with DB");
227 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
232 if (recipeLookupResult == null) {
233 msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
234 MsoLogger.ErrorCode.DataError, "No recipe found in DB");
235 msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
236 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
237 MsoException.ServiceException, "Recipe does not exist in catalog DB",
238 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
239 msoRequest.createRequestRecord(Status.FAILED, action);
240 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
241 "No recipe found in DB");
242 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
243 createOperationStatusRecordForError(action, requestId);
248 RequestClient requestClient = null;
249 HttpResponse response = null;
251 long subStartTime = System.currentTimeMillis();
252 //String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
255 requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
256 MsoPropertiesUtils.loadMsoProperties());
258 JSONObject jjo = new JSONObject(requestJSON);
259 jjo.put("operationId", UUIDChecker.generateUUID(msoLogger));
261 String bpmnRequest = jjo.toString();
263 // Capture audit event
264 msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
265 String serviceId = instanceIdMap.get("serviceId");
266 String serviceInstanceType = e2eDelReq.getServiceType();
267 response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
268 serviceId, null, null, null, null, serviceInstanceType, null, null, null, bpmnRequest);
270 msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
271 "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
273 } catch (Exception e) {
274 msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
275 MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
276 recipeLookupResult.getOrchestrationURI(), null);
277 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
278 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
279 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
280 alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
281 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
282 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
283 MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
284 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
285 "Exception while communicate with BPMN engine");
286 msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
287 createOperationStatusRecordForError(action, requestId);
291 if (response == null) {
292 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
293 MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
294 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
295 MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
296 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
297 "Null response from BPMN");
298 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
299 createOperationStatusRecordForError(action, requestId);
303 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
304 int bpelStatus = respHandler.getStatus();
306 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action);
309 private Response processE2EserviceInstances(String requestJSON, Action action,
310 HashMap<String, String> instanceIdMap, String version) {
312 String requestId = UUIDChecker.generateUUID(msoLogger);
313 long startTime = System.currentTimeMillis();
314 msoLogger.debug("requestId is: " + requestId);
315 E2EServiceInstanceRequest e2eSir = null;
317 MsoRequest msoRequest = new MsoRequest(requestId);
318 ObjectMapper mapper = new ObjectMapper();
320 e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
322 } catch (Exception e) {
323 //TODO update the service name
324 this.createOperationStatusRecordForError(action, requestId);
326 msoLogger.debug("Mapping of request to JSON object failed : ", e);
327 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
328 MsoException.ServiceException, "Mapping of request to JSON object failed. " + e.getMessage(),
329 ErrorNumbers.SVC_BAD_PARAMETER, null);
330 msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
331 MsoLogger.ErrorCode.SchemaError, requestJSON, e);
332 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
333 "Mapping of request to JSON object failed");
334 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
338 mapReqJsonToSvcInstReq(e2eSir, requestJSON);
339 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
341 msoRequest.parse(sir, instanceIdMap, action, version);
342 } catch (Exception e) {
343 msoLogger.debug("Validation failed: ", e);
344 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
345 MsoException.ServiceException, "Error parsing request. " + e.getMessage(),
346 ErrorNumbers.SVC_BAD_PARAMETER, null);
347 if (msoRequest.getRequestId() != null) {
348 msoLogger.debug("Logging failed message to the database");
349 //TODO update the service name
350 this.createOperationStatusRecordForError(action, requestId);
352 msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
353 MsoLogger.ErrorCode.SchemaError, requestJSON, e);
354 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
355 "Validation of the input request failed");
356 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
360 InfraActiveRequests dup = null;
361 // String instanceName = sir.getService().getName();
362 // String requestScope = sir.getService().getParameters().getNodeType();
363 String instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
364 String requestScope = sir.getRequestDetails().getModelInfo().getModelType().name();
366 if (!(instanceName == null && "service".equals(requestScope)
367 && (action == Action.createInstance || action == Action.activateInstance))) {
368 //TODO : Need to check for the duplicate record from the operation status,
369 //TODO : commenting this check for unblocking current testing for now... induces dead code...
370 // dup = (RequestsDatabase.getInstance()).checkInstanceNameDuplicate(instanceIdMap, instanceName,
373 } catch (Exception e) {
374 msoLogger.error(MessageEnum.APIH_DUPLICATE_CHECK_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
375 MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
377 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
378 MsoException.ServiceException, e.getMessage(), ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
380 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
381 "Error during duplicate check");
382 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
387 // Found the duplicate record. Return the appropriate error.
388 String instance = null;
389 if (instanceName != null) {
390 instance = instanceName;
392 instance = instanceIdMap.get(requestScope + "InstanceId");
394 String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
395 + "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - "
396 + dup.getRequestId() + "). The existing request must finish or be cleaned up before proceeding.";
398 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
399 MsoException.ServiceException, dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
401 msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
402 "Duplicate request - Subscriber already has a request for this service");
405 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict,
407 msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
408 createOperationStatusRecordForError(action, requestId);
412 CatalogDatabase db = null;
413 RecipeLookupResult recipeLookupResult = null;
415 db = CatalogDatabase.getInstance();
416 recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
417 } catch (Exception e) {
418 msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
419 MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
420 msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
421 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
422 MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
423 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
424 alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
425 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
427 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
428 "Exception while communciate with DB");
429 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
430 createOperationStatusRecordForError(action, requestId);
436 if (recipeLookupResult == null) {
437 msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
438 MsoLogger.ErrorCode.DataError, "No recipe found in DB");
439 msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
440 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
441 MsoException.ServiceException, "Recipe does not exist in catalog DB",
442 ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
444 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
445 "No recipe found in DB");
446 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
447 createOperationStatusRecordForError(action, requestId);
452 // msoRequest.createRequestRecord(Status.PENDING, action);
453 // //createOperationStatusRecord(action, requestId);
454 // } catch (Exception e) {
455 // msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "",
456 // MsoLogger.ErrorCode.SchemaError, "Exception while creating record in DB", e);
457 // msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
458 // Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
459 // MsoException.ServiceException, "Exception while creating record in DB " + e.getMessage(),
460 // ErrorNumbers.SVC_BAD_PARAMETER, null);
461 // msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
462 // "Exception while creating record in DB");
463 // msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
467 String serviceInstanceType = e2eSir.getService().getParameters().getServiceType();
469 String serviceId = "";
470 RequestClient requestClient = null;
471 HttpResponse response = null;
473 long subStartTime = System.currentTimeMillis();
474 String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
477 requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
478 MsoPropertiesUtils.loadMsoProperties());
480 // Capture audit event
481 msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
483 response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
484 serviceId, null, null, null, null, serviceInstanceType, null, null, null, sirRequestJson);
486 msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
487 "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
489 } catch (Exception e) {
490 msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
491 MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
492 recipeLookupResult.getOrchestrationURI(), null);
493 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
494 MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
495 ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
496 alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
497 Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
498 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
499 MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
500 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
501 "Exception while communicate with BPMN engine");
502 msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
503 createOperationStatusRecordForError(action, requestId);
507 if (response == null) {
508 Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
509 MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
510 msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
511 MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
512 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
513 "Null response from BPMN");
514 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
518 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
519 int bpelStatus = respHandler.getStatus();
521 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action);
524 private void closeCatalogDB(CatalogDatabase db) {
530 private InfraActiveRequests checkForDuplicateRecord(Action action, HashMap<String, String> instanceIdMap,
531 String instanceName, String requestScope) {
532 InfraActiveRequests dupValue = null;
533 if (!(instanceName == null && "service".equals(requestScope)
534 && (action == Action.createInstance || action == Action.activateInstance))) {
535 dupValue = (RequestsDatabase.getInstance()).checkInstanceNameDuplicate(instanceIdMap, instanceName,
541 private Response duplicateRecordFound(Action action, HashMap<String, String> instanceIdMap, long startTime,
542 MsoRequest msoRequest, InfraActiveRequests dup, String instanceName, String requestScope) {
543 String instance = null;
544 if (instanceName != null) {
545 instance = instanceName;
547 instance = instanceIdMap.get(requestScope + "InstanceId");
549 String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
550 + "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - "
551 + dup.getRequestId() + "). The existing request must finish or be cleaned up before proceeding.";
553 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT, MsoException.ServiceException,
554 dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
556 msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
557 "Duplicate request - Subscriber already has a request for this service");
558 msoRequest.createRequestRecord(Status.FAILED, action);
559 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, dupMessage);
560 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
564 private Response beplStatusUpdate(String requestId, long startTime, MsoRequest msoRequest,
565 RequestClient requestClient, ResponseHandler respHandler, int bpelStatus, Action action) {
566 // BPMN accepted the request, the request is in progress
567 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
568 String camundaJSONResponseBody = respHandler.getResponseBody();
569 msoLogger.debug("Received from Camunda: " + camundaJSONResponseBody);
571 // currently only for delete case we update the status here
572 if(action == Action.deleteInstance){
573 ObjectMapper mapper = new ObjectMapper();
575 DelE2ESvcResp jo = mapper.readValue(camundaJSONResponseBody, DelE2ESvcResp.class);
576 String operationId = jo.getOperationId();
578 this.createOperationStatusRecord("DELETE", requestId, operationId);
582 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR, requestClient.getUrl(), "", "",
583 MsoLogger.ErrorCode.BusinessProcesssError,
584 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
587 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
588 "BPMN accepted the request, the request is in progress");
589 msoLogger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
590 return Response.status(HttpStatus.SC_ACCEPTED).entity(camundaJSONResponseBody).build();
592 List<String> variables = new ArrayList<>();
593 variables.add(bpelStatus + "");
594 String camundaJSONResponseBody = respHandler.getResponseBody();
595 if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
596 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
597 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
598 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
599 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR, requestClient.getUrl(), "", "",
600 MsoLogger.ErrorCode.BusinessProcesssError,
601 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
602 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
603 "Response from BPMN engine is failed");
604 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
607 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
608 "Request Failed due to BPEL error with HTTP Status= %1",
609 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
610 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR, requestClient.getUrl(), "", "",
611 MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is empty");
612 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
613 "Response from BPEL engine is empty");
614 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
621 * Getting recipes from catalogDb
627 private RecipeLookupResult getServiceInstanceOrchestrationURI(CatalogDatabase db, Action action) {
629 RecipeLookupResult recipeLookupResult = getServiceURI(db, action);
631 if (recipeLookupResult != null) {
632 msoLogger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI()
633 + ", recipe Timeout is: " + Integer.toString(recipeLookupResult.getRecipeTimeout()));
635 msoLogger.debug("No matching recipe record found");
637 return recipeLookupResult;
641 * Getting recipes from catalogDb
647 private RecipeLookupResult getServiceURI(CatalogDatabase db, Action action) {
649 String defaultServiceModelName = "UUI_DEFAULT";
651 Service serviceRecord = db.getServiceByModelName(defaultServiceModelName);
652 ServiceRecipe recipe = db.getServiceRecipeByModelUUID(serviceRecord.getModelUUID(), action.name());
654 if (recipe == null) {
657 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
662 * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
663 * passing it to camunda engine.
668 private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
670 sir = new ServiceInstancesRequest();
672 String returnString = null;
673 RequestDetails requestDetails = new RequestDetails();
674 ModelInfo modelInfo = new ModelInfo();
677 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
679 // modelNameVersionId
680 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
682 // String modelInfoValue = e2eSir.getService().getParameters().getNodeTemplateName();
683 // String[] arrayOfInfo = modelInfoValue.split(":");
684 // String modelName = arrayOfInfo[0];
685 // String modelVersion = arrayOfInfo[1];
687 // TODO: To ensure, if we dont get the values from the UUI
688 String modelName = "voLTE";
689 String modelVersion = "1.0";
691 modelInfo.setModelName(modelName);
694 modelInfo.setModelVersion(modelVersion);
697 modelInfo.setModelType(ModelType.service);
699 // setting modelInfo to requestDetails
700 requestDetails.setModelInfo(modelInfo);
702 SubscriberInfo subscriberInfo = new SubscriberInfo();
704 // globalsubscriberId
705 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getParameters().getGlobalSubscriberId());
708 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters().getSubscriberName());
710 // setting subscriberInfo to requestDetails
711 requestDetails.setSubscriberInfo(subscriberInfo);
713 RequestInfo requestInfo = new RequestInfo();
716 requestInfo.setInstanceName(e2eSir.getService().getName());
719 requestInfo.setSource("UUI");
722 requestInfo.setSuppressRollback(true);
724 // setting requestInfo to requestDetails
725 requestDetails.setRequestInfo(requestInfo);
727 RequestParameters requestParameters = new RequestParameters();
729 // subscriptionServiceType
730 requestParameters.setSubscriptionServiceType("MOG");
733 List<E2EUserParam> userParams;
734 //userParams = e2eSir.getService().getParameters().getRequestParameters().getUserParams();
735 List<Map<String, String>> userParamList = new ArrayList<>();
736 Map<String, String> userParamMap = new HashMap<>();
737 //complete json request updated in the camunda
738 userParamMap.put("UUIRequest", requestJSON);
739 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
741 // Map<String, String> userParamMap3 = null;
742 // for (E2EUserParam userp : userParams) {
743 // userParamMap.put(userp.getName(), userp.getValue());
746 userParamList.add(userParamMap);
747 requestParameters.setUserParams(userParamList);
749 // setting requestParameters to requestDetails
750 requestDetails.setRequestParameters(requestParameters);
752 sir.setRequestDetails(requestDetails);
754 // converting to string
755 ObjectMapper mapper = new ObjectMapper();
757 returnString = mapper.writeValueAsString(sir);
758 } catch (IOException e) {
759 msoLogger.debug("Exception while converting ServiceInstancesRequest object to string", e);
766 private void createOperationStatusRecordForError(Action action, String requestId) throws MsoDatabaseException{
768 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
770 Session session = null;
773 session = requestsDbSessionFactoryManager.getSessionFactory().openSession();
774 session.beginTransaction();
776 OperationStatus os = new OperationStatus();
777 os.setOperation(action.name());
778 os.setOperationContent("");
779 os.setOperationId("");
780 os.setProgress("100");
782 os.setResult("error");
783 os.setServiceId(requestId);
785 Timestamp startTimeStamp = new Timestamp (System.currentTimeMillis());
786 Timestamp endTimeStamp = new Timestamp (System.currentTimeMillis());
787 os.setFinishedAt(endTimeStamp);
788 os.setOperateAt(startTimeStamp);
791 session.getTransaction().commit();
793 } catch (Exception e) {
794 msoLogger.error (MessageEnum.APIH_DB_INSERT_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception when creation record request in Operation", e);
795 throw new MsoDatabaseException("Data did inserted in Operatus Status Table for failure", e);
797 if (null != session) {
802 private void createOperationStatusRecord(String actionNm, String serviceId, String operationId) throws MsoDatabaseException{
804 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
806 Session session = null;
809 session = requestsDbSessionFactoryManager.getSessionFactory().openSession();
810 session.beginTransaction();
812 OperationStatus os = new OperationStatus();
813 os.setOperation(actionNm);
814 os.setOperationContent("");
815 os.setOperationId(operationId);
818 os.setResult("processing");
819 os.setServiceId(serviceId);
820 //TODO : to be updated...
822 Timestamp startTimeStamp = new Timestamp (System.currentTimeMillis());
823 Timestamp endTimeStamp = new Timestamp (System.currentTimeMillis());
824 os.setFinishedAt(endTimeStamp);
825 os.setOperateAt(startTimeStamp);
828 session.getTransaction().commit();
830 } catch (Exception e) {
831 msoLogger.error (MessageEnum.APIH_DB_INSERT_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception when creation record request in Operation", e);
832 throw new MsoDatabaseException("Data did inserted in Operatus Status Table", e);
834 if (null != session) {