2d1d5729275e0bae95a10712b7fb2b616dade71a
[so.git] /
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.POST;
33 import javax.ws.rs.Path;
34 import javax.ws.rs.PathParam;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.core.MediaType;
37 import javax.ws.rs.core.Response;
38
39 import org.apache.http.HttpResponse;
40 import org.apache.http.HttpStatus;
41 import org.codehaus.jackson.map.ObjectMapper;
42 import org.hibernate.Session;
43
44 import org.openecomp.mso.apihandler.common.ErrorNumbers;
45 import org.openecomp.mso.apihandler.common.RequestClient;
46 import org.openecomp.mso.apihandler.common.RequestClientFactory;
47 import org.openecomp.mso.apihandler.common.ResponseHandler;
48 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
49 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
50 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EUserParam;
51 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ModelInfo;
52 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestDetails;
53 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestInfo;
54 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestParameters;
55 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ServiceInstancesRequest;
56 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.SubscriberInfo;
57 import org.openecomp.mso.db.AbstractSessionFactoryManager;
58 import org.openecomp.mso.db.catalog.CatalogDatabase;
59 import org.openecomp.mso.db.catalog.beans.Service;
60 import org.openecomp.mso.db.catalog.beans.ServiceRecipe;
61 import org.openecomp.mso.logger.MessageEnum;
62 import org.openecomp.mso.logger.MsoAlarmLogger;
63 import org.openecomp.mso.logger.MsoLogger;
64 import org.openecomp.mso.requestsdb.InfraActiveRequests;
65 import org.openecomp.mso.requestsdb.OperationStatus;
66 import org.openecomp.mso.requestsdb.RequestsDatabase;
67 import org.openecomp.mso.requestsdb.RequestsDbSessionFactoryManager;
68 import org.openecomp.mso.utils.UUIDChecker;
69
70 import com.wordnik.swagger.annotations.Api;
71 import com.wordnik.swagger.annotations.ApiOperation;
72
73 @Path("/e2eServiceInstances")
74 @Api(value = "/e2eServiceInstances", description = "API Requests for E2E Service Instances")
75 public class E2EServiceInstances {
76
77         private HashMap<String, String> instanceIdMap = new HashMap<>();
78         private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.APIH);
79         private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
80         public static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
81         private ServiceInstancesRequest sir = null;
82         
83         public static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
84         public static final String EXCEPTION_CREATING_DB_RECORD = "Exception while creating record in DB";
85         public static final String EXCEPTION_COMMUNICATE_BPMN_ENGINE = "Exception while communicate with BPMN engine";
86
87         /**
88          * POST Requests for E2E Service create Instance on a version provided
89          */
90
91         @POST
92         @Path("/{version:[vV][3-5]}")
93         @Consumes(MediaType.APPLICATION_JSON)
94         @Produces(MediaType.APPLICATION_JSON)
95         @ApiOperation(value = "Create a E2E Service Instance on a version provided", response = Response.class)
96         public Response createE2EServiceInstance(String request, @PathParam("version") String version) {
97
98                 return processE2EserviceInstances(request, Action.createInstance, null, version);
99         }
100
101         /**
102          * DELETE Requests for E2E Service delete Instance on a specified version
103          * and serviceId
104          */
105
106         @DELETE
107         @Path("/{version:[vV][3-5]}/{serviceId}")
108         @Consumes(MediaType.APPLICATION_JSON)
109         @Produces(MediaType.APPLICATION_JSON)
110         @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
111         public Response deleteE2EServiceInstance(String request, @PathParam("version") String version,
112                         @PathParam("serviceId") String serviceId) {
113
114                 instanceIdMap.put("serviceId", serviceId);
115
116                 return deleteE2EserviceInstances(request, Action.deleteInstance, instanceIdMap, version);
117         }
118
119         private Response deleteE2EserviceInstances(String requestJSON, Action action,
120                         HashMap<String, String> instanceIdMap, String version) {
121                 
122                 String requestId = UUIDChecker.generateUUID(msoLogger);
123                 long startTime = System.currentTimeMillis();
124                 msoLogger.debug("requestId is: " + requestId);
125                 E2EServiceInstanceDeleteRequest e2eDelReq = null;
126
127                 MsoRequest msoRequest = new MsoRequest(requestId);
128                 
129                 ObjectMapper mapper = new ObjectMapper();
130                 try {
131                         e2eDelReq = mapper.readValue(requestJSON, E2EServiceInstanceDeleteRequest.class);
132
133                 } catch (Exception e) {
134
135                         msoLogger.debug("Mapping of request to JSON object failed : ", e);
136                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
137                                         MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
138                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
139                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
140                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
141                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
142                                         "Mapping of request to JSON object failed");
143                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
144                         createOperationStatusRecordForError(action, requestId);
145                         return response;
146                 }
147                 
148                 CatalogDatabase db = null;
149                 RecipeLookupResult recipeLookupResult = null;
150                 try {
151                         db = CatalogDatabase.getInstance();
152                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
153                 } catch (Exception e) {
154                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
155                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
156                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
157                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
158                                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
159                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
160                         alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
161                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
162                         msoRequest.createRequestRecord(Status.FAILED, action);
163                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
164                                         "Exception while communciate with DB");
165                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
166                         return response;
167                 } finally {
168                         closeCatalogDB(db);
169                 }
170                 if (recipeLookupResult == null) {
171                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
172                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
173                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
174                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
175                                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
176                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
177                         msoRequest.createRequestRecord(Status.FAILED, action);
178                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
179                                         "No recipe found in DB");
180                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
181                         createOperationStatusRecordForError(action, requestId);
182                         return response;
183                 }
184
185                 
186                 RequestClient requestClient = null;
187                 HttpResponse response = null;
188
189                 long subStartTime = System.currentTimeMillis();
190                 //String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
191
192                 try {
193                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
194                                         MsoPropertiesUtils.loadMsoProperties());
195
196                         // Capture audit event
197                         msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
198             String serviceId = instanceIdMap.get("serviceId");
199             String serviceInstanceType = e2eDelReq.getServiceType();
200                         response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
201                                         serviceId, null, null, null, null, serviceInstanceType, null, null, null, requestJSON);
202
203                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
204                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
205                                         null);
206                 } catch (Exception e) {
207                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
208                                         MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
209                                         recipeLookupResult.getOrchestrationURI(), null);
210                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
211                                         MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
212                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
213                         alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
214                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
215                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
216                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
217                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
218                                         "Exception while communicate with BPMN engine");
219                         msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
220                         createOperationStatusRecordForError(action, requestId);
221                         return resp;
222                 }
223
224                 if (response == null) {
225                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
226                                         MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
227                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
228                                         MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
229                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
230                                         "Null response from BPMN");
231                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
232                         createOperationStatusRecordForError(action, requestId);
233                         return resp;
234                 }
235
236                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
237                 int bpelStatus = respHandler.getStatus();
238
239                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus);
240         }
241
242         private Response processE2EserviceInstances(String requestJSON, Action action,
243                         HashMap<String, String> instanceIdMap, String version) {
244
245                 String requestId = UUIDChecker.generateUUID(msoLogger);
246                 long startTime = System.currentTimeMillis();
247                 msoLogger.debug("requestId is: " + requestId);
248                 E2EServiceInstanceRequest e2eSir = null;
249
250                 MsoRequest msoRequest = new MsoRequest(requestId);
251                 ObjectMapper mapper = new ObjectMapper();
252                 try {
253                         e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
254
255                 } catch (Exception e) {
256           //TODO update the service name
257           this.createOperationStatusRecordForError(action, requestId);
258                   
259                         msoLogger.debug("Mapping of request to JSON object failed : ", e);
260                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
261                                         MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
262                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
263                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
264                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
265                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
266                                         "Mapping of request to JSON object failed");
267                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
268                         return response;
269                 }
270
271                 mapReqJsonToSvcInstReq(e2eSir, requestJSON);
272                 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
273                 try {
274                         msoRequest.parse(sir, instanceIdMap, action, version);
275                 } catch (Exception e) {
276                         msoLogger.debug("Validation failed: ", e);
277                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
278                                         MsoException.ServiceException, "Error parsing request.  " + e.getMessage(),
279                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
280                         if (msoRequest.getRequestId() != null) {
281                                 msoLogger.debug("Logging failed message to the database");
282                                 //TODO update the service name
283                           this.createOperationStatusRecordForError(action, requestId);
284                         }
285                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
286                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
287                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
288                                         "Validation of the input request failed");
289                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
290                         return response;
291                 }
292
293                 InfraActiveRequests dup = null;
294 //              String instanceName = sir.getService().getName();
295 //              String requestScope = sir.getService().getParameters().getNodeType();
296                 String instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
297                 String requestScope = sir.getRequestDetails().getModelInfo().getModelType().name();
298                 try {
299                         if (!(instanceName == null && "service".equals(requestScope)
300                                         && (action == Action.createInstance || action == Action.activateInstance))) {
301                           //TODO : Need to check for the duplicate record from the operation status,
302                           //TODO : commenting this check for unblocking current testing for now...  induces dead code...
303 //                              dup = (RequestsDatabase.getInstance()).checkInstanceNameDuplicate(instanceIdMap, instanceName,
304 //                                              requestScope);
305                         }
306                 } catch (Exception e) {
307                         msoLogger.error(MessageEnum.APIH_DUPLICATE_CHECK_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
308                                         MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
309
310                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
311                                         MsoException.ServiceException, e.getMessage(), ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
312
313                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
314                                         "Error during duplicate check");
315                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
316                         return response;
317                 }
318
319                 if (dup != null) {
320                         // Found the duplicate record. Return the appropriate error.
321                         String instance = null;
322                         if (instanceName != null) {
323                                 instance = instanceName;
324                         } else {
325                                 instance = instanceIdMap.get(requestScope + "InstanceId");
326                         }
327                         String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
328                                         + "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - "
329                                         + dup.getRequestId() + "). The existing request must finish or be cleaned up before proceeding.";
330
331                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
332                                         MsoException.ServiceException, dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
333
334                         msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
335                                         "Duplicate request - Subscriber already has a request for this service");
336                         
337                         
338                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict,
339                                         dupMessage);
340                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
341                         createOperationStatusRecordForError(action, requestId);
342                         return response;
343                 }
344                 
345                 CatalogDatabase db = null;
346                 RecipeLookupResult recipeLookupResult = null;
347                 try {
348                         db = CatalogDatabase.getInstance();
349                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
350                 } catch (Exception e) {
351                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
352                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
353                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
354                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
355                                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
356                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
357                         alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
358                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
359                         
360                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
361                                         "Exception while communciate with DB");
362                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
363                         createOperationStatusRecordForError(action, requestId);
364                         return response;
365                 } finally {
366                         closeCatalogDB(db);
367                 }
368
369                 if (recipeLookupResult == null) {
370                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
371                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
372                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
373                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
374                                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
375                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
376                 
377                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
378                                         "No recipe found in DB");
379                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
380                         createOperationStatusRecordForError(action, requestId);
381                         return response;
382                 }
383
384 //              try {
385 //                      msoRequest.createRequestRecord(Status.PENDING, action);
386 //                      //createOperationStatusRecord(action, requestId);
387 //              } catch (Exception e) {
388 //                      msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "",
389 //                                      MsoLogger.ErrorCode.SchemaError, "Exception while creating record in DB", e);
390 //                      msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
391 //                      Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
392 //                                      MsoException.ServiceException, "Exception while creating record in DB " + e.getMessage(),
393 //                                      ErrorNumbers.SVC_BAD_PARAMETER, null);
394 //                      msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
395 //                                      "Exception while creating record in DB");
396 //                      msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
397 //                      return response;
398 //              }
399
400                 String serviceInstanceType = e2eSir.getService().getParameters().getServiceType();
401
402                 String serviceId = "";
403                 RequestClient requestClient = null;
404                 HttpResponse response = null;
405
406                 long subStartTime = System.currentTimeMillis();
407                 String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
408
409                 try {
410                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
411                                         MsoPropertiesUtils.loadMsoProperties());
412
413                         // Capture audit event
414                         msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
415
416                         response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
417                                         serviceId, null, null, null, null, serviceInstanceType, null, null, null, sirRequestJson);
418
419                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
420                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
421                                         null);
422                 } catch (Exception e) {
423                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
424                                         MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
425                                         recipeLookupResult.getOrchestrationURI(), null);
426                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
427                                         MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
428                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
429                         alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
430                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
431                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
432                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
433                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
434                                         "Exception while communicate with BPMN engine");
435                         msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
436                         createOperationStatusRecordForError(action, requestId);
437                         return resp;
438                 }
439
440                 if (response == null) {
441                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
442                                         MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
443                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
444                                         MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
445                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
446                                         "Null response from BPMN");
447                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
448                         return resp;
449                 }
450
451                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
452                 int bpelStatus = respHandler.getStatus();
453
454                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus);
455         }
456
457         private void closeCatalogDB(CatalogDatabase db) {
458                 if (db != null) {
459                         db.close();
460                 }
461         }
462
463         private InfraActiveRequests checkForDuplicateRecord(Action action, HashMap<String, String> instanceIdMap,
464                         String instanceName, String requestScope) {
465                 InfraActiveRequests dupValue = null;
466                 if (!(instanceName == null && "service".equals(requestScope)
467                                 && (action == Action.createInstance || action == Action.activateInstance))) {
468                         dupValue = (RequestsDatabase.getInstance()).checkInstanceNameDuplicate(instanceIdMap, instanceName,
469                                         requestScope);
470                 }
471                 return dupValue;
472         }
473
474         private Response duplicateRecordFound(Action action, HashMap<String, String> instanceIdMap, long startTime,
475                         MsoRequest msoRequest, InfraActiveRequests dup, String instanceName, String requestScope) {
476                 String instance = null;
477                 if (instanceName != null) {
478                         instance = instanceName;
479                 } else {
480                         instance = instanceIdMap.get(requestScope + "InstanceId");
481                 }
482                 String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
483                                 + "already has a request being worked with a status of " + dup.getRequestStatus() + " (RequestId - "
484                                 + dup.getRequestId() + "). The existing request must finish or be cleaned up before proceeding.";
485
486                 Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT, MsoException.ServiceException,
487                                 dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
488
489                 msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
490                                 "Duplicate request - Subscriber already has a request for this service");
491                 msoRequest.createRequestRecord(Status.FAILED, action);
492                 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, dupMessage);
493                 msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
494                 return response;
495         }
496
497         private Response beplStatusUpdate(String requestId, long startTime, MsoRequest msoRequest,
498                         RequestClient requestClient, ResponseHandler respHandler, int bpelStatus) {
499                 // BPEL accepted the request, the request is in progress
500                 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
501                         String camundaJSONResponseBody = respHandler.getResponseBody();
502                         msoLogger.debug("Received from Camunda: " + camundaJSONResponseBody);
503
504                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
505                                         "BPMN accepted the request, the request is in progress");
506                         msoLogger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
507                         return Response.status(HttpStatus.SC_ACCEPTED).entity(camundaJSONResponseBody).build();
508                 } else {
509                         List<String> variables = new ArrayList<>();
510                         variables.add(bpelStatus + "");
511                         String camundaJSONResponseBody = respHandler.getResponseBody();
512                         if (camundaJSONResponseBody != null && !camundaJSONResponseBody.isEmpty()) {
513                                 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
514                                                 "Request Failed due to BPEL error with HTTP Status= %1 " + '\n' + camundaJSONResponseBody,
515                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
516                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR, requestClient.getUrl(), "", "",
517                                                 MsoLogger.ErrorCode.BusinessProcesssError,
518                                                 "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
519                                 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
520                                                 "Response from BPMN engine is failed");
521                                 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
522                                 return resp;
523                         } else {
524                                 Response resp = msoRequest.buildServiceErrorResponse(bpelStatus, MsoException.ServiceException,
525                                                 "Request Failed due to BPEL error with HTTP Status= %1",
526                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
527                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR, requestClient.getUrl(), "", "",
528                                                 MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is empty");
529                                 msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
530                                                 "Response from BPEL engine is empty");
531                                 msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
532                                 return resp;
533                         }
534                 }
535         }
536
537         /**
538          * Getting recipes from catalogDb
539          * 
540          * @param db
541          * @param action
542          * @return
543          */
544         private RecipeLookupResult getServiceInstanceOrchestrationURI(CatalogDatabase db, Action action) {
545
546                 RecipeLookupResult recipeLookupResult = getServiceURI(db, action);
547
548                 if (recipeLookupResult != null) {
549                         msoLogger.debug("Orchestration URI is: " + recipeLookupResult.getOrchestrationURI()
550                                         + ", recipe Timeout is: " + Integer.toString(recipeLookupResult.getRecipeTimeout()));
551                 } else {
552                         msoLogger.debug("No matching recipe record found");
553                 }
554                 return recipeLookupResult;
555         }
556
557         /**
558          * Getting recipes from catalogDb
559          * 
560          * @param db
561          * @param action
562          * @return
563          */
564         private RecipeLookupResult getServiceURI(CatalogDatabase db, Action action) {
565
566                 String defaultServiceModelName = "UUI_DEFAULT";
567
568                 Service serviceRecord = db.getServiceByModelName(defaultServiceModelName);
569                 ServiceRecipe recipe = db.getServiceRecipeByModelUUID(serviceRecord.getModelUUID(), action.name());
570
571                 if (recipe == null) {
572                         return null;
573                 }
574                 return new RecipeLookupResult(recipe.getOrchestrationUri(), recipe.getRecipeTimeout());
575
576         }
577
578         /**
579          * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
580          * passing it to camunda engine.
581          * 
582          * @param e2eSir
583          * @return
584          */
585         private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir, String requestJSON) {
586
587                 sir = new ServiceInstancesRequest();
588
589                 String returnString = null;
590                 RequestDetails requestDetails = new RequestDetails();
591                 ModelInfo modelInfo = new ModelInfo();
592
593                 // ModelInvariantId
594                 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
595
596                 // modelNameVersionId
597                 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
598
599 //              String modelInfoValue = e2eSir.getService().getParameters().getNodeTemplateName();
600 //              String[] arrayOfInfo = modelInfoValue.split(":");
601 //              String modelName = arrayOfInfo[0];
602 //              String modelVersion = arrayOfInfo[1];
603
604 //      TODO: To ensure, if we dont get the values from the UUI
605         String modelName = "voLTE";
606         String modelVersion = "1.0";
607                 // modelName
608                 modelInfo.setModelName(modelName);
609
610                 // modelVersion
611                 modelInfo.setModelVersion(modelVersion);
612
613                 // modelType
614                 modelInfo.setModelType(ModelType.service);
615
616                 // setting modelInfo to requestDetails
617                 requestDetails.setModelInfo(modelInfo);
618
619                 SubscriberInfo subscriberInfo = new SubscriberInfo();
620
621                 // globalsubscriberId
622                 subscriberInfo.setGlobalSubscriberId(e2eSir.getService().getParameters().getGlobalSubscriberId());
623
624                 // subscriberName
625                 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters().getSubscriberName());
626
627                 // setting subscriberInfo to requestDetails
628                 requestDetails.setSubscriberInfo(subscriberInfo);
629
630                 RequestInfo requestInfo = new RequestInfo();
631
632                 // instanceName
633                 requestInfo.setInstanceName(e2eSir.getService().getName());
634
635                 // source
636                 requestInfo.setSource("UUI");
637
638                 // suppressRollback
639                 requestInfo.setSuppressRollback(true);
640
641                 // setting requestInfo to requestDetails
642                 requestDetails.setRequestInfo(requestInfo);
643
644                 RequestParameters requestParameters = new RequestParameters();
645
646                 // subscriptionServiceType
647                 requestParameters.setSubscriptionServiceType("MOG");
648
649                 // Userparams
650                 List<E2EUserParam> userParams;
651                 //userParams = e2eSir.getService().getParameters().getRequestParameters().getUserParams();
652                 List<Map<String, String>> userParamList = new ArrayList<>();
653                 Map<String, String> userParamMap = new HashMap<>();
654                 //complete json request updated in the camunda
655                 userParamMap.put("UUIRequest", requestJSON);
656                 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
657
658 //              Map<String, String> userParamMap3 = null;
659 //              for (E2EUserParam userp : userParams) {
660 //                      userParamMap.put(userp.getName(), userp.getValue());
661 //                      
662 //              }
663                 userParamList.add(userParamMap);
664                 requestParameters.setUserParams(userParamList);
665
666                 // setting requestParameters to requestDetails
667                 requestDetails.setRequestParameters(requestParameters);
668
669                 sir.setRequestDetails(requestDetails);
670
671                 // converting to string
672                 ObjectMapper mapper = new ObjectMapper();
673                 try {
674                         returnString = mapper.writeValueAsString(sir);
675                 } catch (IOException e) {
676                         msoLogger.debug("Exception while converting ServiceInstancesRequest object to string", e);
677                 }
678
679                 return returnString;
680         }
681
682         
683         private void createOperationStatusRecordForError(Action action, String requestId) {
684
685                         AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
686
687                         Session session = null;
688                         try {
689
690                                 session = requestsDbSessionFactoryManager.getSessionFactory().openSession();
691                                 session.beginTransaction();
692                                 
693                           OperationStatus os = new OperationStatus();
694                           os.setOperation(action.name());
695                           os.setOperationContent("");
696                           os.setOperationId("");
697                           os.setProgress("100");
698                           os.setReason("");
699                           os.setResult("error");
700                           os.setServiceId(requestId);
701                           os.setUserId("");
702                           os.setFinishedAt(new Timestamp(System.currentTimeMillis()));
703                           os.setOperateAt(new Timestamp(System.currentTimeMillis()));
704
705                                 session.save(os);
706                                 session.getTransaction().commit();
707
708                         } catch (Exception e) {
709                                 msoLogger.error (MessageEnum.APIH_DB_INSERT_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception when creation record request in Operation", e);
710                         } finally {
711                                 if (null != session) {
712                                         session.close();
713                                 }
714                 }
715         }
716 }