f5d068f900e53e72efd7eed37f0a87c810196503
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / openecomp / mso / apihandlerinfra / E2EServiceInstances.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 Huawei Technologies Co., Ltd. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.apihandlerinfra;
22
23 import java.io.IOException;
24 import java.sql.Timestamp;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.ws.rs.Consumes;
31 import javax.ws.rs.DELETE;
32 import javax.ws.rs.GET;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.PathParam;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
39
40 import org.apache.http.HttpResponse;
41 import org.apache.http.HttpStatus;
42 import org.codehaus.jackson.map.ObjectMapper;
43 import org.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                                         OperationStatus operStatus = chkDuplicateServiceInOperStatus(instanceIdMap
608                                                         .get("serviceId"));
609                                         if (null != operStatus) {
610                                                 msoLogger
611                                                                 .debug("One task is already in progress state for this service id");
612                                         } else {
613                                                 this.createOperationStatusRecord("DELETE", requestId,
614                                                                 operationId);
615                                         }
616                                 } catch (Exception ex) {
617                                         msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
618                                                         requestClient.getUrl(), "", "",
619                                                         MsoLogger.ErrorCode.BusinessProcesssError,
620                                                         "Response from BPEL engine is failed with HTTP Status="
621                                                                         + bpelStatus);
622                                 }
623                         }
624                         msoLogger.recordAuditEvent(startTime,
625                                         MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc,
626                                         "BPMN accepted the request, the request is in progress");
627                         msoLogger.debug(END_OF_THE_TRANSACTION + camundaJSONResponseBody);
628                         return Response.status(HttpStatus.SC_ACCEPTED)
629                                         .entity(camundaJSONResponseBody).build();
630                 } else {
631                         List<String> variables = new ArrayList<>();
632                         variables.add(bpelStatus + "");
633                         String camundaJSONResponseBody = respHandler.getResponseBody();
634                         if (camundaJSONResponseBody != null
635                                         && !camundaJSONResponseBody.isEmpty()) {
636                                 Response resp = msoRequest.buildServiceErrorResponse(
637                                                 bpelStatus, MsoException.ServiceException,
638                                                 "Request Failed due to BPEL error with HTTP Status= %1 "
639                                                                 + '\n' + camundaJSONResponseBody,
640                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR, variables);
641                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
642                                                 requestClient.getUrl(), "", "",
643                                                 MsoLogger.ErrorCode.BusinessProcesssError,
644                                                 "Response from BPEL engine is failed with HTTP Status="
645                                                                 + bpelStatus);
646                                 msoLogger.recordAuditEvent(startTime,
647                                                 MsoLogger.StatusCode.ERROR,
648                                                 MsoLogger.ResponseCode.InternalError,
649                                                 "Response from BPMN engine is failed");
650                                 msoLogger.debug(END_OF_THE_TRANSACTION
651                                                 + (String) resp.getEntity());
652                                 return resp;
653                         } else {
654                                 Response resp = msoRequest
655                                                 .buildServiceErrorResponse(
656                                                                 bpelStatus,
657                                                                 MsoException.ServiceException,
658                                                                 "Request Failed due to BPEL error with HTTP Status= %1",
659                                                                 ErrorNumbers.SVC_DETAILED_SERVICE_ERROR,
660                                                                 variables);
661                                 msoLogger.error(MessageEnum.APIH_BPEL_RESPONSE_ERROR,
662                                                 requestClient.getUrl(), "", "",
663                                                 MsoLogger.ErrorCode.BusinessProcesssError,
664                                                 "Response from BPEL engine is empty");
665                                 msoLogger.recordAuditEvent(startTime,
666                                                 MsoLogger.StatusCode.ERROR,
667                                                 MsoLogger.ResponseCode.InternalError,
668                                                 "Response from BPEL engine is empty");
669                                 msoLogger.debug(END_OF_THE_TRANSACTION
670                                                 + (String) resp.getEntity());
671                                 return resp;
672                         }
673                 }
674         }
675
676         /**
677          * Getting recipes from catalogDb
678          * 
679          * @param db
680          * @param action
681          * @return
682          */
683         private RecipeLookupResult getServiceInstanceOrchestrationURI(
684                         CatalogDatabase db, Action action) {
685
686                 RecipeLookupResult recipeLookupResult = getServiceURI(db, action);
687
688                 if (recipeLookupResult != null) {
689                         msoLogger.debug("Orchestration URI is: "
690                                         + recipeLookupResult.getOrchestrationURI()
691                                         + ", recipe Timeout is: "
692                                         + Integer.toString(recipeLookupResult.getRecipeTimeout()));
693                 } else {
694                         msoLogger.debug("No matching recipe record found");
695                 }
696                 return recipeLookupResult;
697         }
698
699         /**
700          * Getting recipes from catalogDb
701          * 
702          * @param db
703          * @param action
704          * @return
705          */
706         private RecipeLookupResult getServiceURI(CatalogDatabase db, Action action) {
707
708                 String defaultServiceModelName = "UUI_DEFAULT";
709
710                 Service serviceRecord = db
711                                 .getServiceByModelName(defaultServiceModelName);
712                 ServiceRecipe recipe = db.getServiceRecipeByModelUUID(
713                                 serviceRecord.getModelUUID(), action.name());
714
715                 if (recipe == null) {
716                         return null;
717                 }
718                 return new RecipeLookupResult(recipe.getOrchestrationUri(),
719                                 recipe.getRecipeTimeout());
720
721         }
722
723         /**
724          * Converting E2EServiceInstanceRequest to ServiceInstanceRequest and
725          * passing it to camunda engine.
726          * 
727          * @param e2eSir
728          * @return
729          */
730         private String mapReqJsonToSvcInstReq(E2EServiceInstanceRequest e2eSir,
731                         String requestJSON) {
732
733                 sir = new ServiceInstancesRequest();
734
735                 String returnString = null;
736                 RequestDetails requestDetails = new RequestDetails();
737                 ModelInfo modelInfo = new ModelInfo();
738
739                 // ModelInvariantId
740                 modelInfo.setModelInvariantId(e2eSir.getService().getServiceDefId());
741
742                 // modelNameVersionId
743                 modelInfo.setModelNameVersionId(e2eSir.getService().getTemplateId());
744
745                 // String modelInfoValue =
746                 // e2eSir.getService().getParameters().getNodeTemplateName();
747                 // String[] arrayOfInfo = modelInfoValue.split(":");
748                 // String modelName = arrayOfInfo[0];
749                 // String modelVersion = arrayOfInfo[1];
750
751                 // TODO: To ensure, if we dont get the values from the UUI
752                 String modelName = "voLTE";
753                 String modelVersion = "1.0";
754                 // modelName
755                 modelInfo.setModelName(modelName);
756
757                 // modelVersion
758                 modelInfo.setModelVersion(modelVersion);
759
760                 // modelType
761                 modelInfo.setModelType(ModelType.service);
762
763                 // setting modelInfo to requestDetails
764                 requestDetails.setModelInfo(modelInfo);
765
766                 SubscriberInfo subscriberInfo = new SubscriberInfo();
767
768                 // globalsubscriberId
769                 subscriberInfo.setGlobalSubscriberId(e2eSir.getService()
770                                 .getParameters().getGlobalSubscriberId());
771
772                 // subscriberName
773                 subscriberInfo.setSubscriberName(e2eSir.getService().getParameters()
774                                 .getSubscriberName());
775
776                 // setting subscriberInfo to requestDetails
777                 requestDetails.setSubscriberInfo(subscriberInfo);
778
779                 RequestInfo requestInfo = new RequestInfo();
780
781                 // instanceName
782                 requestInfo.setInstanceName(e2eSir.getService().getName());
783
784                 // source
785                 requestInfo.setSource("UUI");
786
787                 // suppressRollback
788                 requestInfo.setSuppressRollback(true);
789
790                 // setting requestInfo to requestDetails
791                 requestDetails.setRequestInfo(requestInfo);
792
793                 RequestParameters requestParameters = new RequestParameters();
794
795                 // subscriptionServiceType
796                 requestParameters.setSubscriptionServiceType("MOG");
797
798                 // Userparams
799                 List<E2EUserParam> userParams;
800                 // userParams =
801                 // e2eSir.getService().getParameters().getRequestParameters().getUserParams();
802                 List<Map<String, String>> userParamList = new ArrayList<>();
803                 Map<String, String> userParamMap = new HashMap<>();
804                 // complete json request updated in the camunda
805                 userParamMap.put("UUIRequest", requestJSON);
806                 userParamMap.put("ServiceInstanceName", e2eSir.getService().getName());
807
808                 // Map<String, String> userParamMap3 = null;
809                 // for (E2EUserParam userp : userParams) {
810                 // userParamMap.put(userp.getName(), userp.getValue());
811                 //
812                 // }
813                 userParamList.add(userParamMap);
814                 requestParameters.setUserParams(userParamList);
815
816                 // setting requestParameters to requestDetails
817                 requestDetails.setRequestParameters(requestParameters);
818
819                 sir.setRequestDetails(requestDetails);
820
821                 // converting to string
822                 ObjectMapper mapper = new ObjectMapper();
823                 try {
824                         returnString = mapper.writeValueAsString(sir);
825                 } catch (IOException e) {
826                         msoLogger
827                                         .debug("Exception while converting ServiceInstancesRequest object to string",
828                                                         e);
829                 }
830
831                 return returnString;
832         }
833
834         private void createOperationStatusRecordForError(Action action,
835                         String requestId) throws MsoDatabaseException {
836
837                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
838
839                 Session session = null;
840                 try {
841
842                         session = requestsDbSessionFactoryManager.getSessionFactory()
843                                         .openSession();
844                         session.beginTransaction();
845
846                         OperationStatus os = new OperationStatus();
847                         os.setOperation(action.name());
848                         os.setOperationContent("");
849                         os.setOperationId("");
850                         os.setProgress("100");
851                         os.setReason("");
852                         os.setResult("error");
853                         os.setServiceId(requestId);
854                         os.setUserId("");
855                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
856                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
857                         os.setFinishedAt(endTimeStamp);
858                         os.setOperateAt(startTimeStamp);
859
860                         session.save(os);
861                         session.getTransaction().commit();
862
863                 } catch (Exception e) {
864                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
865                                         MsoLogger.ErrorCode.DataError,
866                                         "Exception when creation record request in Operation", e);
867                         throw new MsoDatabaseException(
868                                         "Data did inserted in Operatus Status Table for failure", e);
869                 } finally {
870                         if (null != session) {
871                                 session.close();
872                         }
873                 }
874         }
875
876         private void createOperationStatusRecord(String actionNm, String serviceId,
877                         String operationId) throws MsoDatabaseException {
878
879                 AbstractSessionFactoryManager requestsDbSessionFactoryManager = new RequestsDbSessionFactoryManager();
880
881                 Session session = null;
882                 try {
883
884                         session = requestsDbSessionFactoryManager.getSessionFactory()
885                                         .openSession();
886                         session.beginTransaction();
887
888                         OperationStatus os = new OperationStatus();
889                         os.setOperation(actionNm);
890                         os.setOperationContent("");
891                         os.setOperationId(operationId);
892                         os.setProgress("0");
893                         os.setReason("");
894                         os.setResult("processing");
895                         os.setServiceId(serviceId);
896                         // TODO : to be updated...
897                         os.setUserId("");
898                         Timestamp startTimeStamp = new Timestamp(System.currentTimeMillis());
899                         Timestamp endTimeStamp = new Timestamp(System.currentTimeMillis());
900                         os.setFinishedAt(endTimeStamp);
901                         os.setOperateAt(startTimeStamp);
902
903                         session.save(os);
904                         session.getTransaction().commit();
905
906                 } catch (Exception e) {
907                         msoLogger.error(MessageEnum.APIH_DB_INSERT_EXC, "", "",
908                                         MsoLogger.ErrorCode.DataError,
909                                         "Exception when creation record request in Operation", e);
910                         throw new MsoDatabaseException(
911                                         "Data did inserted in Operatus Status Table", e);
912                 } finally {
913                         if (null != session) {
914                                 session.close();
915                         }
916                 }
917         }
918
919         private OperationStatus chkDuplicateServiceInOperStatus(String serviceId) {
920                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
921                                 .getOperationStatusByServiceId(serviceId);
922
923                 return dupServiceName;
924         }
925
926         private OperationStatus chkDuplicateServiceNameInOperStatus(
927                         String serviceName) {
928                 OperationStatus dupServiceName = (RequestsDatabase.getInstance())
929                                 .getOperationStatusByServiceName(serviceName);
930
931                 return dupServiceName;
932         }
933 }