Merge "Initial commit for the docker build issue"
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / openecomp / mso / apihandlerinfra / E2EServiceInstances.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.openecomp.mso.apihandlerinfra;
22
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;
28 import java.util.Map;
29
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;
39
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;
77
78 import com.wordnik.swagger.annotations.Api;
79 import com.wordnik.swagger.annotations.ApiOperation;
80
81 @Path("/e2eServiceInstances")
82 @Api(value = "/e2eServiceInstances", description = "API Requests for E2E Service Instances")
83 public class E2EServiceInstances {
84
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;
90         
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";
94
95         /**
96          * POST Requests for E2E Service create Instance on a version provided
97          */
98
99         @POST
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) {
105
106                 return processE2EserviceInstances(request, Action.createInstance, null, version);
107         }
108
109         /**
110          * DELETE Requests for E2E Service delete Instance on a specified version
111          * and serviceId
112          */
113
114         @DELETE
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) {
121
122                 instanceIdMap.put("serviceId", serviceId);
123
124                 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
125         }
126         
127         @GET
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();
134                 
135                 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
136
137                 MsoRequest msoRequest = new MsoRequest(serviceId);
138
139                 long startTime = System.currentTimeMillis();
140
141                 OperationStatus operationStatus = null;
142
143                 try {
144                         operationStatus = requestsDB.getOperationStatus(serviceId, operationId);
145
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());
158                         return response;
159
160                 }
161
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());
172                         return resp;
173
174                 }
175
176                 e2eServiceResponse.setE2eRequest(operationStatus);
177
178                 return Response.status(200).entity(e2eServiceResponse).build();
179         }
180
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;
188
189                 MsoRequest msoRequest = new MsoRequest(requestId);
190                 
191                 ObjectMapper mapper = new ObjectMapper();
192                 try {
193                         e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
194
195                 } catch (Exception e) {
196
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);
207                         return response;
208                 }
209                 
210                 CatalogDatabase db = null;
211                 RecipeLookupResult recipeLookupResult = null;
212                 try {
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());
228                         return response;
229                 } finally {
230                         closeCatalogDB(db);
231                 }
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);
244                         return response;
245                 }
246
247                 
248                 RequestClient requestClient = null;
249                 HttpResponse response = null;
250
251                 long subStartTime = System.currentTimeMillis();
252                 //String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
253
254                 try {
255                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
256                                         MsoPropertiesUtils.loadMsoProperties());
257
258                         JSONObject jjo = new JSONObject(requestJSON);
259                         jjo.put("operationId", UUIDChecker.generateUUID(msoLogger));
260                         
261                         String bpmnRequest = jjo.toString();
262                         
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);
269
270                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
271                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
272                                         null);
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);
288                         return resp;
289                 }
290
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);
300                         return resp;
301                 }
302
303                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
304                 int bpelStatus = respHandler.getStatus();
305
306                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action);
307         }
308
309         private Response processE2EserviceInstances(String requestJSON, Action action,
310                         HashMap<String, String> instanceIdMap, String version) {
311
312                 String requestId = UUIDChecker.generateUUID(msoLogger);
313                 long startTime = System.currentTimeMillis();
314                 msoLogger.debug("requestId is: " + requestId);
315                 E2EServiceInstanceRequest e2eSir = null;
316
317                 MsoRequest msoRequest = new MsoRequest(requestId);
318                 ObjectMapper mapper = new ObjectMapper();
319                 try {
320                         e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
321
322                 } catch (Exception e) {
323           //TODO update the service name
324           this.createOperationStatusRecordForError(action, requestId);
325                   
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());
335                         return response;
336                 }
337
338                 mapReqJsonToSvcInstReq(e2eSir, requestJSON);
339                 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
340                 try {
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);
351                         }
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());
357                         return response;
358                 }
359
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();
365                 try {
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,
371 //                                              requestScope);
372                         }
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);
376
377                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
378                                         MsoException.ServiceException, e.getMessage(), ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
379
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());
383                         return response;
384                 }
385
386                 if (dup != null) {
387                         // Found the duplicate record. Return the appropriate error.
388                         String instance = null;
389                         if (instanceName != null) {
390                                 instance = instanceName;
391                         } else {
392                                 instance = instanceIdMap.get(requestScope + "InstanceId");
393                         }
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.";
397
398                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
399                                         MsoException.ServiceException, dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
400
401                         msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
402                                         "Duplicate request - Subscriber already has a request for this service");
403                         
404                         
405                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict,
406                                         dupMessage);
407                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
408                         createOperationStatusRecordForError(action, requestId);
409                         return response;
410                 }
411                 
412                 CatalogDatabase db = null;
413                 RecipeLookupResult recipeLookupResult = null;
414                 try {
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));
426                         
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);
431                         return response;
432                 } finally {
433                         closeCatalogDB(db);
434                 }
435
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);
443                 
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);
448                         return response;
449                 }
450
451 //              try {
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());
464 //                      return response;
465 //              }
466
467                 String serviceInstanceType = e2eSir.getService().getParameters().getServiceType();
468
469                 String serviceId = "";
470                 RequestClient requestClient = null;
471                 HttpResponse response = null;
472
473                 long subStartTime = System.currentTimeMillis();
474                 String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
475
476                 try {
477                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
478                                         MsoPropertiesUtils.loadMsoProperties());
479
480                         // Capture audit event
481                         msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
482
483                         response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
484                                         serviceId, null, null, null, null, serviceInstanceType, null, null, null, sirRequestJson);
485
486                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
487                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
488                                         null);
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);
504                         return resp;
505                 }
506
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());
515                         return resp;
516                 }
517
518                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
519                 int bpelStatus = respHandler.getStatus();
520
521                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action);
522         }
523
524         private void closeCatalogDB(CatalogDatabase db) {
525                 if (db != null) {
526                         db.close();
527                 }
528         }
529
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,
536                                         requestScope);
537                 }
538                 return dupValue;
539         }
540
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;
546                 } else {
547                         instance = instanceIdMap.get(requestScope + "InstanceId");
548                 }
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.";
552
553                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT, MsoException.ServiceException,
554                                 dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
555
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());
561                 return response;
562         }
563
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);
570                         
571                         // currently only for delete case we update the status here
572                         if(action == Action.deleteInstance){
573                                 ObjectMapper mapper = new ObjectMapper();
574                                 try{
575                                         DelE2ESvcResp jo = mapper.readValue(camundaJSONResponseBody, DelE2ESvcResp.class);
576                                         String operationId = jo.getOperationId();
577
578                                         this.createOperationStatusRecord("DELETE", requestId, operationId);
579                                 }
580                                 catch(Exception ex)
581                                 {
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);
585                                 }
586                         }
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();
591                 } else {
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());
605                                 return resp;
606                         } else {
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());
615                                 return resp;
616                         }
617                 }
618         }
619
620         /**
621          * Getting recipes from catalogDb
622          * 
623          * @param db
624          * @param action
625          * @return
626          */
627         private RecipeLookupResult getServiceInstanceOrchestrationURI(CatalogDatabase db, Action action) {
628
629                 RecipeLookupResult recipeLookupResult = getServiceURI(db, action);
630
631                 if (recipeLookupResult != null) {
632                         msoLogger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI()
633                                         + ", recipe Timeout is: " + Integer.toString(recipeLookupResult.getRecipeTimeout()));
634                 } else {
635                         msoLogger.debug("No matching recipe record found");
636                 }
637                 return recipeLookupResult;
638         }
639
640         /**
641          * Getting recipes from catalogDb
642          * 
643          * @param db
644          * @param action
645          * @return
646          */
647         private RecipeLookupResult getServiceURI(CatalogDatabase db, Action action) {
648
649                 String defaultServiceModelName = "UUI_DEFAULT";
650
651                 Service serviceRecord = db.getServiceByModelName(defaultServiceModelName);
652                 ServiceRecipe recipe = db.getServiceRecipeByModelUUID(serviceRecord.getModelUUID(), action.name());
653
654                 if (recipe == null) {
655                         return null;
656                 }
657                 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
658
659         }
660
661         /**
662          * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
663          * passing it to camunda engine.
664          * 
665          * @param e2eSir
666          * @return
667          */
668         private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
669
670                 sir = new ServiceInstancesRequest();
671
672                 String returnString = null;
673                 RequestDetails requestDetails = new RequestDetails();
674                 ModelInfo modelInfo = new ModelInfo();
675
676                 // ModelInvariantId
677                 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
678
679                 // modelNameVersionId
680                 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
681
682 //              String modelInfoValue = e2eSir.getService().getParameters().getNodeTemplateName();
683 //              String[] arrayOfInfo = modelInfoValue.split(":");
684 //              String modelName = arrayOfInfo[0];
685 //              String modelVersion = arrayOfInfo[1];
686
687 //      TODO: To ensure, if we dont get the values from the UUI
688         String modelName = "voLTE";
689         String modelVersion = "1.0";
690                 // modelName
691                 modelInfo.setModelName(modelName);
692
693                 // modelVersion
694                 modelInfo.setModelVersion(modelVersion);
695
696                 // modelType
697                 modelInfo.setModelType(ModelType.service);
698
699                 // setting modelInfo to requestDetails
700                 requestDetails.setModelInfo(modelInfo);
701
702                 SubscriberInfo subscriberInfo = new SubscriberInfo();
703
704                 // globalsubscriberId
705                 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getParameters().getGlobalSubscriberId());
706
707                 // subscriberName
708                 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters().getSubscriberName());
709
710                 // setting subscriberInfo to requestDetails
711                 requestDetails.setSubscriberInfo(subscriberInfo);
712
713                 RequestInfo requestInfo = new RequestInfo();
714
715                 // instanceName
716                 requestInfo.setInstanceName(e2eSir.getService().getName());
717
718                 // source
719                 requestInfo.setSource("UUI");
720
721                 // suppressRollback
722                 requestInfo.setSuppressRollback(true);
723
724                 // setting requestInfo to requestDetails
725                 requestDetails.setRequestInfo(requestInfo);
726
727                 RequestParameters requestParameters = new RequestParameters();
728
729                 // subscriptionServiceType
730                 requestParameters.setSubscriptionServiceType("MOG");
731
732                 // Userparams
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());
740
741 //              Map<String, String> userParamMap3 = null;
742 //              for (E2EUserParam userp : userParams) {
743 //                      userParamMap.put(userp.getName(), userp.getValue());
744 //                      
745 //              }
746                 userParamList.add(userParamMap);
747                 requestParameters.setUserParams(userParamList);
748
749                 // setting requestParameters to requestDetails
750                 requestDetails.setRequestParameters(requestParameters);
751
752                 sir.setRequestDetails(requestDetails);
753
754                 // converting to string
755                 ObjectMapper mapper = new ObjectMapper();
756                 try {
757                         returnString = mapper.writeValueAsString(sir);
758                 } catch (IOException e) {
759                         msoLogger.debug("Exception while converting ServiceInstancesRequest object to string", e);
760                 }
761
762                 return returnString;
763         }
764
765         
766         private void createOperationStatusRecordForError(Action action, String requestId) throws MsoDatabaseException{
767
768                         AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
769
770                         Session session = null;
771                         try {
772
773                                 session = requestsDbSessionFactoryManager.getSessionFactory().openSession();
774                                 session.beginTransaction();
775                                 
776                           OperationStatus os = new OperationStatus();
777                           os.setOperation(action.name());
778                           os.setOperationContent("");
779                           os.setOperationId("");
780                           os.setProgress("100");
781                           os.setReason("");
782                           os.setResult("error");
783                           os.setServiceId(requestId);
784                           os.setUserId("");
785                                 Timestamp startTimeStamp = new Timestamp (System.currentTimeMillis());
786                                 Timestamp endTimeStamp = new Timestamp (System.currentTimeMillis());
787                                 os.setFinishedAt(endTimeStamp);
788                                 os.setOperateAt(startTimeStamp);
789
790                                 session.save(os);
791                                 session.getTransaction().commit();
792
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);
796                         } finally {
797                                 if (null != session) {
798                                         session.close();
799                                 }
800                         }
801                 }
802                         private void createOperationStatusRecord(String actionNm, String serviceId, String operationId) throws MsoDatabaseException{
803
804                                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
805
806                                 Session session = null;
807                                 try {
808
809                                         session = requestsDbSessionFactoryManager.getSessionFactory().openSession();
810                                         session.beginTransaction();
811                                         
812                                   OperationStatus os = new OperationStatus();
813                                   os.setOperation(actionNm);
814                                   os.setOperationContent("");
815                                   os.setOperationId(operationId);
816                                   os.setProgress("0");
817                                   os.setReason("");
818                                   os.setResult("processing");
819                                   os.setServiceId(serviceId);
820                                   //TODO : to be updated...
821                                   os.setUserId("");
822                                           Timestamp startTimeStamp = new Timestamp (System.currentTimeMillis());
823                                           Timestamp endTimeStamp = new Timestamp (System.currentTimeMillis());
824                                           os.setFinishedAt(endTimeStamp);
825                                           os.setOperateAt(startTimeStamp);
826
827                                         session.save(os);
828                                         session.getTransaction().commit();
829
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);
833                                 } finally {
834                                         if (null != session) {
835                                                 session.close();
836                                         }
837                         }
838         }
839 }