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