09145165980d428863b91ef5949262cad9943463
[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.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.hibernate.Session;
44 import org.json.JSONObject;
45 import org.openecomp.mso.apihandler.common.ErrorNumbers;
46 import org.openecomp.mso.apihandler.common.RequestClient;
47 import org.openecomp.mso.apihandler.common.RequestClientFactory;
48 import org.openecomp.mso.apihandler.common.ResponseHandler;
49 import org.openecomp.mso.apihandlerinfra.Messages;
50 import org.openecomp.mso.apihandlerinfra.MsoException;
51 import org.openecomp.mso.apihandlerinfra.MsoRequest;
52 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.DelE2ESvcResp;
53 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceDeleteRequest;
54 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EServiceInstanceRequest;
55 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.E2EUserParam;
56 import org.openecomp.mso.apihandlerinfra.e2eserviceinstancebeans.GetE2EServiceInstanceResponse;
57 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ModelInfo;
58 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestDetails;
59 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestInfo;
60 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.RequestParameters;
61 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.ServiceInstancesRequest;
62 import org.openecomp.mso.apihandlerinfra.serviceinstancebeans.SubscriberInfo;
63 import org.openecomp.mso.db.AbstractSessionFactoryManager;
64 import org.openecomp.mso.db.catalog.CatalogDatabase;
65 import org.openecomp.mso.db.catalog.beans.Service;
66 import org.openecomp.mso.db.catalog.beans.ServiceRecipe;
67 import org.openecomp.mso.logger.MessageEnum;
68 import org.openecomp.mso.logger.MsoAlarmLogger;
69 import org.openecomp.mso.logger.MsoLogger;
70 import org.openecomp.mso.properties.MsoDatabaseException;
71 import org.openecomp.mso.requestsdb.OperationStatus;
72 import org.openecomp.mso.requestsdb.RequestsDatabase;
73 import org.openecomp.mso.requestsdb.RequestsDbSessionFactoryManager;
74 import org.openecomp.mso.utils.UUIDChecker;
75
76 import com.wordnik.swagger.annotations.Api;
77 import com.wordnik.swagger.annotations.ApiOperation;
78
79 @Path("/e2eServiceInstances")
80 @Api(value = "/e2eServiceInstances", description = "API Requests for E2E Service Instances")
81 public class E2EServiceInstances {
82
83         private HashMap<String, String> instanceIdMap = new HashMap<>();
84         private static MsoLogger msoLogger = MsoLogger
85                         .getMsoLogger(MsoLogger.Catalog.APIH);
86         private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger();
87         public static final String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
88         private ServiceInstancesRequest sir = null;
89
90         public static final String END_OF_THE_TRANSACTION = "End of the transaction, the final response is: ";
91         public static final String EXCEPTION_CREATING_DB_RECORD = "Exception while creating record in DB";
92         public static final String EXCEPTION_COMMUNICATE_BPMN_ENGINE = "Exception while communicate with BPMN engine";
93
94         /**
95          * POST Requests for E2E Service create Instance on a version provided
96          */
97
98         @POST
99         @Path("/{version:[vV][3-5]}")
100         @Consumes(MediaType.APPLICATION_JSON)
101         @Produces(MediaType.APPLICATION_JSON)
102         @ApiOperation(value = "Create a E2E Service Instance on a version provided", response = Response.class)
103         public Response createE2EServiceInstance(String request,
104                         @PathParam("version") String version) {
105
106                 return processE2EserviceInstances(request, Action.createInstance, null,
107                                 version);
108         }
109
110         /**
111          * DELETE Requests for E2E Service delete Instance on a specified version
112          * and serviceId
113          */
114
115         @DELETE
116         @Path("/{version:[vV][3-5]}/{serviceId}")
117         @Consumes(MediaType.APPLICATION_JSON)
118         @Produces(MediaType.APPLICATION_JSON)
119         @ApiOperation(value = "Delete E2E Service Instance on a specified version and serviceId", response = Response.class)
120         public Response deleteE2EServiceInstance(String request,
121                         @PathParam("version") String version,
122                         @PathParam("serviceId") String serviceId) {
123
124                 instanceIdMap.put("serviceId", serviceId);
125
126                 return deleteE2EserviceInstances(request, Action.deleteInstance,
127                                 instanceIdMap, version);
128         }
129
130         @GET
131         @Path("/{version:[vV][3-5]}/{serviceId}/operations/{operationId}")
132         @ApiOperation(value = "Find e2eServiceInstances Requests for a given serviceId and operationId", response = Response.class)
133         @Produces(MediaType.APPLICATION_JSON)
134         public Response getE2EServiceInstances(
135                         @PathParam("serviceId") String serviceId,
136                         @PathParam("version") String version,
137                         @PathParam("operationId") String operationId) {
138                 return getE2EServiceInstances(serviceId, operationId);
139         }
140
141         private Response getE2EServiceInstances(String serviceId, String operationId) {
142                 RequestsDatabase requestsDB = RequestsDatabase.getInstance();
143
144                 GetE2EServiceInstanceResponse e2eServiceResponse = new GetE2EServiceInstanceResponse();
145
146                 MsoRequest msoRequest = new MsoRequest(serviceId);
147
148                 long startTime = System.currentTimeMillis();
149
150                 OperationStatus operationStatus = null;
151
152                 try {
153                         operationStatus = requestsDB.getOperationStatus(serviceId,
154                                         operationId);
155
156                 } catch (Exception e) {
157                         msoLogger
158                                         .error(MessageEnum.APIH_DB_ACCESS_EXC,
159                                                         MSO_PROP_APIHANDLER_INFRA,
160                                                         "",
161                                                         "",
162                                                         MsoLogger.ErrorCode.AvailabilityError,
163                                                         "Exception while communciate with Request DB - Infra Request Lookup",
164                                                         e);
165                         msoRequest
166                                         .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
167                         Response response = msoRequest.buildServiceErrorResponse(
168                                         HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
169                                         e.getMessage(),
170                                         ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB, null);
171                         alarmLogger.sendAlarm("MsoDatabaseAccessError",
172                                         MsoAlarmLogger.CRITICAL, Messages.errors
173                                                         .get(ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
174                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
175                                         MsoLogger.ResponseCode.DBAccessError,
176                                         "Exception while communciate with Request DB");
177                         msoLogger.debug("End of the transaction, the final response is: "
178                                         + (String) response.getEntity());
179                         return response;
180
181                 }
182
183                 if (operationStatus == null) {
184                         Response resp = msoRequest.buildServiceErrorResponse(
185                                         HttpStatus.SC_NO_CONTENT, MsoException.ServiceException,
186                                         "E2E serviceId " + serviceId + " is not found in DB",
187                                         ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
188                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
189                                         MSO_PROP_APIHANDLER_INFRA, "", "",
190                                         MsoLogger.ErrorCode.BusinessProcesssError,
191                                         "Null response from RequestDB when searching by serviceId");
192                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
193                                         MsoLogger.ResponseCode.DataNotFound,
194                                         "Null response from RequestDB when searching by serviceId");
195                         msoLogger.debug("End of the transaction, the final response is: "
196                                         + (String) resp.getEntity());
197                         return resp;
198
199                 }
200
201                 e2eServiceResponse.setOperationStatus(operationStatus);
202
203                 return Response.status(200).entity(e2eServiceResponse).build();
204         }
205
206         private Response deleteE2EserviceInstances(String requestJSON,
207                         Action action, HashMap<String, String> instanceIdMap, String version) {
208                 // TODO should be a new one or the same service instance Id
209                 String requestId = instanceIdMap.get("serviceId");
210                 long startTime = System.currentTimeMillis();
211                 msoLogger.debug("requestId is: " + requestId);
212                 E2EServiceInstanceDeleteRequest e2eDelReq = null;
213
214                 MsoRequest msoRequest = new MsoRequest(requestId);
215
216                 ObjectMapper mapper = new ObjectMapper();
217                 try {
218                         e2eDelReq = mapper.readValue(requestJSON,
219                                         E2EServiceInstanceDeleteRequest.class);
220
221                 } catch (Exception e) {
222
223                         msoLogger.debug("Mapping of request to JSON object failed : ", e);
224                         Response response = msoRequest.buildServiceErrorResponse(
225                                         HttpStatus.SC_BAD_REQUEST,
226                                         MsoException.ServiceException,
227                                         "Mapping of request to JSON object failed.  "
228                                                         + e.getMessage(), ErrorNumbers.SVC_BAD_PARAMETER,
229                                         null);
230                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR,
231                                         MSO_PROP_APIHANDLER_INFRA, "", "",
232                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
233                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
234                                         MsoLogger.ResponseCode.SchemaError,
235                                         "Mapping of request to JSON object failed");
236                         msoLogger.debug("End of the transaction, the final response is: "
237                                         + (String) response.getEntity());
238                         createOperationStatusRecordForError(action, requestId);
239                         return response;
240                 }
241
242                 CatalogDatabase db = null;
243                 RecipeLookupResult recipeLookupResult = null;
244                 try {
245                         db = CatalogDatabase.getInstance();
246                         //TODO  Get the service template model version uuid from AAI.
247                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, null, action);
248                 } catch (Exception e) {
249                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC,
250                                         MSO_PROP_APIHANDLER_INFRA, "", "",
251                                         MsoLogger.ErrorCode.AvailabilityError,
252                                         "Exception while communciate with Catalog DB", e);
253                         msoRequest
254                                         .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
255                         Response response = msoRequest.buildServiceErrorResponse(
256                                         HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
257                                         "No communication to catalog DB " + e.getMessage(),
258                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
259                         alarmLogger.sendAlarm("MsoDatabaseAccessError",
260                                         MsoAlarmLogger.CRITICAL, Messages.errors
261                                                         .get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
262                         msoRequest.createRequestRecord(Status.FAILED, action);
263                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
264                                         MsoLogger.ResponseCode.DBAccessError,
265                                         "Exception while communciate with DB");
266                         msoLogger.debug(END_OF_THE_TRANSACTION
267                                         + (String) response.getEntity());
268                         return response;
269                 } finally {
270                         closeCatalogDB(db);
271                 }
272                 if (recipeLookupResult == null) {
273                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND,
274                                         MSO_PROP_APIHANDLER_INFRA, "", "",
275                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
276                         msoRequest
277                                         .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
278                         Response response = msoRequest.buildServiceErrorResponse(
279                                         HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
280                                         "Recipe does not exist in catalog DB",
281                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
282                         msoRequest.createRequestRecord(Status.FAILED, action);
283                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
284                                         MsoLogger.ResponseCode.DataNotFound,
285                                         "No recipe found in DB");
286                         msoLogger.debug(END_OF_THE_TRANSACTION
287                                         + (String) response.getEntity());
288                         createOperationStatusRecordForError(action, requestId);
289                         return response;
290                 }
291
292                 RequestClient requestClient = null;
293                 HttpResponse response = null;
294
295                 long subStartTime = System.currentTimeMillis();
296                 // String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
297
298                 try {
299                         requestClient = RequestClientFactory.getRequestClient(
300                                         recipeLookupResult.getOrchestrationURI(),
301                                         MsoPropertiesUtils.loadMsoProperties());
302
303                         JSONObject jjo = new JSONObject(requestJSON);
304                         jjo.put("operationId", UUIDChecker.generateUUID(msoLogger));
305
306                         String bpmnRequest = jjo.toString();
307
308                         // Capture audit event
309                         msoLogger
310                                         .debug("MSO API Handler Posting call to BPEL engine for url: "
311                                                         + requestClient.getUrl());
312                         String serviceId = instanceIdMap.get("serviceId");
313                         String serviceInstanceType = e2eDelReq.getServiceType();
314                         response = requestClient.post(requestId, false,
315                                         recipeLookupResult.getRecipeTimeout(), action.name(),
316                                         serviceId, null, null, null, null, serviceInstanceType,
317                                         null, null, null, bpmnRequest, recipeLookupResult.getRecipeParamXsd());
318
319                         msoLogger.recordMetricEvent(subStartTime,
320                                         MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
321                                         "Successfully received response from BPMN engine", "BPMN",
322                                         recipeLookupResult.getOrchestrationURI(), null);
323                 } catch (Exception e) {
324                         msoLogger.recordMetricEvent(subStartTime,
325                                         MsoLogger.StatusCode.ERROR,
326                                         MsoLogger.ResponseCode.CommunicationError,
327                                         "Exception while communicate with BPMN engine", "BPMN",
328                                         recipeLookupResult.getOrchestrationURI(), null);
329                         Response resp = msoRequest.buildServiceErrorResponse(
330                                         HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
331                                         "Failed calling bpmn " + e.getMessage(),
332                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
333                         alarmLogger.sendAlarm("MsoConfigurationError",
334                                         MsoAlarmLogger.CRITICAL,
335                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
336                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
337                                         MSO_PROP_APIHANDLER_INFRA, "", "",
338                                         MsoLogger.ErrorCode.AvailabilityError,
339                                         "Exception while communicate with BPMN engine");
340                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
341                                         MsoLogger.ResponseCode.CommunicationError,
342                                         "Exception while communicate with BPMN engine");
343                         msoLogger.debug("End of the transaction, the final response is: "
344                                         + (String) resp.getEntity());
345                         createOperationStatusRecordForError(action, requestId);
346                         return resp;
347                 }
348
349                 if (response == null) {
350                         Response resp = msoRequest.buildServiceErrorResponse(
351                                         HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
352                                         "bpelResponse is null",
353                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
354                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
355                                         MSO_PROP_APIHANDLER_INFRA, "", "",
356                                         MsoLogger.ErrorCode.BusinessProcesssError,
357                                         "Null response from BPEL");
358                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
359                                         MsoLogger.ResponseCode.InternalError,
360                                         "Null response from BPMN");
361                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
362                         createOperationStatusRecordForError(action, requestId);
363                         return resp;
364                 }
365
366                 ResponseHandler respHandler = new ResponseHandler(response,
367                                 requestClient.getType());
368                 int bpelStatus = respHandler.getStatus();
369
370                 return beplStatusUpdate(requestId, startTime, msoRequest,
371                                 requestClient, respHandler, bpelStatus, action, instanceIdMap);
372         }
373
374         private Response processE2EserviceInstances(String requestJSON, Action action,
375                         HashMap<String, String> instanceIdMap, String version) {
376
377                 String requestId = UUIDChecker.generateUUID(msoLogger);
378                 long startTime = System.currentTimeMillis();
379                 msoLogger.debug("requestId is: " + requestId);
380                 E2EServiceInstanceRequest e2eSir = null;
381
382                 MsoRequest msoRequest = new MsoRequest(requestId);
383                 ObjectMapper mapper = new ObjectMapper();
384                 try {
385                         e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
386
387                 } catch (Exception e) {
388           //TODO update the service name
389           this.createOperationStatusRecordForError(action, requestId);
390                   
391                         msoLogger.debug("Mapping of request to JSON object failed : ", e);
392                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
393                                         MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
394                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
395                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
396                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
397                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
398                                         "Mapping of request to JSON object failed");
399                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
400                         return response;
401                 }
402
403                 mapReqJsonToSvcInstReq(e2eSir, requestJSON);
404                 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
405                 try {
406                         msoRequest.parse(sir, instanceIdMap, action, version);
407                 } catch (Exception e) {
408                         msoLogger.debug("Validation failed: ", e);
409                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
410                                         MsoException.ServiceException, "Error parsing request.  " + e.getMessage(),
411                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
412                         if (msoRequest.getRequestId() != null) {
413                                 msoLogger.debug("Logging failed message to the database");
414                                 //TODO update the service name
415                           this.createOperationStatusRecordForError(action, requestId);
416                         }
417                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
418                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
419                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
420                                         "Validation of the input request failed");
421                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
422                         return response;
423                 }
424                 
425                 OperationStatus dup = null;
426                 String instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
427                 String requestScope = sir.getRequestDetails().getModelInfo().getModelType().name();
428                 try {
429                         if (!(instanceName == null && "service".equals(requestScope)
430                                         && (action == Action.createInstance || action == Action.activateInstance))) {
431                           //TODO : Need to check for the duplicate record from the operation status,
432                           //TODO : commenting this check for unblocking current testing for now...  induces dead code...
433                                 dup = chkDuplicateServiceNameInOperStatus( instanceName);
434                         }
435                 } catch (Exception e) {
436                         msoLogger.error(MessageEnum.APIH_DUPLICATE_CHECK_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
437                                         MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
438
439                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
440                                         MsoException.ServiceException, e.getMessage(), ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
441
442                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
443                                         "Error during duplicate check");
444                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
445                         return response;
446                 }
447
448                 if (dup != null) {
449                         // Found the duplicate record. Return the appropriate error.
450                         String instance = null;
451                         if (instanceName != null) {
452                                 instance = instanceName;
453                         } else {
454                                 instance = instanceIdMap.get(requestScope + "InstanceId");
455                         }
456                         String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
457                                         + "already has a request being worked with a status of " + dup.getProgress() + " (ServiceId - "
458                                         + dup.getServiceId() + "). The existing request must finish or be cleaned up before proceeding.";
459
460                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
461                                         MsoException.ServiceException, dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
462
463                         msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
464                                         "Duplicate request - Subscriber already has a request for this service");
465                         
466                         
467                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict,
468                                         dupMessage);
469                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
470                         createOperationStatusRecordForError(action, requestId);
471                         return response;
472                 }
473                 
474                 CatalogDatabase db = null;
475                 RecipeLookupResult recipeLookupResult = null;
476                 try {
477                         db = CatalogDatabase.getInstance();
478                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, e2eSir.getService().getTemplateId(), action);
479                 } catch (Exception e) {
480                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
481                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
482                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
483                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
484                                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
485                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
486                         alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
487                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
488                         
489                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
490                                         "Exception while communciate with DB");
491                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
492                         createOperationStatusRecordForError(action, requestId);
493                         return response;
494                 } finally {
495                         closeCatalogDB(db);
496                 }
497
498                 if (recipeLookupResult == null) {
499                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
500                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
501                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
502                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
503                                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
504                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
505                 
506                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
507                                         "No recipe found in DB");
508                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
509                         createOperationStatusRecordForError(action, requestId);
510                         return response;
511                 }
512 //              try {
513 //                      msoRequest.createRequestRecord(Status.PENDING, action);
514 //                      //createOperationStatusRecord(action, requestId);
515 //              } catch (Exception e) {
516 //                      msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "",
517 //                                      MsoLogger.ErrorCode.SchemaError, "Exception while creating record in DB", e);
518 //                      msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
519 //                      Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
520 //                                      MsoException.ServiceException, "Exception while creating record in DB " + e.getMessage(),
521 //                                      ErrorNumbers.SVC_BAD_PARAMETER, null);
522 //                      msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
523 //                                      "Exception while creating record in DB");
524 //                      msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
525 //                      return response;
526 //              }
527
528                 String serviceInstanceType = e2eSir.getService().getParameters().getServiceType();
529
530                 String serviceId = "";
531                 RequestClient requestClient = null;
532                 HttpResponse response = null;
533
534                 long subStartTime = System.currentTimeMillis();
535                 String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
536
537                 try {
538                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
539                                         MsoPropertiesUtils.loadMsoProperties());
540
541                         // Capture audit event
542                         msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
543
544                         response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
545                                         serviceId, null, null, null, null, serviceInstanceType, null, null, null, sirRequestJson, recipeLookupResult.getRecipeParamXsd());
546
547                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
548                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
549                                         null);
550                 } catch (Exception e) {
551                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
552                                         MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
553                                         recipeLookupResult.getOrchestrationURI(), null);
554                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
555                                         MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
556                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
557                         alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
558                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
559                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
560                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
561                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
562                                         "Exception while communicate with BPMN engine");
563                         msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
564                         createOperationStatusRecordForError(action, requestId);
565                         return resp;
566                 }
567
568                 if (response == null) {
569                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
570                                         MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
571                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
572                                         MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
573                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
574                                         "Null response from BPMN");
575                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
576                         return resp;
577                 }
578
579                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
580                 int bpelStatus = respHandler.getStatus();
581
582                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action, instanceIdMap);
583         }
584
585         private void closeCatalogDB(CatalogDatabase db) {
586                 if (db != null) {
587                         db.close();
588                 }
589         }
590
591         private Response beplStatusUpdate(String requestId, long startTime,
592                         MsoRequest msoRequest, RequestClient requestClient,
593                         ResponseHandler respHandler, int bpelStatus, Action action,
594                         HashMap<String, String> instanceIdMap) {
595                 // BPMN accepted the request, the request is in progress
596                 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
597                         String camundaJSONResponseBody = respHandler.getResponseBody();
598                         msoLogger
599                                         .debug("Received from Camunda: " + camundaJSONResponseBody);
600
601                         // currently only for delete case we update the status here
602                         if (action == Action.deleteInstance) {
603                                 ObjectMapper mapper = new ObjectMapper();
604                                 try {
605                                         DelE2ESvcResp jo = mapper.readValue(
606                                                         camundaJSONResponseBody, DelE2ESvcResp.class);
607                                         String operationId = jo.getOperationId();
608                                 this.createOperationStatusRecord("DELETE", requestId,
609                                                                 operationId);
610                                 } catch (Exception ex) {
611                                         msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
612                                                         requestClient.getUrl(), "", "",
613                                                         MsoLogger.ErrorCode.BusinessProcesssError,
614                                                         "Response from BPEL engine is failed with HTTP Status="
615                                                                         + bpelStatus);
616                                 }
617                         }
618                         msoLogger.recordAuditEvent(startTime,
619                                         MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
620                                         "BPMN accepted the request, the request is in progress");
621                         msoLogger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
622                         return Response.status(HttpStatus.SC_ACCEPTED)
623                                         .entity(camundaJSONResponseBody).build();
624                 } else {
625                         List<String> variables = new ArrayList<>();
626                         variables.add(bpelStatus + "");
627                         String camundaJSONResponseBody = respHandler.getResponseBody();
628                         if (camundaJSONResponseBody != null
629                                         && !camundaJSONResponseBody.isEmpty()) {
630                                 Response resp = msoRequest.buildServiceErrorResponse(
631                                                 bpelStatus, MsoException.ServiceException,
632                                                 "Request Failed due to BPEL error with HTTP Status= %1 "
633                                                                 + '\n' + camundaJSONResponseBody,
634                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
635                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
636                                                 requestClient.getUrl(), "", "",
637                                                 MsoLogger.ErrorCode.BusinessProcesssError,
638                                                 "Response from BPEL engine is failed with HTTP Status="
639                                                                 + bpelStatus);
640                                 msoLogger.recordAuditEvent(startTime,
641                                                 MsoLogger.StatusCode.ERROR,
642                                                 MsoLogger.ResponseCode.InternalError,
643                                                 "Response from BPMN engine is failed");
644                                 msoLogger.debug(END_OF_THE_TRANSACTION
645                                                 + (String) resp.getEntity());
646                                 return resp;
647                         } else {
648                                 Response resp = msoRequest
649                                                 .buildServiceErrorResponse(
650                                                                 bpelStatus,
651                                                                 MsoException.ServiceException,
652                                                                 "Request Failed due to BPEL error with HTTP Status= %1",
653                                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
654                                                                 variables);
655                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
656                                                 requestClient.getUrl(), "", "",
657                                                 MsoLogger.ErrorCode.BusinessProcesssError,
658                                                 "Response from BPEL engine is empty");
659                                 msoLogger.recordAuditEvent(startTime,
660                                                 MsoLogger.StatusCode.ERROR,
661                                                 MsoLogger.ResponseCode.InternalError,
662                                                 "Response from BPEL engine is empty");
663                                 msoLogger.debug(END_OF_THE_TRANSACTION
664                                                 + (String) resp.getEntity());
665                                 return resp;
666                         }
667                 }
668         }
669
670         /**
671          * Getting recipes from catalogDb
672          * 
673          * @param db the catalog db
674          * @param serviceModelUUID the service model version uuid
675          * @param action the action for the service
676          * @return the service recipe result
677          */
678         private RecipeLookupResult getServiceInstanceOrchestrationURI(
679                         CatalogDatabase db, String serviceModelUUID, Action action) {
680
681                 RecipeLookupResult recipeLookupResult = getServiceURI(db, serviceModelUUID, action);
682
683                 if (recipeLookupResult != null) {
684                         msoLogger.debug("Orchestration URI is: "
685                                         + recipeLookupResult.getOrchestrationURI()
686                                         + ", recipe Timeout is: "
687                                         + Integer.toString(recipeLookupResult.getRecipeTimeout()));
688                 } else {
689                         msoLogger.debug("No matching recipe record found");
690                 }
691                 return recipeLookupResult;
692         }
693
694         /**
695          * Getting recipes from catalogDb
696          * If Service recipe is not set, use default recipe, if set , use special recipe.
697          * @param db the catalog db
698          * @param serviceModelUUID the service version uuid
699          * @param action the action of the service.
700          * @return the service recipe result.
701          */
702         private RecipeLookupResult getServiceURI(CatalogDatabase db, String serviceModelUUID, Action action) {
703
704                 String defaultServiceModelName = "UUI_DEFAULT";
705
706                 Service defaultServiceRecord = db
707                                 .getServiceByModelName(defaultServiceModelName);
708                 ServiceRecipe defaultRecipe = db.getServiceRecipeByModelUUID(
709                         defaultServiceRecord.getModelUUID(), action.name());
710                 //set recipe as default generic recipe
711                 ServiceRecipe recipe = defaultRecipe;
712                 //check the service special recipe 
713                 if(null != serviceModelUUID && ! serviceModelUUID.isEmpty()){
714                       ServiceRecipe serviceSpecialRecipe = db.getServiceRecipeByModelUUID(
715                               serviceModelUUID, action.name());
716                       if(null != serviceSpecialRecipe){
717                           //set service special recipe.
718                           recipe = serviceSpecialRecipe;
719                       }
720                 }       
721                 
722                 if (recipe == null) {
723                         return null;
724                 }
725                 return new RecipeLookupResult(recipe.getOrchestrationUri(),
726                                 recipe.getRecipeTimeout(), recipe.getServiceParamXSD());
727
728         }
729
730         /**
731          * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
732          * passing it to camunda engine.
733          * 
734          * @param e2eSir
735          * @return
736          */
737         private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir,
738                         String requestJSON) {
739
740                 sir = new ServiceInstancesRequest();
741
742                 String returnString = null;
743                 RequestDetails requestDetails = new RequestDetails();
744                 ModelInfo modelInfo = new ModelInfo();
745
746                 // ModelInvariantId
747                 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
748
749                 // modelNameVersionId
750                 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
751
752                 // String modelInfoValue =
753                 // e2eSir.getService().getParameters().getNodeTemplateName();
754                 // String[] arrayOfInfo = modelInfoValue.split(":");
755                 // String modelName = arrayOfInfo[0];
756                 // String modelVersion = arrayOfInfo[1];
757
758                 // TODO: To ensure, if we dont get the values from the UUI
759                 String modelName = "voLTE";
760                 String modelVersion = "1.0";
761                 // modelName
762                 modelInfo.setModelName(modelName);
763
764                 // modelVersion
765                 modelInfo.setModelVersion(modelVersion);
766
767                 // modelType
768                 modelInfo.setModelType(ModelType.service);
769
770                 // setting modelInfo to requestDetails
771                 requestDetails.setModelInfo(modelInfo);
772
773                 SubscriberInfo subscriberInfo = new SubscriberInfo();
774
775                 // globalsubscriberId
776                 subscriberInfo.setGlobalSubscriberId(e2eSir.getService()
777                                 .getParameters().getGlobalSubscriberId());
778
779                 // subscriberName
780                 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters()
781                                 .getSubscriberName());
782
783                 // setting subscriberInfo to requestDetails
784                 requestDetails.setSubscriberInfo(subscriberInfo);
785
786                 RequestInfo requestInfo = new RequestInfo();
787
788                 // instanceName
789                 requestInfo.setInstanceName(e2eSir.getService().getName());
790
791                 // source
792                 requestInfo.setSource("UUI");
793
794                 // suppressRollback
795                 requestInfo.setSuppressRollback(true);
796
797                 // setting requestInfo to requestDetails
798                 requestDetails.setRequestInfo(requestInfo);
799
800                 RequestParameters requestParameters = new RequestParameters();
801
802                 // subscriptionServiceType
803                 requestParameters.setSubscriptionServiceType("MOG");
804
805                 // Userparams
806                 List<E2EUserParam> userParams;
807                 // userParams =
808                 // e2eSir.getService().getParameters().getRequestParameters().getUserParams();
809                 List<Map<String, String>> userParamList = new ArrayList<>();
810                 Map<String, String> userParamMap = new HashMap<>();
811                 // complete json request updated in the camunda
812                 userParamMap.put("UUIRequest", requestJSON);
813                 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
814
815                 // Map<String, String> userParamMap3 = null;
816                 // for (E2EUserParam userp : userParams) {
817                 // userParamMap.put(userp.getName(), userp.getValue());
818                 //
819                 // }
820                 userParamList.add(userParamMap);
821                 requestParameters.setUserParams(userParamList);
822
823                 // setting requestParameters to requestDetails
824                 requestDetails.setRequestParameters(requestParameters);
825
826                 sir.setRequestDetails(requestDetails);
827
828                 // converting to string
829                 ObjectMapper mapper = new ObjectMapper();
830                 try {
831                         returnString = mapper.writeValueAsString(sir);
832                 } catch (IOException e) {
833                         msoLogger
834                                         .debug("Exception while converting ServiceInstancesRequest object to string",
835                                                         e);
836                 }
837
838                 return returnString;
839         }
840
841         private void createOperationStatusRecordForError(Action action,
842                         String requestId) throws MsoDatabaseException {
843
844                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
845
846                 Session session = null;
847                 try {
848
849                         session = requestsDbSessionFactoryManager.getSessionFactory()
850                                         .openSession();
851                         session.beginTransaction();
852
853                         OperationStatus os = new OperationStatus();
854                         os.setOperation(action.name());
855                         os.setOperationContent("");
856                         os.setOperationId("");
857                         os.setProgress("100");
858                         os.setReason("");
859                         os.setResult("error");
860                         os.setServiceId(requestId);
861                         os.setUserId("");
862                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
863                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
864                         os.setFinishedAt(endTimeStamp);
865                         os.setOperateAt(startTimeStamp);
866
867                         session.save(os);
868                         session.getTransaction().commit();
869
870                 } catch (Exception e) {
871                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
872                                         MsoLogger.ErrorCode.DataError,
873                                         "Exception when creation record request in Operation", e);
874                         throw new MsoDatabaseException(
875                                         "Data did inserted in Operatus Status Table for failure", e);
876                 } finally {
877                         if (null != session) {
878                                 session.close();
879                         }
880                 }
881         }
882
883         private void createOperationStatusRecord(String actionNm, String serviceId,
884                         String operationId) throws MsoDatabaseException {
885
886                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
887
888                 Session session = null;
889                 try {
890
891                         session = requestsDbSessionFactoryManager.getSessionFactory()
892                                         .openSession();
893                         session.beginTransaction();
894
895                         OperationStatus os = new OperationStatus();
896                         os.setOperation(actionNm);
897                         os.setOperationContent("");
898                         os.setOperationId(operationId);
899                         os.setProgress("0");
900                         os.setReason("");
901                         os.setResult("processing");
902                         os.setServiceId(serviceId);
903                         // TODO : to be updated...
904                         os.setUserId("");
905                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
906                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
907                         os.setFinishedAt(endTimeStamp);
908                         os.setOperateAt(startTimeStamp);
909
910                         session.save(os);
911                         session.getTransaction().commit();
912
913                 } catch (Exception e) {
914                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
915                                         MsoLogger.ErrorCode.DataError,
916                                         "Exception when creation record request in Operation", e);
917                         throw new MsoDatabaseException(
918                                         "Data did inserted in Operatus Status Table", e);
919                 } finally {
920                         if (null != session) {
921                                 session.close();
922                         }
923                 }
924         }
925
926         private OperationStatus chkDuplicateServiceInOperStatus(String serviceId) {
927                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
928                                 .getOperationStatusByServiceId(serviceId);
929
930                 return dupServiceName;
931         }
932
933         private OperationStatus chkDuplicateServiceNameInOperStatus(
934                         String serviceName) {
935                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
936                                 .getOperationStatusByServiceName(serviceName);
937
938                 return dupServiceName;
939         }
940 }