Initial OpenECOMP MSO commit
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / openecomp / mso / apihandlerinfra / NetworkRequestHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * OPENECOMP - MSO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. 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
24 import java.io.StringReader;
25 import java.io.StringWriter;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.UUID;
29
30 import javax.ws.rs.GET;
31 import javax.ws.rs.POST;
32 import javax.ws.rs.Path;
33 import javax.ws.rs.PathParam;
34 import javax.ws.rs.Produces;
35 import javax.ws.rs.QueryParam;
36 import javax.ws.rs.core.Context;
37 import javax.ws.rs.core.MediaType;
38 import javax.ws.rs.core.Response;
39 import javax.ws.rs.core.UriInfo;
40 import javax.xml.bind.JAXBContext;
41 import javax.xml.bind.JAXBException;
42 import javax.xml.bind.Marshaller;
43 import javax.xml.bind.Unmarshaller;
44 import javax.xml.transform.sax.SAXSource;
45
46 import org.apache.http.HttpResponse;
47 import org.apache.http.HttpStatus;
48 import org.xml.sax.InputSource;
49
50 import org.openecomp.mso.apihandler.common.ErrorNumbers;
51 import org.openecomp.mso.apihandler.common.RequestClient;
52 import org.openecomp.mso.apihandler.common.RequestClientFactory;
53 import org.openecomp.mso.apihandler.common.ResponseHandler;
54 import org.openecomp.mso.apihandler.common.ValidationException;
55 import org.openecomp.mso.apihandlerinfra.networkbeans.ActionType;
56 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkInputs;
57 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkOutputs;
58 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkRequest;
59 import org.openecomp.mso.apihandlerinfra.networkbeans.NetworkRequests;
60 import org.openecomp.mso.apihandlerinfra.networkbeans.ObjectFactory;
61 import org.openecomp.mso.apihandlerinfra.networkbeans.RequestInfo;
62 import org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType;
63 import org.openecomp.mso.db.catalog.CatalogDatabase;
64 import org.openecomp.mso.db.catalog.beans.Recipe;
65 import org.openecomp.mso.logger.MessageEnum;
66 import org.openecomp.mso.logger.MsoAlarmLogger;
67 import org.openecomp.mso.logger.MsoLogger;
68 import org.openecomp.mso.properties.MsoJavaProperties;
69 import org.openecomp.mso.properties.MsoPropertiesFactory;
70 import org.openecomp.mso.requestsdb.InfraActiveRequests;
71 import org.openecomp.mso.requestsdb.InfraRequests;
72 import org.openecomp.mso.requestsdb.RequestsDatabase;
73 import org.openecomp.mso.utils.UUIDChecker;
74
75 @Path("/{version: v1|v2|v3}/network-request")
76 public class NetworkRequestHandler {
77
78     @Context
79     private UriInfo uriInfo;
80
81     protected ObjectFactory beansObjectFactory = new ObjectFactory ();
82
83     public final static String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
84
85     private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
86
87     private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
88
89     private static MsoJavaProperties props = MsoPropertiesUtils.loadMsoProperties ();
90
91     private static final String NOT_FOUND = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Application Not Started</title></head><body>Application not started, properties file missing or invalid or Database Connection failed</body></html>";
92
93     private static final Response NOT_STARTED_RESPONSE = Response.status (HttpStatus.SC_SERVICE_UNAVAILABLE)
94             .entity (NOT_FOUND)
95             .build ();
96
97     @GET
98     public Response queryFilters (@QueryParam("network-type") String networkType,
99                                   @QueryParam("service-type") String serviceType,
100                                   @QueryParam("aic-node-clli") String aicNodeClli,
101                                   @QueryParam("tenant-id") String tenantId,
102                                   @PathParam("version") String version) {
103         MsoLogger.setServiceName ("QueryFilters");
104         // Generate a Request Id
105         UUIDChecker.generateUUID(msoLogger);
106         long startTime = System.currentTimeMillis ();
107
108         msoLogger.debug ("Incoming request received for query filters with Network type " + networkType
109                                          + " - service type "
110                                          + serviceType
111                                          + " - aicNodeClli "
112                                          + aicNodeClli
113                                          + " - tenant id "
114                                          + tenantId);
115         Response response = null;
116         if (networkType != null) {
117             response = this.getRequestList ("vnfType", networkType, version);
118         } else {
119             response = queryGenericFilters (serviceType, aicNodeClli, tenantId, version);
120         }
121         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
122         msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
123         return response;
124     }
125
126     @GET
127     @Path(Constants.REQUEST_ID_PATH)
128     public Response getRequest (@PathParam("request-id") String requestId, @PathParam("version") String version) {
129         // Check INFRA_ACTIVE_REQUESTS table to find info
130         // on this request
131         MsoLogger.setServiceName ("GetRequest");
132         // Generate a Request Id
133         UUIDChecker.generateUUID(msoLogger);
134         msoLogger.debug ("Incoming request received for getRequest with requestId=" + requestId + ", version = " + version);
135         long startTime = System.currentTimeMillis ();
136
137         Response response = getRequestGeneric (requestId, version);
138         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
139         msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
140         return response;
141     }
142
143     protected MsoLogger getMsoLogger () {
144         return msoLogger;
145     }
146
147     protected void fillNetworkRequest (NetworkRequest qr, InfraRequests ar, String version) {
148         NetworkInputs vi = beansObjectFactory.createNetworkInputs ();
149
150         if (ar.getVnfId () != null) {
151             vi.setNetworkId (ar.getVnfId ());
152         }
153         if (ar.getVnfName () != null) {
154             vi.setNetworkName (ar.getVnfName ());
155         }
156         if (ar.getVnfType () != null) {
157             vi.setNetworkType (ar.getVnfType ());
158         }
159         if (version.equals(Constants.SCHEMA_VERSION_V1)) {
160                 if (ar.getServiceType () != null) {
161                         vi.setServiceType (ar.getServiceType ());
162                 }
163                 if (ar.getAicNodeClli () != null) {
164                         vi.setAicNodeClli (ar.getAicNodeClli ());
165                 }
166         }
167         else if (version.equals(Constants.SCHEMA_VERSION_V2)) {
168                 if (ar.getAaiServiceId () != null) {
169                         vi.setServiceId (ar.getAaiServiceId ());
170                 }
171                 if (ar.getAicCloudRegion () != null) {
172                         vi.setAicCloudRegion (ar.getAicCloudRegion ());
173                 }
174         }
175         else if (version.equals(Constants.SCHEMA_VERSION_V3)) {
176                 if (ar.getAaiServiceId () != null) {
177                         vi.setServiceId (ar.getAaiServiceId ());
178                 }
179                 if (ar.getAicCloudRegion () != null) {
180                         vi.setAicCloudRegion (ar.getAicCloudRegion ());
181                 }
182                 if (ar.getServiceInstanceId () != null) {
183                         vi.setServiceInstanceId (ar.getServiceInstanceId ());
184                 }
185                                 
186         }
187         
188         if (ar.getTenantId () != null) {
189             vi.setTenantId (ar.getTenantId ());
190         }
191         if (ar.getProvStatus () != null) {
192             vi.setProvStatus (ar.getProvStatus ());
193         }
194         qr.setNetworkInputs (vi);
195
196         qr.setNetworkParams (ar.getVnfParams ());
197
198         try {
199             String networkoutputs = ar.getVnfOutputs ();
200             if (networkoutputs != null && networkoutputs.length () > 0) {
201                 msoLogger.debug ("Read NETWORK outputs: " + networkoutputs);
202                 NetworkOutputs networkOutput = null;
203
204                 // Now unmarshal it into network outputs
205                 try {
206                     JAXBContext jaxbContext = JAXBContext.newInstance (NetworkOutputs.class);
207                     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller ();
208
209                     InputSource inputSource = new InputSource (new StringReader (networkoutputs));
210                     SAXSource source = new SAXSource (inputSource);
211
212                     networkOutput = jaxbUnmarshaller.unmarshal (source, NetworkOutputs.class).getValue ();
213
214                 } catch (Exception e) {
215                     msoLogger.debug ("Validation failed", e);
216                     throw new ValidationException ("format for network outputs");
217                 }
218
219                 qr.setNetworkOutputs (networkOutput);
220             }
221         } catch (Exception e) {
222             msoLogger.debug ("exception reading networkOutputs Clob", e);
223         }
224     }
225
226     protected Response queryGenericFilters (String serviceType, String aicNodeClli, String tenantId, String version) {
227         if (serviceType != null) {
228             return this.getRequestList ("serviceType", serviceType, version);
229         }
230         if (aicNodeClli != null) {
231             return this.getRequestList ("aicNodeClli", aicNodeClli, version);
232         }
233         if (tenantId != null) {
234             return this.getRequestList ("tenantId", tenantId, version);
235         }
236         return Response.status (HttpStatus.SC_BAD_REQUEST).entity ("").build ();
237     }
238
239     protected Response getRequestGeneric (String requestId, String version) {
240         // Check INFRA_ACTIVE_REQUESTS table to find info
241         // on this request
242         MsoLogger.setLogContext (requestId, null);
243         getMsoLogger ().debug ("getRequest: " + requestId);
244
245         String responseString = null;
246
247         InfraActiveRequests activeReq = RequestsDatabase.getRequestFromInfraActive (requestId, "NETWORK");
248         if (activeReq != null) {
249             // build response for active
250             responseString = infraRequestsResponse (activeReq, version);
251             return Response.status (HttpStatus.SC_OK).entity (responseString).build ();
252         } else {
253             // Report that no request has been found
254             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
255         }
256     }
257
258     protected Response getRequestList (String queryAttribute, String queryValue, String version) {
259         // Check INFRA_ACTIVE_REQUESTS table to find info
260         // on this request
261
262         getMsoLogger ().debug ("getRequest based on " + queryAttribute + ": " + queryValue);
263
264         List <InfraActiveRequests> activeReqList = RequestsDatabase.getRequestListFromInfraActive (queryAttribute,
265                                                                                                    queryValue,
266                                                                                                    "NETWORK");
267
268         List <NetworkRequest> queryResponseList = new LinkedList <NetworkRequest> ();
269
270         if (activeReqList != null) {
271             // build response for active
272             queryResponseList = infraRequestsResponses (activeReqList, version);
273
274         }
275
276         if (queryResponseList != null && !queryResponseList.isEmpty ()) {
277             String result = this.translateNetworkRequests (queryResponseList);
278             return Response.status (HttpStatus.SC_OK).entity (result).build ();
279
280         } else {
281             // Report that no request has been found
282             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
283         }
284     }
285
286     private NetworkRequest fillGeneric (InfraRequests ar) {
287         NetworkRequest qr = beansObjectFactory.createNetworkRequest ();
288         RequestInfo ri = beansObjectFactory.createRequestInfo ();
289         ri.setRequestId (ar.getRequestId ());
290         ri.setAction (ActionType.fromValue (ar.getAction ()));
291         ri.setRequestStatus (RequestStatusType.fromValue (ar.getRequestStatus ()));
292         if (ar.getProgress () != null) {
293             ri.setProgress (ar.getProgress ().intValue ());
294         }
295         if (ar.getSource () != null) {
296             ri.setSource (ar.getSource ());
297         }
298
299         ri.setStartTime (ar.getStartTime ().toString ());
300         if (ar.getEndTime () != null) {
301             ri.setEndTime (ar.getEndTime ().toString ());
302         }
303
304         if (ar.getStatusMessage () != null) {
305             ri.setStatusMessage (ar.getStatusMessage ());
306         }
307         qr.setRequestInfo (ri);
308         return qr;
309     }
310
311     private List <NetworkRequest> infraRequestsResponses (List <? extends InfraRequests> arList, String version) {
312         List <NetworkRequest> queryResponseList = new LinkedList <NetworkRequest> ();
313
314         for (InfraRequests ar : arList) {
315             NetworkRequest qr = fillGeneric (ar);
316             fillNetworkRequest (qr, ar, version);
317             queryResponseList.add (qr);
318         }
319         return queryResponseList;
320     }
321
322     private String translateNetworkRequests (List <NetworkRequest> queryResponseList) {
323         NetworkRequests queryResponses = new NetworkRequests ();
324         for (int i = 0; i < queryResponseList.size (); i++) {
325             queryResponses.getNetworkRequest ().add (queryResponseList.get (i));
326         }
327
328         StringWriter stringWriter = new StringWriter ();
329         try {
330             JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequests.class);
331             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
332
333             // output pretty printed
334             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
335
336             jaxbMarshaller.marshal (queryResponses, stringWriter);
337
338         } catch (JAXBException e) {
339             getMsoLogger ().debug ("Marshalling issue", e);
340         }
341
342         return stringWriter.toString ();
343     }
344
345     private String infraRequestsResponse (InfraRequests ar, String version) {
346         NetworkRequest qr = fillGeneric (ar);
347         fillNetworkRequest (qr, ar, version);
348
349         StringWriter stringWriter = new StringWriter ();
350         try {
351             JAXBContext jaxbContext = JAXBContext.newInstance (NetworkRequest.class);
352             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
353
354             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
355             jaxbMarshaller.marshal (qr, stringWriter);
356
357         } catch (JAXBException e) {
358             getMsoLogger ().debug ("Marshalling issue", e);
359         }
360
361         String response = stringWriter.toString ();
362         return response;
363     }
364
365     @POST
366     @Path("/")
367     @Produces(MediaType.APPLICATION_XML)
368     public Response manageNetworkRequest (String reqXML, @PathParam("version") String version) {
369         MsoLogger.setServiceName ("NetworkRequest");
370         if ("v1".equals(version)) {
371             return manageNetworkRequestImpl (reqXML, Constants.SCHEMA_VERSION_V1);
372         } else if ("v2".equals(version)) {
373             return manageNetworkRequestImpl (reqXML, Constants.SCHEMA_VERSION_V2);
374         } else if ("v3".equals(version)) {
375             return manageNetworkRequestImpl (reqXML, Constants.SCHEMA_VERSION_V3);
376         } else {
377             long startTime = System.currentTimeMillis ();
378             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "Version not found");
379                 return Response.status(HttpStatus.SC_NOT_FOUND).build();
380         }
381     }
382
383     private Response manageNetworkRequestImpl (String reqXML, String version) {
384         String methodName = "NetworkRequest";
385
386         props = MsoPropertiesUtils.loadMsoProperties ();
387         
388         long startTime = System.currentTimeMillis ();
389         if (MsoPropertiesUtils.getNoPropertiesState()) {
390             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.ServiceNotAvailable, "Application not started, properties file missing or invalid");
391                 return NOT_STARTED_RESPONSE;
392         }
393         uriInfo.getRequestUri ();
394
395         // Generate unique request id for the new request
396         UUID requestUUID = UUID.randomUUID ();
397
398         NetworkMsoInfraRequest msoRequest = new NetworkMsoInfraRequest (requestUUID.toString ());
399         MsoLogger.setLogContext (msoRequest.getRequestId (), null);
400
401         if (reqXML == null) {
402             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "The input Request is null");
403             return Response.status (HttpStatus.SC_NO_CONTENT).entity ("").build ();
404         }
405
406         String requestUri = uriInfo.getRequestUri ().toString ();
407
408         msoLogger.debug ("Incoming Request: " + reqXML);
409
410         msoRequest.setRequestUri (requestUri);
411         msoLogger.debug ("Schema version: " + version);
412         try {
413             msoRequest.parse (reqXML, version, props);
414         } catch (Exception e) {
415             msoLogger.debug ("Validation failed: ", e);
416             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
417             Response response = msoRequest.buildResponseFailedValidation (HttpStatus.SC_BAD_REQUEST, e.getMessage ());
418             if (msoRequest.getRequestId () != null) {
419                 msoLogger.debug ("Logging failed message to the database");
420                 msoRequest.createRequestRecord (Status.FAILED);
421             }
422             msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR, reqXML, "", "", MsoLogger.ErrorCode.DataError, "Exception when parsing reqXML", e);
423             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, "Validation of the input request failed");
424             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
425             return response;
426         }
427         MsoLogger.setServiceName (MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo().getAction().name());
428         msoLogger.debug ("Update serviceName with detailed action info to:" + MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo().getAction().name());
429         if (msoRequest.getRequestInfo ()
430                       .getAction () == org.openecomp.mso.apihandlerinfra.networkbeans.ActionType.CREATE) {
431             // Check if this request is a duplicate of the one with the same network Name
432             msoLogger.debug ("Checking for a duplicate with the same network-name");
433             InfraActiveRequests dup = null;
434             try {
435
436                 dup = RequestsDatabase.checkDuplicateByVnfName (msoRequest.getNetworkInputs ().getNetworkName (),
437                                                                 msoRequest.getRequestInfo ().getAction ().value (),
438                                                                 "NETWORK");
439
440             } catch (Exception e) {
441                 msoLogger.debug ("Exception", e);
442                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
443                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
444                                                                        ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB,
445                                                                        null,
446                                                                        e.getMessage ());
447                 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
448                                        MsoAlarmLogger.CRITICAL,
449                                        Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
450                 msoRequest.createRequestRecord (Status.FAILED);
451                 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC_ATT, "network-name", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for duplicated request", e);
452                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for duplicated request");
453                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
454                 return response;
455             }
456             if (dup != null) {
457                 // Found the duplicate record. Return the appropriate error.
458                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
459                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
460                                                               ErrorNumbers.LOCKED_CREATE_ON_THE_SAME_VNF_NAME_IN_PROGRESS,
461                                                               dup);
462                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND,
463                                 "CREATE on the same Network Name is already progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicates request - CREATE on the same Network Name is already progress");
464                 msoRequest.createRequestRecord (Status.FAILED);
465                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicates request - CREATE on the same Network Name is already progress");
466                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
467                 return response;
468             }
469         } else {
470             // Check if this request is a duplicate of the one with the same networkId
471             InfraActiveRequests dup = null;
472             msoLogger.debug ("Checking for a duplicate with the same network-id");
473             try {
474                 dup = RequestsDatabase.checkDuplicateByVnfId (msoRequest.getNetworkInputs ().getNetworkId (),
475                                                               msoRequest.getRequestInfo ().getAction ().value (),
476                                                               "NETWORK");
477
478             } catch (Exception e) {
479                 msoLogger.debug ("Exception", e);
480                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
481                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
482                                                                        ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB,
483                                                                        null,
484                                                                        e.getMessage ());
485                 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
486                                        MsoAlarmLogger.CRITICAL,
487                                        Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
488                 msoRequest.createRequestRecord (Status.FAILED);
489                 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC_ATT, "network-id", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for a duplicate request with the same network-id", e);
490                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for a duplicate request with the same network-id");
491                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
492                 return response;
493             }
494             if (dup != null) {
495                 // Found the duplicate record. Return the appropriate error.
496                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
497                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
498                                                               ErrorNumbers.LOCKED_SAME_ACTION_AND_VNF_ID,
499                                                               dup);
500                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND,
501                                 msoRequest.getRequestInfo ().getAction ().value ()
502                                                                   + " on the same Network Id already in progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicated request on the same Network Id already in progress");
503
504                 msoRequest.createRequestRecord (Status.FAILED);
505                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicated request on the same Network Id already in progress.");
506                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
507                 return response;
508             }
509         }
510
511         String orchestrationURI = "";
512
513         // Query MSO Catalog DB
514         try (CatalogDatabase db = new CatalogDatabase()) {
515
516             Recipe recipe = null;
517
518             if (msoRequest.getServiceType () != null
519                     && msoRequest.getServiceType ().length () > 0) {
520                 recipe = db.getNetworkRecipe (msoRequest.getNetworkInputs ().getNetworkType (),
521                         msoRequest.getRequestInfo ().getAction ().value (),
522                         msoRequest.getServiceType ());
523
524             }
525             if (recipe == null) {
526                 recipe = db.getNetworkRecipe (msoRequest.getNetworkInputs ().getNetworkType (),
527                         msoRequest.getRequestInfo ().getAction ().value (),
528                         null);
529             }
530
531             if (recipe == null) {
532                 msoLogger.error (MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, "VNF Recipe", "", "", MsoLogger.ErrorCode.DataError, "VNF Recipe attribute not found");
533                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
534                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
535                         ErrorNumbers.RECIPE_DOES_NOT_EXIST,
536                         null,
537                         "");
538                 msoRequest.createRequestRecord (Status.FAILED);
539                 db.close ();
540                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "No recipe found in DB");
541                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
542                 return response;
543             }
544             orchestrationURI = recipe.getOrchestrationUri ();
545             msoLogger.debug ("Orchestration URI is: " + orchestrationURI);
546
547             db.close ();
548
549             String requestId = msoRequest.getRequestId ();
550             msoLogger.debug ("requestId is: " + requestId);
551             msoLogger.debug ("About to insert a record");
552
553             try {
554                 msoRequest.createRequestRecord (Status.PENDING);
555             } catch (Exception e) {
556                 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "", MsoLogger.ErrorCode.DataError, "Exception while creating record in DB", e);
557                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
558                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
559                         ErrorNumbers.COULD_NOT_WRITE_TO_REQUESTS_DB,
560                         null,
561                         "non-unique request-id specified");
562                 // Cannot create a record of this request here, our communication with MSO DB just failed. Do not try
563                 // to create a failed record
564                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while creating record in DB");
565                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
566                 return response;
567             }
568
569             RequestClient requestClient = null;
570             HttpResponse response = null;
571             long subStartTime = System.currentTimeMillis();
572             try {
573                 requestClient = RequestClientFactory.getRequestClient (orchestrationURI, props);
574                 // Capture audit event
575                 msoLogger.debug ("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl ());
576                 response = requestClient.post (msoRequest.getRequestXML (),
577                         requestId,
578                         Integer.toString (recipe.getRecipeTimeout ()).toString (),
579                         version,
580                         null,
581                         null);
582                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from BPMN engine", "BPMN", orchestrationURI, null);
583             } catch (Exception e) {
584                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN", orchestrationURI, null);
585                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
586                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
587                         ErrorNumbers.NO_COMMUNICATION_TO_BPEL,
588                         null,
589                         e.getMessage ());
590                 alarmLogger.sendAlarm ("MsoConfigurationError",
591                         MsoAlarmLogger.CRITICAL,
592                         Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
593                 msoRequest.updateFinalStatus (Status.FAILED);
594                 msoLogger.error (MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
595                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine");
596                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
597                 return resp;
598             }
599
600             if (response == null) {
601                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
602                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
603                         ErrorNumbers.NO_RESPONSE_FROM_BPEL,
604                         null,
605                         "bpelResponse is null");
606                 msoRequest.updateFinalStatus (Status.FAILED);
607                 msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Null response from BPEL", "Camunda", "", MsoLogger.ErrorCode.DataError, "bpelResponse is null");
608                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is null");
609                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
610                 return resp;
611             }
612
613             ResponseHandler respHandler = new ResponseHandler (response, requestClient.getType ());
614             int bpelStatus = respHandler.getStatus ();
615
616             // BPEL accepted the request, the request is in progress
617             if (bpelStatus == HttpStatus.SC_ACCEPTED) {
618                 String bpelXMLResponseBody = respHandler.getResponseBody ();
619                 msoLogger.debug ("Received from BPEL: " + bpelXMLResponseBody);
620                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.IN_PROGRESS);
621                 RequestsDatabase.updateInfraStatus (msoRequest.getRequestId (),
622                         Status.IN_PROGRESS.toString (),
623                         Constants.PROGRESS_REQUEST_IN_PROGRESS,
624                         Constants.MODIFIED_BY_APIHANDLER);
625                 Response resp = msoRequest.buildResponse (bpelStatus, null, null);
626                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "BPMN accepted the request, the request is in progress");
627                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
628                 return resp;
629             } else {
630
631                 String bpelXMLResponseBody = respHandler.getResponseBody ();
632                 if (bpelXMLResponseBody != null && !bpelXMLResponseBody.isEmpty ()) {
633                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
634                     Response resp = msoRequest.buildResponse (bpelStatus, bpelXMLResponseBody, null);
635                     msoRequest.updateFinalStatus (Status.FAILED);
636                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR,
637                             "Response from BPEL engine is failed with HTTP Status=" + bpelStatus, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
638                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is with status Failed");
639                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
640                     return resp;
641                 } else {
642                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
643                     Response resp = msoRequest.buildResponse (bpelStatus, ErrorNumbers.ERROR_FROM_BPEL, null);
644                     msoRequest.updateFinalStatus (Status.FAILED);
645                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Response from BPEL engine is empty", "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is empty");
646                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPEL engine is empty");
647                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
648                     return resp;
649                 }
650             }
651         } catch (Exception e) {
652             msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception while communciate with Catalog DB", e);
653             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.networkbeans.RequestStatusType.FAILED);
654             Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
655                                                                    ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB,
656                                                                    null,
657                                                                    e.getMessage ());
658             alarmLogger.sendAlarm ("MsoDatabaseAccessError",
659                                    MsoAlarmLogger.CRITICAL,
660                                    Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
661             msoRequest.createRequestRecord (Status.FAILED);
662             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while communciate with DB");
663             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
664             return response;
665         }
666     }
667 }