f6b30e8772eb7d44737bfd7c89eb739255ee12b0
[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                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
247                 } catch (Exception e) {
248                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC,
249                                         MSO_PROP_APIHANDLER_INFRA, "", "",
250                                         MsoLogger.ErrorCode.AvailabilityError,
251                                         "Exception while communciate with Catalog DB", e);
252                         msoRequest
253                                         .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
254                         Response response = msoRequest.buildServiceErrorResponse(
255                                         HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
256                                         "No communication to catalog DB " + e.getMessage(),
257                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
258                         alarmLogger.sendAlarm("MsoDatabaseAccessError",
259                                         MsoAlarmLogger.CRITICAL, Messages.errors
260                                                         .get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
261                         msoRequest.createRequestRecord(Status.FAILED, action);
262                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
263                                         MsoLogger.ResponseCode.DBAccessError,
264                                         "Exception while communciate with DB");
265                         msoLogger.debug(END_OF_THE_TRANSACTION
266                                         + (String) response.getEntity());
267                         return response;
268                 } finally {
269                         closeCatalogDB(db);
270                 }
271                 if (recipeLookupResult == null) {
272                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND,
273                                         MSO_PROP_APIHANDLER_INFRA, "", "",
274                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
275                         msoRequest
276                                         .setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
277                         Response response = msoRequest.buildServiceErrorResponse(
278                                         HttpStatus.SC_NOT_FOUND, MsoException.ServiceException,
279                                         "Recipe does not exist in catalog DB",
280                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
281                         msoRequest.createRequestRecord(Status.FAILED, action);
282                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
283                                         MsoLogger.ResponseCode.DataNotFound,
284                                         "No recipe found in DB");
285                         msoLogger.debug(END_OF_THE_TRANSACTION
286                                         + (String) response.getEntity());
287                         createOperationStatusRecordForError(action, requestId);
288                         return response;
289                 }
290
291                 RequestClient requestClient = null;
292                 HttpResponse response = null;
293
294                 long subStartTime = System.currentTimeMillis();
295                 // String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
296
297                 try {
298                         requestClient = RequestClientFactory.getRequestClient(
299                                         recipeLookupResult.getOrchestrationURI(),
300                                         MsoPropertiesUtils.loadMsoProperties());
301
302                         JSONObject jjo = new JSONObject(requestJSON);
303                         jjo.put("operationId", UUIDChecker.generateUUID(msoLogger));
304
305                         String bpmnRequest = jjo.toString();
306
307                         // Capture audit event
308                         msoLogger
309                                         .debug("MSO API Handler Posting call to BPEL engine for url: "
310                                                         + requestClient.getUrl());
311                         String serviceId = instanceIdMap.get("serviceId");
312                         String serviceInstanceType = e2eDelReq.getServiceType();
313                         response = requestClient.post(requestId, false,
314                                         recipeLookupResult.getRecipeTimeout(), action.name(),
315                                         serviceId, null, null, null, null, serviceInstanceType,
316                                         null, null, null, bpmnRequest);
317
318                         msoLogger.recordMetricEvent(subStartTime,
319                                         MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
320                                         "Successfully received response from BPMN engine", "BPMN",
321                                         recipeLookupResult.getOrchestrationURI(), null);
322                 } catch (Exception e) {
323                         msoLogger.recordMetricEvent(subStartTime,
324                                         MsoLogger.StatusCode.ERROR,
325                                         MsoLogger.ResponseCode.CommunicationError,
326                                         "Exception while communicate with BPMN engine", "BPMN",
327                                         recipeLookupResult.getOrchestrationURI(), null);
328                         Response resp = msoRequest.buildServiceErrorResponse(
329                                         HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
330                                         "Failed calling bpmn " + e.getMessage(),
331                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
332                         alarmLogger.sendAlarm("MsoConfigurationError",
333                                         MsoAlarmLogger.CRITICAL,
334                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
335                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
336                                         MSO_PROP_APIHANDLER_INFRA, "", "",
337                                         MsoLogger.ErrorCode.AvailabilityError,
338                                         "Exception while communicate with BPMN engine");
339                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
340                                         MsoLogger.ResponseCode.CommunicationError,
341                                         "Exception while communicate with BPMN engine");
342                         msoLogger.debug("End of the transaction, the final response is: "
343                                         + (String) resp.getEntity());
344                         createOperationStatusRecordForError(action, requestId);
345                         return resp;
346                 }
347
348                 if (response == null) {
349                         Response resp = msoRequest.buildServiceErrorResponse(
350                                         HttpStatus.SC_BAD_GATEWAY, MsoException.ServiceException,
351                                         "bpelResponse is null",
352                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
353                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR,
354                                         MSO_PROP_APIHANDLER_INFRA, "", "",
355                                         MsoLogger.ErrorCode.BusinessProcesssError,
356                                         "Null response from BPEL");
357                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR,
358                                         MsoLogger.ResponseCode.InternalError,
359                                         "Null response from BPMN");
360                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
361                         createOperationStatusRecordForError(action, requestId);
362                         return resp;
363                 }
364
365                 ResponseHandler respHandler = new ResponseHandler(response,
366                                 requestClient.getType());
367                 int bpelStatus = respHandler.getStatus();
368
369                 return beplStatusUpdate(requestId, startTime, msoRequest,
370                                 requestClient, respHandler, bpelStatus, action, instanceIdMap);
371         }
372
373         private Response processE2EserviceInstances(String requestJSON, Action action,
374                         HashMap<String, String> instanceIdMap, String version) {
375
376                 String requestId = UUIDChecker.generateUUID(msoLogger);
377                 long startTime = System.currentTimeMillis();
378                 msoLogger.debug("requestId is: " + requestId);
379                 E2EServiceInstanceRequest e2eSir = null;
380
381                 MsoRequest msoRequest = new MsoRequest(requestId);
382                 ObjectMapper mapper = new ObjectMapper();
383                 try {
384                         e2eSir = mapper.readValue(requestJSON, E2EServiceInstanceRequest.class);
385
386                 } catch (Exception e) {
387           //TODO update the service name
388           this.createOperationStatusRecordForError(action, requestId);
389                   
390                         msoLogger.debug("Mapping of request to JSON object failed : ", e);
391                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
392                                         MsoException.ServiceException, "Mapping of request to JSON object failed.  " + e.getMessage(),
393                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
394                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
395                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
396                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
397                                         "Mapping of request to JSON object failed");
398                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
399                         return response;
400                 }
401
402                 mapReqJsonToSvcInstReq(e2eSir, requestJSON);
403                 sir.getRequestDetails().getRequestParameters().setaLaCarte(true);
404                 try {
405                         msoRequest.parse(sir, instanceIdMap, action, version);
406                 } catch (Exception e) {
407                         msoLogger.debug("Validation failed: ", e);
408                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_REQUEST,
409                                         MsoException.ServiceException, "Error parsing request.  " + e.getMessage(),
410                                         ErrorNumbers.SVC_BAD_PARAMETER, null);
411                         if (msoRequest.getRequestId() != null) {
412                                 msoLogger.debug("Logging failed message to the database");
413                                 //TODO update the service name
414                           this.createOperationStatusRecordForError(action, requestId);
415                         }
416                         msoLogger.error(MessageEnum.APIH_REQUEST_VALIDATION_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
417                                         MsoLogger.ErrorCode.SchemaError, requestJSON, e);
418                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError,
419                                         "Validation of the input request failed");
420                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
421                         return response;
422                 }
423                 
424                 OperationStatus dup = null;
425                 String instanceName = sir.getRequestDetails().getRequestInfo().getInstanceName();
426                 String requestScope = sir.getRequestDetails().getModelInfo().getModelType().name();
427                 try {
428                         if (!(instanceName == null && "service".equals(requestScope)
429                                         && (action == Action.createInstance || action == Action.activateInstance))) {
430                           //TODO : Need to check for the duplicate record from the operation status,
431                           //TODO : commenting this check for unblocking current testing for now...  induces dead code...
432                                 dup = chkDuplicateServiceNameInOperStatus( instanceName);
433                         }
434                 } catch (Exception e) {
435                         msoLogger.error(MessageEnum.APIH_DUPLICATE_CHECK_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
436                                         MsoLogger.ErrorCode.DataError, "Error during duplicate check ", e);
437
438                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
439                                         MsoException.ServiceException, e.getMessage(), ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
440
441                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
442                                         "Error during duplicate check");
443                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
444                         return response;
445                 }
446
447                 if (dup != null) {
448                         // Found the duplicate record. Return the appropriate error.
449                         String instance = null;
450                         if (instanceName != null) {
451                                 instance = instanceName;
452                         } else {
453                                 instance = instanceIdMap.get(requestScope + "InstanceId");
454                         }
455                         String dupMessage = "Error: Locked instance - This " + requestScope + " (" + instance + ") "
456                                         + "already has a request being worked with a status of " + dup.getProgress() + " (ServiceId - "
457                                         + dup.getServiceId() + "). The existing request must finish or be cleaned up before proceeding.";
458
459                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_CONFLICT,
460                                         MsoException.ServiceException, dupMessage, ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, null);
461
462                         msoLogger.warn(MessageEnum.APIH_DUPLICATE_FOUND, dupMessage, "", "", MsoLogger.ErrorCode.SchemaError,
463                                         "Duplicate request - Subscriber already has a request for this service");
464                         
465                         
466                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict,
467                                         dupMessage);
468                         msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
469                         createOperationStatusRecordForError(action, requestId);
470                         return response;
471                 }
472                 
473                 CatalogDatabase db = null;
474                 RecipeLookupResult recipeLookupResult = null;
475                 try {
476                         db = CatalogDatabase.getInstance();
477                         recipeLookupResult = getServiceInstanceOrchestrationURI(db, action);
478                 } catch (Exception e) {
479                         msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC, MSO_PROP_APIHANDLER_INFRA, "", "",
480                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
481                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
482                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
483                                         MsoException.ServiceException, "No communication to catalog DB " + e.getMessage(),
484                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
485                         alarmLogger.sendAlarm("MsoDatabaseAccessError", MsoAlarmLogger.CRITICAL,
486                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
487                         
488                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
489                                         "Exception while communciate with DB");
490                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
491                         createOperationStatusRecordForError(action, requestId);
492                         return response;
493                 } finally {
494                         closeCatalogDB(db);
495                 }
496
497                 if (recipeLookupResult == null) {
498                         msoLogger.error(MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, MSO_PROP_APIHANDLER_INFRA, "", "",
499                                         MsoLogger.ErrorCode.DataError, "No recipe found in DB");
500                         msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
501                         Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_NOT_FOUND,
502                                         MsoException.ServiceException, "Recipe does not exist in catalog DB",
503                                         ErrorNumbers.SVC_GENERAL_SERVICE_ERROR, null);
504                 
505                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound,
506                                         "No recipe found in DB");
507                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) response.getEntity());
508                         createOperationStatusRecordForError(action, requestId);
509                         return response;
510                 }
511 //              try {
512 //                      msoRequest.createRequestRecord(Status.PENDING, action);
513 //                      //createOperationStatusRecord(action, requestId);
514 //              } catch (Exception e) {
515 //                      msoLogger.error(MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "",
516 //                                      MsoLogger.ErrorCode.SchemaError, "Exception while creating record in DB", e);
517 //                      msoRequest.setStatus(org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
518 //                      Response response = msoRequest.buildServiceErrorResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR,
519 //                                      MsoException.ServiceException, "Exception while creating record in DB " + e.getMessage(),
520 //                                      ErrorNumbers.SVC_BAD_PARAMETER, null);
521 //                      msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError,
522 //                                      "Exception while creating record in DB");
523 //                      msoLogger.debug("End of the transaction, the final response is: " + (String) response.getEntity());
524 //                      return response;
525 //              }
526
527                 String serviceInstanceType = e2eSir.getService().getParameters().getServiceType();
528
529                 String serviceId = "";
530                 RequestClient requestClient = null;
531                 HttpResponse response = null;
532
533                 long subStartTime = System.currentTimeMillis();
534                 String sirRequestJson = mapReqJsonToSvcInstReq(e2eSir, requestJSON);
535
536                 try {
537                         requestClient = RequestClientFactory.getRequestClient(recipeLookupResult.getOrchestrationURI(),
538                                         MsoPropertiesUtils.loadMsoProperties());
539
540                         // Capture audit event
541                         msoLogger.debug("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl());
542
543                         response = requestClient.post(requestId, false, recipeLookupResult.getRecipeTimeout(), action.name(),
544                                         serviceId, null, null, null, null, serviceInstanceType, null, null, null, sirRequestJson);
545
546                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
547                                         "Successfully received response from BPMN engine", "BPMN", recipeLookupResult.getOrchestrationURI(),
548                                         null);
549                 } catch (Exception e) {
550                         msoLogger.recordMetricEvent(subStartTime, MsoLogger.StatusCode.ERROR,
551                                         MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN",
552                                         recipeLookupResult.getOrchestrationURI(), null);
553                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
554                                         MsoException.ServiceException, "Failed calling bpmn " + e.getMessage(),
555                                         ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
556                         alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL,
557                                         Messages.errors.get(ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
558                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
559                                         MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine");
560                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError,
561                                         "Exception while communicate with BPMN engine");
562                         msoLogger.debug("End of the transaction, the final response is: " + (String) resp.getEntity());
563                         createOperationStatusRecordForError(action, requestId);
564                         return resp;
565                 }
566
567                 if (response == null) {
568                         Response resp = msoRequest.buildServiceErrorResponse(HttpStatus.SC_BAD_GATEWAY,
569                                         MsoException.ServiceException, "bpelResponse is null", ErrorNumbers.SVC_NO_SERVER_RESOURCES, null);
570                         msoLogger.error(MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, MSO_PROP_APIHANDLER_INFRA, "", "",
571                                         MsoLogger.ErrorCode.BusinessProcesssError, "Null response from BPEL");
572                         msoLogger.recordAuditEvent(startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError,
573                                         "Null response from BPMN");
574                         msoLogger.debug(END_OF_THE_TRANSACTION + (String) resp.getEntity());
575                         return resp;
576                 }
577
578                 ResponseHandler respHandler = new ResponseHandler(response, requestClient.getType());
579                 int bpelStatus = respHandler.getStatus();
580
581                 return beplStatusUpdate(requestId, startTime, msoRequest, requestClient, respHandler, bpelStatus, action, instanceIdMap);
582         }
583
584         private void closeCatalogDB(CatalogDatabase db) {
585                 if (db != null) {
586                         db.close();
587                 }
588         }
589
590         private Response beplStatusUpdate(String requestId, long startTime,
591                         MsoRequest msoRequest, RequestClient requestClient,
592                         ResponseHandler respHandler, int bpelStatus, Action action,
593                         HashMap<String, String> instanceIdMap) {
594                 // BPMN accepted the request, the request is in progress
595                 if (bpelStatus == HttpStatus.SC_ACCEPTED) {
596                         String camundaJSONResponseBody = respHandler.getResponseBody();
597                         msoLogger
598                                         .debug("Received from Camunda: " + camundaJSONResponseBody);
599
600                         // currently only for delete case we update the status here
601                         if (action == Action.deleteInstance) {
602                                 ObjectMapper mapper = new ObjectMapper();
603                                 try {
604                                         DelE2ESvcResp jo = mapper.readValue(
605                                                         camundaJSONResponseBody, DelE2ESvcResp.class);
606                                         String operationId = jo.getOperationId();
607                                 this.createOperationStatusRecord("DELETE", requestId,
608                                                                 operationId);
609                                 } catch (Exception ex) {
610                                         msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
611                                                         requestClient.getUrl(), "", "",
612                                                         MsoLogger.ErrorCode.BusinessProcesssError,
613                                                         "Response from BPEL engine is failed with HTTP Status="
614                                                                         + bpelStatus);
615                                 }
616                         }
617                         msoLogger.recordAuditEvent(startTime,
618                                         MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
619                                         "BPMN accepted the request, the request is in progress");
620                         msoLogger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
621                         return Response.status(HttpStatus.SC_ACCEPTED)
622                                         .entity(camundaJSONResponseBody).build();
623                 } else {
624                         List<String> variables = new ArrayList<>();
625                         variables.add(bpelStatus + "");
626                         String camundaJSONResponseBody = respHandler.getResponseBody();
627                         if (camundaJSONResponseBody != null
628                                         && !camundaJSONResponseBody.isEmpty()) {
629                                 Response resp = msoRequest.buildServiceErrorResponse(
630                                                 bpelStatus, MsoException.ServiceException,
631                                                 "Request Failed due to BPEL error with HTTP Status= %1 "
632                                                                 + '\n' + camundaJSONResponseBody,
633                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
634                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
635                                                 requestClient.getUrl(), "", "",
636                                                 MsoLogger.ErrorCode.BusinessProcesssError,
637                                                 "Response from BPEL engine is failed with HTTP Status="
638                                                                 + bpelStatus);
639                                 msoLogger.recordAuditEvent(startTime,
640                                                 MsoLogger.StatusCode.ERROR,
641                                                 MsoLogger.ResponseCode.InternalError,
642                                                 "Response from BPMN engine is failed");
643                                 msoLogger.debug(END_OF_THE_TRANSACTION
644                                                 + (String) resp.getEntity());
645                                 return resp;
646                         } else {
647                                 Response resp = msoRequest
648                                                 .buildServiceErrorResponse(
649                                                                 bpelStatus,
650                                                                 MsoException.ServiceException,
651                                                                 "Request Failed due to BPEL error with HTTP Status= %1",
652                                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
653                                                                 variables);
654                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
655                                                 requestClient.getUrl(), "", "",
656                                                 MsoLogger.ErrorCode.BusinessProcesssError,
657                                                 "Response from BPEL engine is empty");
658                                 msoLogger.recordAuditEvent(startTime,
659                                                 MsoLogger.StatusCode.ERROR,
660                                                 MsoLogger.ResponseCode.InternalError,
661                                                 "Response from BPEL engine is empty");
662                                 msoLogger.debug(END_OF_THE_TRANSACTION
663                                                 + (String) resp.getEntity());
664                                 return resp;
665                         }
666                 }
667         }
668
669         /**
670          * Getting recipes from catalogDb
671          * 
672          * @param db
673          * @param action
674          * @return
675          */
676         private RecipeLookupResult getServiceInstanceOrchestrationURI(
677                         CatalogDatabase db, Action action) {
678
679                 RecipeLookupResult recipeLookupResult = getServiceURI(db, action);
680
681                 if (recipeLookupResult != null) {
682                         msoLogger.debug("Orchestration URI is: "
683                                         + recipeLookupResult.getOrchestrationURI()
684                                         + ", recipe Timeout is: "
685                                         + Integer.toString(recipeLookupResult.getRecipeTimeout()));
686                 } else {
687                         msoLogger.debug("No matching recipe record found");
688                 }
689                 return recipeLookupResult;
690         }
691
692         /**
693          * Getting recipes from catalogDb
694          * 
695          * @param db
696          * @param action
697          * @return
698          */
699         private RecipeLookupResult getServiceURI(CatalogDatabase db, Action action) {
700
701                 String defaultServiceModelName = "UUI_DEFAULT";
702
703                 Service serviceRecord = db
704                                 .getServiceByModelName(defaultServiceModelName);
705                 ServiceRecipe recipe = db.getServiceRecipeByModelUUID(
706                                 serviceRecord.getModelUUID(), action.name());
707
708                 if (recipe == null) {
709                         return null;
710                 }
711                 return new RecipeLookupResult(recipe.getOrchestrationUri(),
712                                 recipe.getRecipeTimeout());
713
714         }
715
716         /**
717          * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
718          * passing it to camunda engine.
719          * 
720          * @param e2eSir
721          * @return
722          */
723         private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir,
724                         String requestJSON) {
725
726                 sir = new ServiceInstancesRequest();
727
728                 String returnString = null;
729                 RequestDetails requestDetails = new RequestDetails();
730                 ModelInfo modelInfo = new ModelInfo();
731
732                 // ModelInvariantId
733                 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
734
735                 // modelNameVersionId
736                 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
737
738                 // String modelInfoValue =
739                 // e2eSir.getService().getParameters().getNodeTemplateName();
740                 // String[] arrayOfInfo = modelInfoValue.split(":");
741                 // String modelName = arrayOfInfo[0];
742                 // String modelVersion = arrayOfInfo[1];
743
744                 // TODO: To ensure, if we dont get the values from the UUI
745                 String modelName = "voLTE";
746                 String modelVersion = "1.0";
747                 // modelName
748                 modelInfo.setModelName(modelName);
749
750                 // modelVersion
751                 modelInfo.setModelVersion(modelVersion);
752
753                 // modelType
754                 modelInfo.setModelType(ModelType.service);
755
756                 // setting modelInfo to requestDetails
757                 requestDetails.setModelInfo(modelInfo);
758
759                 SubscriberInfo subscriberInfo = new SubscriberInfo();
760
761                 // globalsubscriberId
762                 subscriberInfo.setGlobalSubscriberId(e2eSir.getService()
763                                 .getParameters().getGlobalSubscriberId());
764
765                 // subscriberName
766                 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters()
767                                 .getSubscriberName());
768
769                 // setting subscriberInfo to requestDetails
770                 requestDetails.setSubscriberInfo(subscriberInfo);
771
772                 RequestInfo requestInfo = new RequestInfo();
773
774                 // instanceName
775                 requestInfo.setInstanceName(e2eSir.getService().getName());
776
777                 // source
778                 requestInfo.setSource("UUI");
779
780                 // suppressRollback
781                 requestInfo.setSuppressRollback(true);
782
783                 // setting requestInfo to requestDetails
784                 requestDetails.setRequestInfo(requestInfo);
785
786                 RequestParameters requestParameters = new RequestParameters();
787
788                 // subscriptionServiceType
789                 requestParameters.setSubscriptionServiceType("MOG");
790
791                 // Userparams
792                 List<E2EUserParam> userParams;
793                 // userParams =
794                 // e2eSir.getService().getParameters().getRequestParameters().getUserParams();
795                 List<Map<String, String>> userParamList = new ArrayList<>();
796                 Map<String, String> userParamMap = new HashMap<>();
797                 // complete json request updated in the camunda
798                 userParamMap.put("UUIRequest", requestJSON);
799                 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
800
801                 // Map<String, String> userParamMap3 = null;
802                 // for (E2EUserParam userp : userParams) {
803                 // userParamMap.put(userp.getName(), userp.getValue());
804                 //
805                 // }
806                 userParamList.add(userParamMap);
807                 requestParameters.setUserParams(userParamList);
808
809                 // setting requestParameters to requestDetails
810                 requestDetails.setRequestParameters(requestParameters);
811
812                 sir.setRequestDetails(requestDetails);
813
814                 // converting to string
815                 ObjectMapper mapper = new ObjectMapper();
816                 try {
817                         returnString = mapper.writeValueAsString(sir);
818                 } catch (IOException e) {
819                         msoLogger
820                                         .debug("Exception while converting ServiceInstancesRequest object to string",
821                                                         e);
822                 }
823
824                 return returnString;
825         }
826
827         private void createOperationStatusRecordForError(Action action,
828                         String requestId) throws MsoDatabaseException {
829
830                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
831
832                 Session session = null;
833                 try {
834
835                         session = requestsDbSessionFactoryManager.getSessionFactory()
836                                         .openSession();
837                         session.beginTransaction();
838
839                         OperationStatus os = new OperationStatus();
840                         os.setOperation(action.name());
841                         os.setOperationContent("");
842                         os.setOperationId("");
843                         os.setProgress("100");
844                         os.setReason("");
845                         os.setResult("error");
846                         os.setServiceId(requestId);
847                         os.setUserId("");
848                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
849                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
850                         os.setFinishedAt(endTimeStamp);
851                         os.setOperateAt(startTimeStamp);
852
853                         session.save(os);
854                         session.getTransaction().commit();
855
856                 } catch (Exception e) {
857                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
858                                         MsoLogger.ErrorCode.DataError,
859                                         "Exception when creation record request in Operation", e);
860                         throw new MsoDatabaseException(
861                                         "Data did inserted in Operatus Status Table for failure", e);
862                 } finally {
863                         if (null != session) {
864                                 session.close();
865                         }
866                 }
867         }
868
869         private void createOperationStatusRecord(String actionNm, String serviceId,
870                         String operationId) throws MsoDatabaseException {
871
872                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
873
874                 Session session = null;
875                 try {
876
877                         session = requestsDbSessionFactoryManager.getSessionFactory()
878                                         .openSession();
879                         session.beginTransaction();
880
881                         OperationStatus os = new OperationStatus();
882                         os.setOperation(actionNm);
883                         os.setOperationContent("");
884                         os.setOperationId(operationId);
885                         os.setProgress("0");
886                         os.setReason("");
887                         os.setResult("processing");
888                         os.setServiceId(serviceId);
889                         // TODO : to be updated...
890                         os.setUserId("");
891                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
892                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
893                         os.setFinishedAt(endTimeStamp);
894                         os.setOperateAt(startTimeStamp);
895
896                         session.save(os);
897                         session.getTransaction().commit();
898
899                 } catch (Exception e) {
900                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
901                                         MsoLogger.ErrorCode.DataError,
902                                         "Exception when creation record request in Operation", e);
903                         throw new MsoDatabaseException(
904                                         "Data did inserted in Operatus Status Table", e);
905                 } finally {
906                         if (null != session) {
907                                 session.close();
908                         }
909                 }
910         }
911
912         private OperationStatus chkDuplicateServiceInOperStatus(String serviceId) {
913                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
914                                 .getOperationStatusByServiceId(serviceId);
915
916                 return dupServiceName;
917         }
918
919         private OperationStatus chkDuplicateServiceNameInOperStatus(
920                         String serviceName) {
921                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
922                                 .getOperationStatusByServiceName(serviceName);
923
924                 return dupServiceName;
925         }
926 }