Initial OpenECOMP MSO commit
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / openecomp / mso / apihandlerinfra / VnfRequestHandler.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
44 import org.apache.http.HttpResponse;
45 import org.apache.http.HttpStatus;
46
47 import javax.xml.bind.Unmarshaller;
48 import javax.xml.transform.sax.SAXSource;
49
50 import org.xml.sax.InputSource;
51
52 import org.openecomp.mso.apihandler.common.ErrorNumbers;
53 import org.openecomp.mso.apihandler.common.RequestClient;
54 import org.openecomp.mso.apihandler.common.RequestClientFactory;
55 import org.openecomp.mso.apihandler.common.ResponseHandler;
56 import org.openecomp.mso.apihandler.common.ValidationException;
57 import org.openecomp.mso.apihandlerinfra.vnfbeans.ActionType;
58 import org.openecomp.mso.apihandlerinfra.vnfbeans.ObjectFactory;
59 import org.openecomp.mso.apihandlerinfra.vnfbeans.RequestInfo;
60 import org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType;
61 import org.openecomp.mso.apihandlerinfra.vnfbeans.VnfInputs;
62 import org.openecomp.mso.apihandlerinfra.vnfbeans.VnfOutputs;
63 import org.openecomp.mso.apihandlerinfra.vnfbeans.VnfRequest;
64 import org.openecomp.mso.apihandlerinfra.vnfbeans.VnfRequests;
65 import org.openecomp.mso.db.catalog.CatalogDatabase;
66 import org.openecomp.mso.db.catalog.beans.Recipe;
67 import org.openecomp.mso.db.catalog.beans.VfModule;
68 import org.openecomp.mso.db.catalog.beans.VnfResource;
69 import org.openecomp.mso.logger.MessageEnum;
70 import org.openecomp.mso.logger.MsoAlarmLogger;
71 import org.openecomp.mso.logger.MsoLogger;
72 import org.openecomp.mso.properties.MsoJavaProperties;
73 import org.openecomp.mso.properties.MsoPropertiesFactory;
74 import org.openecomp.mso.requestsdb.InfraRequests;
75 import org.openecomp.mso.requestsdb.InfraActiveRequests;
76 import org.openecomp.mso.requestsdb.RequestsDatabase;
77 import org.openecomp.mso.utils.UUIDChecker;
78
79 @Path("/{version: v1|v2|v3}/vnf-request")
80 public class VnfRequestHandler {
81
82     @Context
83     private UriInfo uriInfo;
84
85     protected ObjectFactory beansObjectFactory = new ObjectFactory ();
86
87     public final static String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
88
89     private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
90
91     private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
92
93     private static MsoJavaProperties props = MsoPropertiesUtils.loadMsoProperties ();
94
95     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>";
96
97     private static final Response NOT_STARTED_RESPONSE = Response.status (HttpStatus.SC_SERVICE_UNAVAILABLE)
98             .entity (NOT_FOUND)
99             .build ();
100
101     @GET
102     public Response queryFilters (@QueryParam("vnf-type") String vnfType,
103                                   @QueryParam("service-type") String serviceType,
104                                   @QueryParam("aic-node-clli") String aicNodeClli,
105                                   @QueryParam("tenant-id") String tenantId,
106                                   @QueryParam("volume-group-id") String volumeGroupId,
107                                   @QueryParam("volume-group-name") String volumeGroupName,
108                                   @QueryParam("vnf-name") String vnfName,
109                                   @PathParam("version") String version) {
110         long startTime = System.currentTimeMillis ();
111         MsoLogger.setServiceName ("VNFQueryFilters");
112         // Generate a Request Id
113         UUIDChecker.generateUUID(msoLogger);
114         msoLogger.debug ("Incoming request received for queryFilter with vnf-type:" + vnfType
115                                                                 + " service-type:" + serviceType
116                                                                 + " aic-node-clli:" + aicNodeClli
117                                                                 + " tenant-id:" + tenantId
118                                                                 + " volume-group-id:" + volumeGroupId
119                                                                 + " volume-group-name:" + volumeGroupName
120                                                                 + " vnf-name: " + vnfName);
121         Response response = null;
122         if (vnfType != null) {
123             response = this.getRequestList ("vnfType", vnfType, version);
124         } else {
125             response = queryGenericFilters (serviceType, aicNodeClli, tenantId, volumeGroupId, volumeGroupName, vnfName, version);
126         }
127         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
128         msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
129         return response;
130     }
131
132     @GET
133     @Path(Constants.REQUEST_ID_PATH)
134     public Response getRequest (@PathParam("request-id") String requestId, @PathParam("version") String version) {
135         // Check INFRA_ACTIVE_REQUESTS table to find info
136         // on this request
137         long startTime = System.currentTimeMillis ();
138         MsoLogger.setServiceName ("VNFGetRequest");
139         // Generate a Request Id
140         UUIDChecker.generateUUID(msoLogger);
141         msoLogger.debug ("Incoming request received for getRequest with request-id:" + requestId + ", version = " + version);
142
143         Response response = getRequestGeneric (requestId, version);
144         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
145         msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
146         return response;
147     }
148
149     protected MsoLogger getMsoLogger () {
150         return msoLogger;
151     }
152
153     protected String getRequestType () {
154         return VnfRequestType.VNF.toString ();
155     }
156
157     protected void fillVnfRequest (VnfRequest qr, InfraRequests ar, String version) {
158         VnfInputs vi = beansObjectFactory.createVnfInputs ();
159
160         if (ar.getVnfId () != null) {
161             vi.setVnfId (ar.getVnfId ());
162         }
163         if (ar.getVnfName () != null) {
164             vi.setVnfName (ar.getVnfName ());
165         }
166         if (ar.getVnfType () != null) {
167             vi.setVnfType (ar.getVnfType ());
168         }        
169         if (ar.getTenantId () != null) {
170             vi.setTenantId (ar.getTenantId ());
171         }
172         if (ar.getProvStatus () != null) {
173             vi.setProvStatus (ar.getProvStatus ());
174         }
175         if (ar.getVolumeGroupName () != null) {
176                 vi.setVolumeGroupName (ar.getVolumeGroupName ());
177         }
178         if (ar.getVolumeGroupId () != null) {
179                 vi.setVolumeGroupId (ar.getVolumeGroupId ());
180         }
181         if (version.equals(Constants.SCHEMA_VERSION_V1)) {
182                 if (ar.getServiceType () != null) {
183                         vi.setServiceType (ar.getServiceType ());
184                 }
185                 if (ar.getAicNodeClli () != null) {
186                         vi.setAicNodeClli (ar.getAicNodeClli ());
187                 }
188         }
189         else if (version.equals(Constants.SCHEMA_VERSION_V2)) {
190                 if (ar.getAaiServiceId () != null) {
191                         vi.setServiceId (ar.getAaiServiceId ());
192                 }
193                 if (ar.getAicCloudRegion () != null) {
194                         vi.setAicCloudRegion (ar.getAicCloudRegion ());
195                 }
196                 if (ar.getVfModuleName () != null) {
197                         vi.setVfModuleName (ar.getVfModuleName ());
198                 }
199                 if (ar.getVfModuleId () != null) {
200                         vi.setVfModuleId (ar.getVfModuleId ());
201                 }
202                 if (ar.getVfModuleModelName () != null) {
203                         vi.setVfModuleModelName (ar.getVfModuleModelName ());
204                 }               
205         }
206         else if (version.equals(Constants.SCHEMA_VERSION_V3)) {
207                 if (ar.getAaiServiceId () != null) {
208                         vi.setServiceId (ar.getAaiServiceId ());
209                 }
210                 if (ar.getAicCloudRegion () != null) {
211                         vi.setAicCloudRegion (ar.getAicCloudRegion ());
212                 }
213                 if (ar.getVfModuleName () != null) {
214                         vi.setVfModuleName (ar.getVfModuleName ());
215                 }
216                 if (ar.getVfModuleId () != null) {
217                         vi.setVfModuleId (ar.getVfModuleId ());
218                 }
219                 if (ar.getVfModuleModelName () != null) {
220                         vi.setVfModuleModelName (ar.getVfModuleModelName ());
221                 }
222                 if (ar.getServiceInstanceId () != null) {
223                         vi.setServiceInstanceId (ar.getServiceInstanceId ());
224                 }
225         }
226         qr.setVnfInputs (vi);
227
228         qr.setVnfParams (ar.getVnfParams ());
229
230         try {
231             String vnfoutputs = ar.getVnfOutputs ();
232             if (vnfoutputs != null && vnfoutputs.length () > 0) {
233                 msoLogger.debug ("Read VNF outputs: " + vnfoutputs);
234                 VnfOutputs vnfOutput = null;
235
236                 // Now unmarshal it into vnf outputs
237                 try {
238                     JAXBContext jaxbContext = JAXBContext.newInstance (VnfOutputs.class);
239                     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller ();
240
241                     InputSource inputSource = new InputSource (new StringReader (vnfoutputs));
242                     SAXSource source = new SAXSource (inputSource);
243
244                     vnfOutput = jaxbUnmarshaller.unmarshal (source, VnfOutputs.class).getValue ();
245
246                 } catch (Exception e) {
247                     msoLogger.debug ("Validation failed", e);
248                     throw new ValidationException ("format for vnf outputs");
249                 }
250
251                 qr.setVnfOutputs (vnfOutput);
252             }
253         } catch (Exception e) {
254             msoLogger.debug ("exception reading vnfOutputs Clob", e);
255         }
256     }
257
258     protected Response queryGenericFilters (String serviceType, String aicNodeClli, String tenantId, String volumeGroupId, String volumeGroupName, String vnfName, String version) {
259         if (serviceType != null) {
260             return this.getRequestList ("serviceType", serviceType, version);
261         }
262         if (aicNodeClli != null) {
263             return this.getRequestList ("aicNodeClli", aicNodeClli, version);
264         }
265         if (tenantId != null) {
266             return this.getRequestList ("tenantId", tenantId, version);
267         }
268         if (volumeGroupId != null) {
269                 return this.getRequestList ("volumeGroupId", volumeGroupId, version);
270         }
271         if (volumeGroupName != null) {
272                 return this.getRequestList ("volumeGroupName", volumeGroupName, version);
273         }
274         if (vnfName != null) {
275                 return this.getRequestList ("vnfName", vnfName, version);
276         }
277         return Response.status (HttpStatus.SC_BAD_REQUEST).entity ("").build ();
278     }
279
280     protected Response getRequestGeneric (String requestId, String version) {
281         // Check INFRA_ACTIVE_REQUESTS table to find info
282         // on this request
283
284         getMsoLogger ().debug ("getRequest: " + requestId);
285
286         String responseString = null;
287
288         InfraActiveRequests activeReq = RequestsDatabase.getRequestFromInfraActive (requestId, getRequestType ());
289         if (activeReq != null) {
290             // build response for active
291             responseString = infraRequestsResponse (activeReq, version);
292             return Response.status (HttpStatus.SC_OK).entity (responseString).build ();
293         } else {
294             // Report that no request has been found
295             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
296         }
297     }
298
299     protected Response getRequestList (String queryAttribute, String queryValue, String version) {
300         // Check INFRA_ACTIVE_REQUESTS table to find info
301         // on this request
302
303         getMsoLogger ().debug ("getRequest based on " + queryAttribute + ": " + queryValue);
304
305         List <InfraActiveRequests> activeReqList = RequestsDatabase.getRequestListFromInfraActive (queryAttribute,
306                                                                                                    queryValue,
307                                                                                                    getRequestType ());
308
309         List <VnfRequest> queryResponseList = new LinkedList <VnfRequest> ();
310
311         if (activeReqList != null) {
312             // build response for active
313             queryResponseList = infraRequestsResponses (activeReqList, version);
314
315         }
316
317         if (queryResponseList != null && !queryResponseList.isEmpty ()) {
318             String result = this.translateVnfRequests (queryResponseList);
319             return Response.status (HttpStatus.SC_OK).entity (result).build ();
320
321         } else {
322             // Report that no request has been found
323             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
324         }
325     }
326
327     private VnfRequest fillGeneric (InfraRequests ar) {
328         VnfRequest qr = beansObjectFactory.createVnfRequest ();
329         RequestInfo ri = beansObjectFactory.createRequestInfo ();
330         ri.setRequestId (ar.getRequestId ());
331         ri.setAction (ActionType.fromValue (ar.getAction ()));
332         ri.setRequestStatus (RequestStatusType.fromValue (ar.getRequestStatus ()));
333         if (ar.getProgress () != null) {
334             ri.setProgress (ar.getProgress ().intValue ());
335         }
336         if (ar.getSource () != null) {
337             ri.setSource (ar.getSource ());
338         }
339
340         ri.setStartTime (ar.getStartTime ().toString ());
341         if (ar.getEndTime () != null) {
342             ri.setEndTime (ar.getEndTime ().toString ());
343         }
344
345         if (ar.getStatusMessage () != null) {
346             ri.setStatusMessage (ar.getStatusMessage ());
347         }
348         qr.setRequestInfo (ri);
349         return qr;
350     }
351
352     private List <VnfRequest> infraRequestsResponses (List <? extends InfraRequests> arList, String version) {
353         List <VnfRequest> queryResponseList = new LinkedList <VnfRequest> ();
354
355         for (InfraRequests ar : arList) {
356             VnfRequest qr = fillGeneric (ar);
357             fillVnfRequest (qr, ar, version);
358             queryResponseList.add (qr);
359         }
360         return queryResponseList;
361     }
362
363     private String translateVnfRequests (List <VnfRequest> queryResponseList) {
364         VnfRequests queryResponses = new VnfRequests ();
365         for (int i = 0; i < queryResponseList.size (); i++) {
366             queryResponses.getVnfRequest ().add (queryResponseList.get (i));
367         }
368
369         StringWriter stringWriter = new StringWriter ();
370         try {
371             JAXBContext jaxbContext = JAXBContext.newInstance (VnfRequests.class);
372             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
373
374             // output pretty printed
375             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
376
377             jaxbMarshaller.marshal (queryResponses, stringWriter);
378
379         } catch (JAXBException e) {
380             getMsoLogger ().debug ("Marshalling issue", e);
381         }
382
383         return stringWriter.toString ();
384     }
385
386     private String infraRequestsResponse (InfraRequests ar, String version) {
387         VnfRequest qr = fillGeneric (ar);
388         fillVnfRequest (qr, ar, version);
389
390         StringWriter stringWriter = new StringWriter ();
391         try {
392             JAXBContext jaxbContext = JAXBContext.newInstance (VnfRequest.class);
393             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
394
395             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
396             jaxbMarshaller.marshal (qr, stringWriter);
397
398         } catch (JAXBException e) {
399             getMsoLogger ().debug ("Marshalling issue", e);
400         }
401
402         String response = stringWriter.toString ();
403         return response;
404     }
405
406     @POST
407     @Path("/")
408     @Produces(MediaType.APPLICATION_XML)
409     public Response manageVnfRequest (String reqXML, @PathParam("version") String version) {
410         MsoLogger.setServiceName ("VnfRequest");
411         if ("v1".equals(version)) {
412             return manageVnfRequestImpl (reqXML, Constants.SCHEMA_VERSION_V1);
413         } else if ("v2".equals(version)) {
414             return manageVnfRequestImpl (reqXML, Constants.SCHEMA_VERSION_V2);
415         } else if ("v3".equals(version)) {
416             return manageVnfRequestImpl (reqXML, Constants.SCHEMA_VERSION_V3);
417         } else {
418             long startTime = System.currentTimeMillis ();
419             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "Version not found");
420                 return Response.status(HttpStatus.SC_NOT_FOUND).build();
421         }
422     }
423     
424     private Response manageVnfRequestImpl (String reqXML, String version) {
425         String methodName = "VnfRequest";
426         props = MsoPropertiesUtils.loadMsoProperties ();
427         long startTime = System.currentTimeMillis ();
428
429         // Generate unique request id for the new request
430         UUID requestUUID = UUID.randomUUID ();
431
432         VnfMsoInfraRequest msoRequest = new VnfMsoInfraRequest (requestUUID.toString ());
433         MsoLogger.setLogContext (msoRequest.getRequestId (), null);
434
435         if (MsoPropertiesUtils.getNoPropertiesState()) {
436             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.ServiceNotAvailable, "Exiting the transaction: Infra API Handler not started, properties file missing or invalid");
437             return NOT_STARTED_RESPONSE;
438         }
439
440         uriInfo.getRequestUri ();
441
442         if (reqXML == null) {
443             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "The content of the request is null");
444             return Response.status (HttpStatus.SC_NO_CONTENT).entity ("").build ();
445         }
446
447         String requestUri = uriInfo.getRequestUri ().toString ();
448         msoLogger.debug ("Incoming request received for pose VNFRequest:" + reqXML);
449
450         msoRequest.setRequestUri (requestUri);
451         msoLogger.debug ("Schema version: " + version);
452         try {
453             msoRequest.parse (reqXML, version, props);
454         } catch (Exception e) {
455             msoLogger.debug ("Validation failed: ", e);
456             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
457             Response response = msoRequest.buildResponseFailedValidation (HttpStatus.SC_BAD_REQUEST, e.getMessage ());
458             if (msoRequest.getRequestId () != null) {
459                 msoLogger.debug ("Logging failed message to the database");
460                 msoRequest.createRequestRecord (Status.FAILED);
461             }
462             msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR, reqXML, "", "", MsoLogger.ErrorCode.SchemaError, "Exception when parsing reqXML", e);
463             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, "Validation of the input request failed");
464             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
465             return response;
466         }
467         MsoLogger.setServiceName (MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo().getAction().name());
468         msoLogger.debug ("Update serviceName with detailed action info to:" + MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo().getAction().name());
469         if (msoRequest.getRequestInfo ().getAction () == org.openecomp.mso.apihandlerinfra.vnfbeans.ActionType.CREATE) {
470             // Check if this request is a duplicate of the one with the same vnfName
471             msoLogger.debug ("Checking for a duplicate with the same vnf-name");
472             InfraActiveRequests dup = null;
473             try {
474                 dup = RequestsDatabase.checkDuplicateByVnfName (msoRequest.getVnfInputs ().getVnfName (),
475                                                                 msoRequest.getRequestInfo ().getAction ().value (),
476                                                                 "VNF");
477
478             } catch (Exception e) {
479                 msoLogger.debug ("Exception", e);
480                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.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, "vnf-name", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for duplicated request", e);
490                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for duplicated request");
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.vnfbeans.RequestStatusType.FAILED);
497                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
498                                                               ErrorNumbers.LOCKED_CREATE_ON_THE_SAME_VNF_NAME_IN_PROGRESS,
499                                                               dup);
500                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND, "CREATE on the same VNF Name is already progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicates request - CREATE on the same VNF Name is already progress");
501                 msoRequest.createRequestRecord (Status.FAILED);
502                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicates request - CREATE on the same VNF Name is already progress");
503                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
504                 return response;
505             }
506         } else {
507             // Check if this request is a duplicate of the one with the same vnfId
508             InfraActiveRequests dup = null;
509             msoLogger.debug ("Checking for a duplicate with the same vnf-id");
510             try {
511                 dup = RequestsDatabase.checkDuplicateByVnfId (msoRequest.getVnfInputs ().getVnfId (),
512                                                               msoRequest.getRequestInfo ().getAction ().value (),
513                                                               "VNF");
514
515             } catch (Exception e) {
516                 msoLogger.debug ("Exception", e);
517                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
518                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
519                                                                        ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB,
520                                                                        null,
521                                                                        e.getMessage ());
522                 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
523                                        MsoAlarmLogger.CRITICAL,
524                                        Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
525                 msoRequest.createRequestRecord (Status.FAILED);
526                 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC_ATT, "vnf-id", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for a duplicate request with the same vnf-id", e);
527                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for a duplicate request with the same vnf-id");
528                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
529                 return response;
530             }
531             if (dup != null) {
532                 // Found the duplicate record. Return the appropriate error.
533                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
534                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
535                                                               ErrorNumbers.LOCKED_SAME_ACTION_AND_VNF_ID,
536                                                               dup);
537                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND,
538                                 msoRequest.getRequestInfo ().getAction ().value ()
539                                                                   + " on the same VNF Id already in progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicated request on the same VNF Id already in progress");
540
541                 msoRequest.createRequestRecord (Status.FAILED);
542                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicated request on the same VNF Id already in progress");
543                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
544                 return response;
545             }
546         }
547
548         String orchestrationURI = "";
549
550         // Query MSO Catalog DB
551         try (CatalogDatabase db = new CatalogDatabase()){
552
553             Recipe recipe = null;
554
555             if (version.equals(Constants.SCHEMA_VERSION_V1)) {
556                 // First get recipe for the service type given
557                 if (msoRequest.getServiceType () != null
558                         && msoRequest.getServiceType ().length () > 0) {
559                     recipe = db.getVnfRecipe (msoRequest.getVnfInputs ().getVnfType (),
560                             msoRequest.getRequestInfo ().getAction ().value (),
561                             msoRequest.getServiceType ());
562                 }
563                 // If no recipe for the service type or no service type was given, look for recipe without service type
564                 if (recipe == null) {
565                     recipe = db.getVnfRecipe (msoRequest.getVnfInputs ().getVnfType (),
566                             msoRequest.getRequestInfo ().getAction ().value (),
567                             null);
568                 }
569             }
570             if (version.equals (Constants.SCHEMA_VERSION_V2) || version.equals (Constants.SCHEMA_VERSION_V3)) {
571                 switch (msoRequest.getRequestInfo ().getAction ()) {
572                     case CREATE:
573                     case UPDATE:
574                     case DELETE:
575                         // First get recipe for the vnf type given
576                         recipe = db.getVnfRecipe (msoRequest.getVnfInputs ().getVnfType (),
577                                 msoRequest.getRequestInfo ().getAction ().value ());
578
579                         // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
580                         if (recipe == null) {
581                             recipe = db.getVnfRecipe (Constants.VNF_TYPE_WILDCARD,
582                                     msoRequest.getRequestInfo ().getAction ().value ());
583                         }
584                         break;
585                     case CREATE_VF_MODULE:
586                     case UPDATE_VF_MODULE:
587                     case DELETE_VF_MODULE:
588                         // First get recipe for the vnf type/vf module model name through vf module id query
589                         recipe = db.getVfModuleRecipe (msoRequest.getVnfInputs ().getVnfType (), msoRequest.getVnfInputs ().getVfModuleModelName (),
590                                 msoRequest.getRequestInfo ().getAction ().value ());
591
592                         // If no recipe is found, look for generic recipe with "*" vnf type
593                         if (recipe == null) {
594                             recipe = db.getVnfRecipeByVfModuleId (msoRequest.getVnfInputs ().getVfModuleId (),
595                                     Constants.VNF_TYPE_WILDCARD, msoRequest.getRequestInfo ().getAction ().value ());
596                         }
597                         // First get recipe for the vnf type given
598                         //recipe = db.getVnfRecipe (msoRequest.getVnfInputs ().getVnfType (),
599                         //      msoRequest.getRequestInfo ().getAction ().value ());
600
601                         // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
602                         //if (recipe == null) {
603                         //      recipe = db.getVnfRecipe (Constants.VNF_TYPE_WILDCARD,
604                         //                      msoRequest.getRequestInfo ().getAction ().value ());
605                         //
606                         //}
607                         break;
608                     default:
609                         break;
610                 }
611
612             }
613
614             if (recipe == null) {
615                 msoLogger.error (MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, "VNF Recipe", "", "", MsoLogger.ErrorCode.DataError, "No recipe found in DB");
616                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
617                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
618                         ErrorNumbers.RECIPE_DOES_NOT_EXIST,
619                         null,
620                         "");
621                 msoRequest.createRequestRecord (Status.FAILED);
622                 db.close ();
623                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "No recipe found in DB");
624                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
625                 return response;
626             }
627             orchestrationURI = recipe.getOrchestrationUri ();
628             msoLogger.debug ("Orchestration URI is: " + orchestrationURI);
629
630             // Retrieve additional info for Vf Modules from Catalog DB to send it to BPMN
631             switch (msoRequest.getRequestInfo ().getAction ()) {
632                 case CREATE_VF_MODULE:
633                 case UPDATE_VF_MODULE:
634                     String personaModelId = "";
635                     String personaModelVersion = "";
636                     String vnfPersonaModelId = "";
637                     String vnfPersonaModelVersion = "";
638                     Boolean isBase = false;
639                     String asdcServiceModelVersion = msoRequest.getVnfInputs ().getAsdcServiceModelVersion ();
640
641                     // Get VF Module-specific persona info and base module indicator
642                     VfModule vfm = null;
643                     String vfModuleType = msoRequest.getVnfInputs ().getVnfType () + "::" + msoRequest.getVnfInputs ().getVfModuleModelName ();
644                     if (asdcServiceModelVersion != null && !asdcServiceModelVersion.isEmpty ()) {
645                         vfm = db.getVfModuleType (vfModuleType, asdcServiceModelVersion);
646                     }
647                     else {
648                         vfm = db.getVfModuleType (vfModuleType);
649                     }
650                     if (vfm != null) {
651                         if (vfm.getIsBase() == 1) {
652                             isBase = true;
653                         }
654                         personaModelId = vfm.getModelInvariantUuid();
655                         personaModelVersion = vfm.getModelVersion();
656                         msoLogger.debug("Setting personaModelId to " + personaModelId +
657                                 ", personaModelVersion to " + personaModelVersion);
658                     }
659                     // Get VNF-specific persona info
660                     VnfResource vnfr = null;
661                     if (asdcServiceModelVersion != null && !asdcServiceModelVersion.isEmpty ()) {
662                         vnfr = db.getVnfResource (msoRequest.getVnfInputs ().getVnfType (), asdcServiceModelVersion);
663                     }
664                     else {
665                         vnfr = db.getVnfResource (msoRequest.getVnfInputs ().getVnfType ());
666                     }
667                     if (vnfr != null) {
668                         vnfPersonaModelId = vnfr.getModelInvariantUuid ();
669                         vnfPersonaModelVersion = vnfr.getModelVersion();
670                         msoLogger.debug("Setting vnfPersonaModelId to " + vnfPersonaModelId +
671                                 ", vnfPersonaModelVersion to " + vnfPersonaModelVersion);
672                     }
673
674                     msoRequest.addBPMNSpecificInputs(personaModelId, personaModelVersion, isBase,
675                             vnfPersonaModelId, vnfPersonaModelVersion);
676
677                     break;
678                 default:
679                     break;
680             }
681
682             db.close ();
683
684             String requestId = msoRequest.getRequestId ();
685             msoLogger.debug ("requestId is: " + requestId);
686             msoLogger.debug ("About to insert a record");
687
688             try {
689                 msoRequest.createRequestRecord (Status.PENDING);
690             } catch (Exception e) {
691                 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "", MsoLogger.ErrorCode.SchemaError, "Exception while creating record in DB", e);
692                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
693                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
694                         ErrorNumbers.COULD_NOT_WRITE_TO_REQUESTS_DB,
695                         null,
696                         "non-unique request-id specified");
697                 // Cannot create a record of this request here, our communication with MSO DB just failed. Do not try
698                 // to create a failed record
699                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while creating record in DB");
700                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
701                 return response;
702             }
703
704             msoLogger.debug("Request going to BPEL: " + msoRequest.getRequestXML ());
705
706             RequestClient requestClient = null;
707             HttpResponse response = null;
708             long subStartTime = System.currentTimeMillis();
709             try {
710                 requestClient = RequestClientFactory.getRequestClient (orchestrationURI, props);
711                 // Capture audit event
712                 msoLogger.debug ("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl ());
713                 response = requestClient.post (msoRequest.getRequestXML (),
714                         requestId,
715                         Integer.toString (recipe.getRecipeTimeout ()).toString (),
716                         version,
717                         null,
718                         null);
719                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from BPMN engine", "BPMN", orchestrationURI, null);
720             } catch (Exception e) {
721                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN", orchestrationURI, null);
722                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
723                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
724                         ErrorNumbers.NO_COMMUNICATION_TO_BPEL,
725                         null,
726                         e.getMessage ());
727                 alarmLogger.sendAlarm ("MsoConfigurationError",
728                         MsoAlarmLogger.CRITICAL,
729                         Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
730                 msoRequest.updateFinalStatus (Status.FAILED);
731                 msoLogger.error (MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
732                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine");
733                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
734                 return resp;
735             }
736
737             if (response == null) {
738                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
739                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
740                         ErrorNumbers.NO_RESPONSE_FROM_BPEL,
741                         null,
742                         "bpelResponse is null");
743                 msoRequest.updateFinalStatus (Status.FAILED);
744                 msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Null response from BPEL", "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "Null response from BPEL");
745                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Null response from BPMN");
746                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
747                 return resp;
748             }
749
750             ResponseHandler respHandler = new ResponseHandler (response, requestClient.getType ());
751             int bpelStatus = respHandler.getStatus ();
752
753             // BPEL accepted the request, the request is in progress
754             if (bpelStatus == HttpStatus.SC_ACCEPTED) {
755                 String bpelXMLResponseBody = respHandler.getResponseBody ();
756                 msoLogger.debug ("Received from BPEL: " + bpelXMLResponseBody);
757                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.IN_PROGRESS);
758                 RequestsDatabase.updateInfraStatus (msoRequest.getRequestId (),
759                         Status.IN_PROGRESS.toString (),
760                         Constants.PROGRESS_REQUEST_IN_PROGRESS,
761                         Constants.MODIFIED_BY_APIHANDLER);
762                 Response resp = msoRequest.buildResponse (bpelStatus, null, null);
763                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "BPMN accepted the request, the request is in progress");
764                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
765                 return resp;
766             } else {
767
768                 String bpelXMLResponseBody = respHandler.getResponseBody ();
769                 if (bpelXMLResponseBody != null && !bpelXMLResponseBody.isEmpty ()) {
770                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
771                     Response resp = msoRequest.buildResponse (bpelStatus, bpelXMLResponseBody, null);
772                     msoRequest.updateFinalStatus (Status.FAILED);
773                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR,
774                             "Response from BPEL engine is failed with HTTP Status=" + bpelStatus, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
775                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is failed");
776                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
777                     return resp;
778                 } else {
779                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
780                     Response resp = msoRequest.buildResponse (bpelStatus, ErrorNumbers.ERROR_FROM_BPEL, null);
781                     msoRequest.updateFinalStatus (Status.FAILED);
782                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Response from BPEL engine is empty", "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Response from BPEL engine is empty");
783                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPEL engine is empty");
784                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
785                     return resp;
786                 }
787             }
788         } catch (Exception e) {
789             msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communciate with Catalog DB", e);
790             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.vnfbeans.RequestStatusType.FAILED);
791             Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
792                                                                    ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB,
793                                                                    null,
794                                                                    e.getMessage ());
795             alarmLogger.sendAlarm ("MsoDatabaseAccessError",
796                                    MsoAlarmLogger.CRITICAL,
797                                    Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
798             msoRequest.createRequestRecord (Status.FAILED);
799             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while communciate with DB");
800             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
801             return response;
802         }
803     }
804 }