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