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