e3af83df92ede641adb9b6abec9d79cf9bd4e56f
[so.git] /
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.Response;
40 import javax.ws.rs.core.UriInfo;
41 import javax.xml.bind.JAXBContext;
42 import javax.xml.bind.JAXBException;
43 import javax.xml.bind.Marshaller;
44
45 import org.apache.http.HttpResponse;
46 import org.apache.http.HttpStatus;
47
48 import javax.xml.bind.Unmarshaller;
49 import javax.xml.transform.sax.SAXSource;
50
51 import org.xml.sax.InputSource;
52
53 import org.openecomp.mso.apihandler.common.ErrorNumbers;
54 import org.openecomp.mso.apihandler.common.RequestClient;
55 import org.openecomp.mso.apihandler.common.RequestClientFactory;
56 import org.openecomp.mso.apihandler.common.ResponseHandler;
57 import org.openecomp.mso.apihandler.common.ValidationException;
58 import org.openecomp.mso.apihandlerinfra.volumebeans.ActionType;
59 import org.openecomp.mso.apihandlerinfra.volumebeans.ObjectFactory;
60 import org.openecomp.mso.apihandlerinfra.volumebeans.RequestInfo;
61 import org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType;
62 import org.openecomp.mso.apihandlerinfra.volumebeans.VolumeInputs;
63 import org.openecomp.mso.apihandlerinfra.volumebeans.VolumeOutputs;
64 import org.openecomp.mso.apihandlerinfra.volumebeans.VolumeRequest;
65 import org.openecomp.mso.apihandlerinfra.volumebeans.VolumeRequests;
66 import org.openecomp.mso.db.catalog.CatalogDatabase;
67 import org.openecomp.mso.db.catalog.beans.Recipe;
68 import org.openecomp.mso.logger.MessageEnum;
69 import org.openecomp.mso.logger.MsoAlarmLogger;
70 import org.openecomp.mso.logger.MsoLogger;
71 import org.openecomp.mso.properties.MsoJavaProperties;
72 import org.openecomp.mso.properties.MsoPropertiesFactory;
73 import org.openecomp.mso.requestsdb.InfraRequests;
74 import org.openecomp.mso.requestsdb.InfraActiveRequests;
75 import org.openecomp.mso.requestsdb.RequestsDatabase;
76 import org.openecomp.mso.utils.UUIDChecker;
77
78 @Path("/{version: v1|v2|v3}/volume-request")
79 public class VolumeRequestHandler {
80         
81     @Context
82     private UriInfo uriInfo;
83
84     protected ObjectFactory beansObjectFactory = new ObjectFactory ();
85
86     public final static String MSO_PROP_APIHANDLER_INFRA = "MSO_PROP_APIHANDLER_INFRA";
87
88     private static MsoLogger msoLogger = MsoLogger.getMsoLogger (MsoLogger.Catalog.APIH);
89
90     private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
91
92     private static MsoJavaProperties props = MsoPropertiesUtils.loadMsoProperties ();
93
94     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>";
95
96     private static final Response NOT_STARTED_RESPONSE = Response.status (HttpStatus.SC_SERVICE_UNAVAILABLE)
97             .entity (NOT_FOUND)
98             .build ();
99
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("tenantId") String tenantId,
107                                   @QueryParam("volume-group-id") String volumeGroupId,
108                                   @QueryParam("volume-group-name") String volumeGroupName,
109                                   @PathParam("version") String version) {
110         long startTime = System.currentTimeMillis ();
111         MsoLogger.setServiceName ("VolumeQueryFilters");
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         Response response = null;
121         if (vnfType != null) {
122             response = this.getRequestList ("vnfType", vnfType, version);
123         } else {
124                 response = queryGenericFilters (serviceType, aicNodeClli, tenantId, volumeGroupId, volumeGroupName, version);
125         }
126         msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successful");
127         msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
128         return response;
129     }
130
131     @GET
132     @Path(Constants.REQUEST_ID_PATH)
133     public Response getRequest (@PathParam("request-id") String requestId, @PathParam("version") String version) {
134         
135         // Check INFRA_ACTIVE_REQUESTS table to find info
136         // on this request
137         
138         long startTime = System.currentTimeMillis ();
139         MsoLogger.setServiceName ("VolumeGetRequest");
140         // Generate a Request Id
141         UUIDChecker.generateUUID(msoLogger);
142         msoLogger.debug ("Incoming request received for getRequest with request-id:" + requestId);
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
151    
152     protected MsoLogger getMsoLogger () {
153         return msoLogger;
154     }
155
156    
157      protected void fillVolumeRequest (VolumeRequest qr, InfraRequests ar, String version) {
158         VolumeInputs vi = beansObjectFactory.createVolumeInputs ();
159
160         if (ar.getVolumeGroupId () != null) {
161             vi.setVolumeGroupId (ar.getVolumeGroupId ());
162         }
163         if (ar.getVolumeGroupName () != null) {
164             vi.setVolumeGroupName (ar.getVolumeGroupName ());
165         }
166         if (ar.getVnfType () != null) {
167             vi.setVnfType (ar.getVnfType ());
168         }
169
170          switch (version) {
171              case Constants.SCHEMA_VERSION_V1:
172                  if (ar.getServiceType() != null) {
173                      vi.setServiceType(ar.getServiceType());
174                  }
175                  if (ar.getAicNodeClli() != null) {
176                      vi.setAicNodeClli(ar.getAicNodeClli());
177                  }
178                  break;
179              case Constants.SCHEMA_VERSION_V2:
180                  if (ar.getAaiServiceId() != null) {
181                      vi.setServiceId(ar.getAaiServiceId());
182                  }
183                  if (ar.getAicCloudRegion() != null) {
184                      vi.setAicCloudRegion(ar.getAicCloudRegion());
185                  }
186                  if (ar.getVfModuleModelName() != null) {
187                      vi.setVfModuleModelName(ar.getVfModuleModelName());
188                  }
189                  break;
190              case Constants.SCHEMA_VERSION_V3:
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.getVfModuleModelName() != null) {
198                      vi.setVfModuleModelName(ar.getVfModuleModelName());
199                  }
200                  if (ar.getServiceInstanceId() != null) {
201                      vi.setServiceInstanceId(ar.getServiceInstanceId());
202                  }
203                  if (ar.getVnfId() != null) {
204                      vi.setVnfId(ar.getVnfId());
205                  }
206                  break;
207          }
208         if (ar.getTenantId () != null) {
209             vi.setTenantId (ar.getTenantId ());
210         }
211         
212         qr.setVolumeInputs (vi);
213         
214         qr.setVolumeParams(ar.getVnfParams ());
215
216         try {
217             String volumeoutputs = ar.getVnfOutputs ();
218             if (volumeoutputs != null && volumeoutputs.length () > 0) {
219                 msoLogger.debug ("Read VOLUME outputs: " + volumeoutputs);
220                 VolumeOutputs volumeOutput = null;
221
222                 // Now unmarshal it into network outputs
223                 try {
224                     JAXBContext jaxbContext = JAXBContext.newInstance (VolumeOutputs.class);
225                     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller ();
226
227                     InputSource inputSource = new InputSource (new StringReader (volumeoutputs));
228                     SAXSource source = new SAXSource (inputSource);
229
230                     volumeOutput = (VolumeOutputs) jaxbUnmarshaller.unmarshal (source, VolumeOutputs.class).getValue ();
231
232                 } catch (Exception e) {
233                     msoLogger.debug ("Validation failed", e);
234                     throw new ValidationException ("format for volume outputs");
235                 }
236
237                 qr.setVolumeOutputs (volumeOutput);
238             }
239         } catch (Exception e) {
240             msoLogger.debug ("exception reading networkOutputs Clob", e);
241         }
242     }
243     
244     protected Response queryGenericFilters (String serviceType, String aicNodeClli, String tenantId, String volumeGroupId, String volumeGroupName, String version) {
245         if (serviceType != null) {
246             return this.getRequestList ("serviceType", serviceType, version);
247         }
248         if (aicNodeClli != null) {
249             return this.getRequestList ("aicNodeClli", aicNodeClli, version);
250         }
251         if (tenantId != null) {
252             return this.getRequestList ("tenantId", tenantId, version);
253         }
254         if (volumeGroupName != null) {
255                 return this.getRequestList ("volumeGroupName", volumeGroupName, version);
256         }
257         if (volumeGroupId != null) {
258                 return this.getRequestList ("volumeGroupId", volumeGroupId, version);
259         }
260         return Response.status (HttpStatus.SC_BAD_REQUEST).entity ("").build ();
261     }
262
263
264     protected Response getRequestGeneric (String requestId, String version) {
265         // Check INFRA_ACTIVE_REQUESTS table  to find info
266         // on this request
267
268         getMsoLogger ().debug ("getRequest: " + requestId);
269
270         String responseString = null;
271
272         InfraActiveRequests activeReq = requestDB.getRequestFromInfraActive (requestId,
273                                                                                     "VOLUME");
274         if (activeReq != null) {
275             // build response for active
276             responseString = infraRequestsResponse (activeReq, version);
277             return Response.status (HttpStatus.SC_OK).entity (responseString).build ();
278         } else {
279             // Report that no request has been found
280             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
281          }
282     }
283
284     protected Response getRequestList (String queryAttribute, String queryValue, String version) {
285         // Check INFRA_ACTIVE_REQUESTS table to find info
286         // on this request
287
288         getMsoLogger ().debug ("getRequest based on " + queryAttribute + ": " + queryValue);
289
290         List <InfraActiveRequests> activeReqList = requestDB.getRequestListFromInfraActive (queryAttribute,
291                                                                                                    queryValue,
292                                                                                                    "VOLUME");
293   
294         List <VolumeRequest> queryResponseList = new LinkedList<>();
295
296         if (activeReqList != null) {
297             // build response for active
298             queryResponseList = infraRequestsResponses (activeReqList, version);
299
300         }
301
302  
303         if (queryResponseList != null && !queryResponseList.isEmpty ()) {
304             String result = this.translateVolumeRequests (queryResponseList);
305             return Response.status (HttpStatus.SC_OK).entity (result).build ();
306
307         } else {
308             // Report that no request has been found
309             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
310         }
311     }
312
313     private VolumeRequest fillGeneric (InfraRequests ar) {
314         VolumeRequest qr = beansObjectFactory.createVolumeRequest ();
315         RequestInfo ri = beansObjectFactory.createRequestInfo ();
316         ri.setRequestId (ar.getRequestId ());
317         ri.setAction (ActionType.fromValue (ar.getAction ()));
318         ri.setRequestStatus (RequestStatusType.fromValue (ar.getRequestStatus ()));
319         if (ar.getProgress () != null) {
320             ri.setProgress (ar.getProgress ().intValue ());
321         }
322         if (ar.getSource () != null) {
323             ri.setSource (ar.getSource ());
324         }
325
326         ri.setStartTime (ar.getStartTime ().toString ());
327         if (ar.getEndTime () != null) {
328             ri.setEndTime (ar.getEndTime ().toString ());
329         }
330         
331         if (ar.getStatusMessage () != null) {
332                 ri.setStatusMessage (ar.getStatusMessage ());
333         }
334         qr.setRequestInfo (ri);
335         return qr;
336     }
337
338     private List <VolumeRequest> infraRequestsResponses (List <? extends InfraRequests> arList, String version) {
339         List <VolumeRequest> queryResponseList = new LinkedList<>();
340
341         for (InfraRequests ar : arList) {
342             VolumeRequest qr = fillGeneric (ar);
343             fillVolumeRequest (qr, ar, version);
344             queryResponseList.add (qr);
345         }
346         return queryResponseList;
347     }
348
349     private String translateVolumeRequests (List <VolumeRequest> queryResponseList) {
350         VolumeRequests queryResponses = new VolumeRequests ();
351         for (VolumeRequest aQueryResponseList : queryResponseList) {
352             queryResponses.getVolumeRequest().add(aQueryResponseList);
353         }
354
355         StringWriter stringWriter = new StringWriter ();
356         try {
357             JAXBContext jaxbContext = JAXBContext.newInstance (VolumeRequests.class);
358             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
359
360             // output pretty printed
361             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
362
363             jaxbMarshaller.marshal (queryResponses, stringWriter);
364
365         } catch (JAXBException e) {
366             getMsoLogger ().debug ("Marshalling issue", e);
367         }
368
369         return stringWriter.toString ();
370     }
371
372     private String infraRequestsResponse (InfraRequests ar, String version) {
373         VolumeRequest qr = fillGeneric (ar);
374         fillVolumeRequest (qr, ar, version);
375
376         StringWriter stringWriter = new StringWriter ();
377         try {
378             JAXBContext jaxbContext = JAXBContext.newInstance (VolumeRequest.class);
379             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
380
381             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
382             jaxbMarshaller.marshal (qr, stringWriter);
383
384         } catch (JAXBException e) {
385             getMsoLogger ().debug ("Marshalling issue", e);
386         }
387
388         String response = stringWriter.toString ();
389         return response;
390     }
391
392     private String getAuditLogReturnMsg (Response response) {
393         String returnMsg = "";
394         if (response.getStatus() == HttpStatus.SC_OK) {
395                 returnMsg = "Successful. StatusCode=" + HttpStatus.SC_OK;
396         } else if (response.getStatus() == HttpStatus.SC_NOT_FOUND) {
397                 returnMsg = "Record not found . StatusCode=" + HttpStatus.SC_NOT_FOUND;
398         } else if (response.getStatus() == HttpStatus.SC_BAD_REQUEST) {
399                 returnMsg = "Bad request: one of the following attribute serviceType, aicNodeClli, tenantId, volumeGroupId, volumeGroupName should be defined. StatusCode=" + HttpStatus.SC_BAD_REQUEST;
400         }
401         return returnMsg;
402     }
403
404     @POST
405     @Path("/")
406     @Produces(MediaType.APPLICATION_XML)
407     public Response manageVolumeRequest (String reqXML, @PathParam("version") String version) {
408         MsoLogger.setServiceName ("VolumeRequest");
409         if ("v1".equals(version)) {
410             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V1);
411         } else if ("v2".equals(version)) {
412             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V2);
413         } else if ("v3".equals(version)) {
414             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V3);
415         } else {
416             long startTime = System.currentTimeMillis ();
417             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "Version not found");
418                 return Response.status(HttpStatus.SC_NOT_FOUND).build();
419         }
420     }
421
422     private Response manageVolumeRequestImpl (String reqXML, String version) {
423         String methodName = "VolumeRequest";
424         props = MsoPropertiesUtils.loadMsoProperties ();
425        
426         long startTime = System.currentTimeMillis ();
427         if (MsoPropertiesUtils.getNoPropertiesState()) {
428             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.ServiceNotAvailable, "Application not started, properties file missing or invalid");
429                 return NOT_STARTED_RESPONSE;
430         }
431
432         uriInfo.getRequestUri ();
433
434         // Generate unique request id for the new request
435         UUID requestUUID = UUID.randomUUID ();
436
437         VolumeMsoInfraRequest msoRequest = new VolumeMsoInfraRequest (requestUUID.toString ());
438
439         if (reqXML == null) {
440             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "The input request is null");
441             return Response.status (HttpStatus.SC_NO_CONTENT).entity ("").build ();
442         }
443
444         String requestUri = uriInfo.getRequestUri ().toString ();
445
446         msoLogger.debug ("Incoming Request: " + reqXML);
447
448         msoRequest.setRequestUri (requestUri);
449        
450         msoLogger.debug ("Schema version: " + version);
451         try {
452             msoRequest.parse (reqXML, version, props);
453         } catch (Exception e) {
454             msoLogger.debug ("Validation failed: ", e);
455             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
456             Response response = msoRequest.buildResponseFailedValidation (HttpStatus.SC_BAD_REQUEST, e.getMessage ());
457             if (msoRequest.getRequestId () != null) {
458                 msoLogger.debug ("Logging failed message to the database");
459                 msoRequest.createRequestRecord (Status.FAILED);
460             }
461             msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR, reqXML, "", "", MsoLogger.ErrorCode.DataError, "Exception when parsing reqXML", e);
462             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, "Validation of the input request failed");
463             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
464             return response;
465         }
466         MsoLogger.setServiceName (MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo ().getAction ().name ());
467         msoLogger.debug ("Update serviceName with detailed action info to:" + MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo ().getAction ().name ());
468         if (msoRequest.getRequestInfo ()
469                       .getAction () == org.openecomp.mso.apihandlerinfra.volumebeans.ActionType.CREATE) {
470             // Check if this request is a duplicate of the one with the same network Name
471             msoLogger.debug ("Checking for a duplicate with the same volume-name");
472             InfraActiveRequests dup = null;
473             try {
474
475                 dup = requestDB.checkDuplicateByVnfName (msoRequest.getVolumeInputs ().getVolumeGroupName (),
476                                                                 msoRequest.getRequestInfo ().getAction ().value (),
477                                                                 "VOLUME");
478
479             } catch (Exception e) {
480                 msoLogger.debug ("Exception", e);
481                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.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, "volume-group-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.volumebeans.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,
502                                 "CREATE on the same Volume Group Name is already progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicates request - CREATE on the same Volume Group Name is already progress");
503                 msoRequest.createRequestRecord (Status.FAILED);
504                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicates request - CREATE on the same Volume Group Name is already progress");
505                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
506                 return response;
507             }
508         } else {
509             // Check if this request is a duplicate of the one with the same volumeGroupId
510             InfraActiveRequests dup = null;
511             msoLogger.debug ("Checking for a duplicate with the same volume-group-id");
512             try {
513                 dup = requestDB.checkDuplicateByVnfId (msoRequest.getVolumeInputs ().getVolumeGroupId (),
514                                                               msoRequest.getRequestInfo ().getAction ().value (),
515                                                               "VOLUME");
516
517             } catch (Exception e) {
518                 msoLogger.debug ("Exception", e);
519                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
520                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
521                                                                        ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB,
522                                                                        null,
523                                                                        e.getMessage ());
524                 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
525                                        MsoAlarmLogger.CRITICAL,
526                                        Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
527                 msoRequest.createRequestRecord (Status.FAILED);
528                 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC_ATT, "volume-group-id", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for a duplicate request with the sam volume-group-id", e);
529                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for a duplicate request with the sam volume-group-id");
530                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
531                 return response;
532             }
533             if (dup != null) {
534                 // Found the duplicate record. Return the appropriate error.
535                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
536                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
537                                                               ErrorNumbers.LOCKED_SAME_ACTION_AND_VNF_ID,
538                                                               dup);
539                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND,
540                                 msoRequest.getRequestInfo ().getAction ().value ()
541                                                                   + " on the same Volume Group Id already in progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicated request on the same Volume Group Id already in progress");
542                 msoRequest.createRequestRecord (Status.FAILED);
543                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicated request on the same Volume Group 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             Recipe recipe = null;
554
555             if (version.equals(Constants.SCHEMA_VERSION_V1)) {
556                 if (msoRequest.getServiceType () != null
557                         && msoRequest.getServiceType ().length () > 0) {
558                     recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
559                             Constants.VOLUME_GROUP_COMPONENT_TYPE,
560                             msoRequest.getRequestInfo ().getAction ().value (),
561                             msoRequest.getServiceType ());
562                 }
563                 if (recipe == null) {
564                     recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
565                             Constants.VOLUME_GROUP_COMPONENT_TYPE,
566                             msoRequest.getRequestInfo ().getAction ().value (),
567                             null);
568                     // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
569                     if (recipe == null) {
570                         recipe = db.getVnfComponentsRecipe (Constants.VNF_TYPE_WILDCARD,
571                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
572                                 msoRequest.getRequestInfo ().getAction ().value (),
573                                 null);
574                     }
575                 }
576             }
577             else if (version.equals (Constants.SCHEMA_VERSION_V2) || version.equals (Constants.SCHEMA_VERSION_V3)) {
578                 switch (msoRequest.getRequestInfo ().getAction ()) {
579                     case CREATE:
580                     case UPDATE:
581                     case DELETE:
582                         // First get recipe for the vnf type given
583                         recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
584                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
585                                 msoRequest.getRequestInfo ().getAction ().value (), null);
586
587                         // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
588                         if (recipe == null) {
589                             recipe = db.getVnfComponentsRecipe (Constants.VNF_TYPE_WILDCARD,
590                                     Constants.VOLUME_GROUP_COMPONENT_TYPE,
591                                     msoRequest.getRequestInfo ().getAction ().value (), null);
592                         }
593                         break;
594                     case CREATE_VF_MODULE_VOL:
595                     case UPDATE_VF_MODULE_VOL:
596                     case DELETE_VF_MODULE_VOL:
597                         // First get recipe for the vnf type given
598                         recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
599                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
600                                 msoRequest.getRequestInfo ().getAction ().value (), null);
601
602                         // If no recipe for the vnf type is found, look for generic recipe with "*" in vf module id
603                         if (recipe == null) {
604                                 recipe = db.getVnfComponentsRecipeByVfModuleModelUUId (Constants.VNF_TYPE_WILDCARD,
605                                     Constants.VOLUME_GROUP_COMPONENT_TYPE,
606                                     msoRequest.getRequestInfo ().getAction ().value ());
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, "VNF Recipe not found in DB");
617                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.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, "VNF Recipe not 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             String requestId = msoRequest.getRequestId ();
631             msoLogger.debug ("requestId is: " + requestId);
632             msoLogger.debug ("About to insert a record");
633
634             try {
635                 msoRequest.createRequestRecord (Status.PENDING);
636             } catch (Exception e) {
637                 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception in createRequestRecord", e);
638                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
639                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
640                         ErrorNumbers.COULD_NOT_WRITE_TO_REQUESTS_DB,
641                         null,
642                         "non-unique request-id specified");
643                 // Cannot create a record of this request here, our communication with MSO DB just failed. Do not try
644                 // to create a failed record
645                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while creating record in DB");
646                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
647                 return response;
648             }
649
650             RequestClient requestClient = null;
651             HttpResponse response = null;
652             long subStartTime = System.currentTimeMillis();
653             try {
654                 requestClient = RequestClientFactory.getRequestClient (orchestrationURI, props);
655                 // Capture audit event
656                 msoLogger.debug ("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl ());
657                 response = requestClient.post(msoRequest.getRequestXML(),
658                     requestId,
659                     Integer.toString(recipe.getRecipeTimeout()),
660                     version,
661                     null,
662                     null);
663                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from BPMN engine", "BPMN", orchestrationURI, null);
664             } catch (Exception e) {
665                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN", orchestrationURI, null);
666                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
667                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
668                         ErrorNumbers.NO_COMMUNICATION_TO_BPEL,
669                         null,
670                         e.getMessage ());
671                 alarmLogger.sendAlarm ("MsoConfigurationError",
672                         MsoAlarmLogger.CRITICAL,
673                         Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
674                 msoRequest.updateFinalStatus (Status.FAILED);
675                 msoLogger.error (MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
676                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine");
677                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
678                 return resp;
679             }
680
681             if (response == null) {
682                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
683                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
684                         ErrorNumbers.NO_RESPONSE_FROM_BPEL,
685                         null,
686                         "bpelResponse is null");
687                 msoRequest.updateFinalStatus (Status.FAILED);
688                 msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Null response from BPEL", "Camunda", "", MsoLogger.ErrorCode.DataError, "Null response from BPMN engine");
689                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Null response from BPMN engine");
690                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
691                 return resp;
692             }
693
694             ResponseHandler respHandler = new ResponseHandler (response, requestClient.getType ());
695             int bpelStatus = respHandler.getStatus ();
696
697             // BPEL accepted the request, the request is in progress
698             if (bpelStatus == HttpStatus.SC_ACCEPTED) {
699                 String bpelXMLResponseBody = respHandler.getResponseBody ();
700                 msoLogger.debug ("Received from BPEL: " + bpelXMLResponseBody);
701                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.IN_PROGRESS);
702                 requestDB.updateInfraStatus (msoRequest.getRequestId (),
703                         Status.IN_PROGRESS.toString (),
704                         Constants.PROGRESS_REQUEST_IN_PROGRESS,
705                         Constants.MODIFIED_BY_APIHANDLER);
706                 Response resp = msoRequest.buildResponse (bpelStatus, null, null);
707                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "BPMN accepted the request, the request is in progress");
708                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
709                 return resp;
710             } else {
711
712                 String bpelXMLResponseBody = respHandler.getResponseBody ();
713                 if (bpelXMLResponseBody != null && !bpelXMLResponseBody.isEmpty ()) {
714                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
715                     Response resp = msoRequest.buildResponse (bpelStatus, bpelXMLResponseBody, null);
716                     msoRequest.updateFinalStatus (Status.FAILED);
717                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR,
718                             "Response from BPEL engine is failed with HTTP Status=" + bpelStatus, "Camunda", "", MsoLogger.ErrorCode.DataError, "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
719                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is with status Failed");
720                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
721                     return resp;
722                 } else {
723                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
724                     Response resp = msoRequest.buildResponse (bpelStatus, ErrorNumbers.ERROR_FROM_BPEL, null);
725                     msoRequest.updateFinalStatus (Status.FAILED);
726                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Response from BPEL engine is empty", "Camunda", "", MsoLogger.ErrorCode.DataError, "Response from BPEL engine is empty");
727                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is empty");
728                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
729                     return resp;
730                 }
731             }
732
733         } catch (Exception e) {
734             msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception while communciate with Catalog DB", e);
735             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
736             Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
737                                                                    ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB,
738                                                                    null,
739                                                                    e.getMessage ());
740             alarmLogger.sendAlarm ("MsoDatabaseAccessError",
741                                    MsoAlarmLogger.CRITICAL,
742                                    Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
743             msoRequest.createRequestRecord (Status.FAILED);
744             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while communciate with DB");
745             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
746             return response;
747         }
748
749     }
750 }