Change the header to SO
[so.git] / mso-api-handlers / mso-api-handler-infra / src / main / java / org / openecomp / mso / apihandlerinfra / VolumeRequestHandler.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.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         if (version.equals(Constants.SCHEMA_VERSION_V1)) {
171                 if (ar.getServiceType () != null) {
172                         vi.setServiceType (ar.getServiceType ());
173                 }
174                 if (ar.getAicNodeClli () != null) {
175                         vi.setAicNodeClli (ar.getAicNodeClli ());
176                 }
177         }
178         else if (version.equals(Constants.SCHEMA_VERSION_V2)) {
179                 if (ar.getAaiServiceId () != null) {
180                         vi.setServiceId (ar.getAaiServiceId ());
181                 }
182                 if (ar.getAicCloudRegion () != null) {
183                         vi.setAicCloudRegion (ar.getAicCloudRegion ());
184                 }               
185                 if (ar.getVfModuleModelName () != null) {
186                         vi.setVfModuleModelName (ar.getVfModuleModelName ());
187                 }               
188         }
189         else if (version.equals(Constants.SCHEMA_VERSION_V3)) {
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.getVfModuleModelName () != null) {
197                         vi.setVfModuleModelName (ar.getVfModuleModelName ());
198                 }
199                 if (ar.getServiceInstanceId () != null) {
200                         vi.setServiceInstanceId (ar.getServiceInstanceId ());
201                 }
202                 if (ar.getVnfId () != null) {
203                 vi.setVnfId (ar.getVnfId ());
204             }
205         }
206         if (ar.getTenantId () != null) {
207             vi.setTenantId (ar.getTenantId ());
208         }
209         
210         qr.setVolumeInputs (vi);
211         
212         qr.setVolumeParams(ar.getVnfParams ());
213
214         try {
215             String volumeoutputs = ar.getVnfOutputs ();
216             if (volumeoutputs != null && volumeoutputs.length () > 0) {
217                 msoLogger.debug ("Read VOLUME outputs: " + volumeoutputs);
218                 VolumeOutputs volumeOutput = null;
219
220                 // Now unmarshal it into network outputs
221                 try {
222                     JAXBContext jaxbContext = JAXBContext.newInstance (VolumeOutputs.class);
223                     Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller ();
224
225                     InputSource inputSource = new InputSource (new StringReader (volumeoutputs));
226                     SAXSource source = new SAXSource (inputSource);
227
228                     volumeOutput = (VolumeOutputs) jaxbUnmarshaller.unmarshal (source, VolumeOutputs.class).getValue ();
229
230                 } catch (Exception e) {
231                     msoLogger.debug ("Validation failed", e);
232                     throw new ValidationException ("format for volume outputs");
233                 }
234
235                 qr.setVolumeOutputs (volumeOutput);
236             }
237         } catch (Exception e) {
238             msoLogger.debug ("exception reading networkOutputs Clob", e);
239         }
240     }
241     
242     protected Response queryGenericFilters (String serviceType, String aicNodeClli, String tenantId, String volumeGroupId, String volumeGroupName, String version) {
243         if (serviceType != null) {
244             return this.getRequestList ("serviceType", serviceType, version);
245         }
246         if (aicNodeClli != null) {
247             return this.getRequestList ("aicNodeClli", aicNodeClli, version);
248         }
249         if (tenantId != null) {
250             return this.getRequestList ("tenantId", tenantId, version);
251         }
252         if (volumeGroupName != null) {
253                 return this.getRequestList ("volumeGroupName", volumeGroupName, version);
254         }
255         if (volumeGroupId != null) {
256                 return this.getRequestList ("volumeGroupId", volumeGroupId, version);
257         }
258         return Response.status (HttpStatus.SC_BAD_REQUEST).entity ("").build ();
259     }
260
261
262     protected Response getRequestGeneric (String requestId, String version) {
263         // Check INFRA_ACTIVE_REQUESTS table  to find info
264         // on this request
265
266         getMsoLogger ().debug ("getRequest: " + requestId);
267
268         String responseString = null;
269
270         InfraActiveRequests activeReq = requestDB.getRequestFromInfraActive (requestId,
271                                                                                     "VOLUME");
272         if (activeReq != null) {
273             // build response for active
274             responseString = infraRequestsResponse (activeReq, version);
275             return Response.status (HttpStatus.SC_OK).entity (responseString).build ();
276         } else {
277             // Report that no request has been found
278             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
279          }
280     }
281
282     protected Response getRequestList (String queryAttribute, String queryValue, String version) {
283         // Check INFRA_ACTIVE_REQUESTS table to find info
284         // on this request
285
286         getMsoLogger ().debug ("getRequest based on " + queryAttribute + ": " + queryValue);
287
288         List <InfraActiveRequests> activeReqList = requestDB.getRequestListFromInfraActive (queryAttribute,
289                                                                                                    queryValue,
290                                                                                                    "VOLUME");
291   
292         List <VolumeRequest> queryResponseList = new LinkedList <VolumeRequest> ();
293
294         if (activeReqList != null) {
295             // build response for active
296             queryResponseList = infraRequestsResponses (activeReqList, version);
297
298         }
299
300  
301         if (queryResponseList != null && !queryResponseList.isEmpty ()) {
302             String result = this.translateVolumeRequests (queryResponseList);
303             return Response.status (HttpStatus.SC_OK).entity (result).build ();
304
305         } else {
306             // Report that no request has been found
307             return Response.status (HttpStatus.SC_NOT_FOUND).entity ("").build ();
308         }
309     }
310
311     private VolumeRequest fillGeneric (InfraRequests ar) {
312         VolumeRequest qr = beansObjectFactory.createVolumeRequest ();
313         RequestInfo ri = beansObjectFactory.createRequestInfo ();
314         ri.setRequestId (ar.getRequestId ());
315         ri.setAction (ActionType.fromValue (ar.getAction ()));
316         ri.setRequestStatus (RequestStatusType.fromValue (ar.getRequestStatus ()));
317         if (ar.getProgress () != null) {
318             ri.setProgress (ar.getProgress ().intValue ());
319         }
320         if (ar.getSource () != null) {
321             ri.setSource (ar.getSource ());
322         }
323
324         ri.setStartTime (ar.getStartTime ().toString ());
325         if (ar.getEndTime () != null) {
326             ri.setEndTime (ar.getEndTime ().toString ());
327         }
328         
329         if (ar.getStatusMessage () != null) {
330                 ri.setStatusMessage (ar.getStatusMessage ());
331         }
332         qr.setRequestInfo (ri);
333         return qr;
334     }
335
336     private List <VolumeRequest> infraRequestsResponses (List <? extends InfraRequests> arList, String version) {
337         List <VolumeRequest> queryResponseList = new LinkedList <VolumeRequest> ();
338
339         for (InfraRequests ar : arList) {
340             VolumeRequest qr = fillGeneric (ar);
341             fillVolumeRequest (qr, ar, version);
342             queryResponseList.add (qr);
343         }
344         return queryResponseList;
345     }
346
347     private String translateVolumeRequests (List <VolumeRequest> queryResponseList) {
348         VolumeRequests queryResponses = new VolumeRequests ();
349         for (int i = 0; i < queryResponseList.size (); i++) {
350             queryResponses.getVolumeRequest ().add (queryResponseList.get (i));
351         }
352
353         StringWriter stringWriter = new StringWriter ();
354         try {
355             JAXBContext jaxbContext = JAXBContext.newInstance (VolumeRequests.class);
356             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
357
358             // output pretty printed
359             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
360
361             jaxbMarshaller.marshal (queryResponses, stringWriter);
362
363         } catch (JAXBException e) {
364             getMsoLogger ().debug ("Marshalling issue", e);
365         }
366
367         return stringWriter.toString ();
368     }
369
370     private String infraRequestsResponse (InfraRequests ar, String version) {
371         VolumeRequest qr = fillGeneric (ar);
372         fillVolumeRequest (qr, ar, version);
373
374         StringWriter stringWriter = new StringWriter ();
375         try {
376             JAXBContext jaxbContext = JAXBContext.newInstance (VolumeRequest.class);
377             Marshaller jaxbMarshaller = jaxbContext.createMarshaller ();
378
379             jaxbMarshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true);
380             jaxbMarshaller.marshal (qr, stringWriter);
381
382         } catch (JAXBException e) {
383             getMsoLogger ().debug ("Marshalling issue", e);
384         }
385
386         String response = stringWriter.toString ();
387         return response;
388     }
389
390     private String getAuditLogReturnMsg (Response response) {
391         String returnMsg = "";
392         if (response.getStatus() == HttpStatus.SC_OK) {
393                 returnMsg = "Successful. StatusCode=" + HttpStatus.SC_OK;
394         } else if (response.getStatus() == HttpStatus.SC_NOT_FOUND) {
395                 returnMsg = "Record not found . StatusCode=" + HttpStatus.SC_NOT_FOUND;
396         } else if (response.getStatus() == HttpStatus.SC_BAD_REQUEST) {
397                 returnMsg = "Bad request: one of the following attribute serviceType, aicNodeClli, tenantId, volumeGroupId, volumeGroupName should be defined. StatusCode=" + HttpStatus.SC_BAD_REQUEST;
398         }
399         return returnMsg;
400     }
401
402     @POST
403     @Path("/")
404     @Produces(MediaType.APPLICATION_XML)
405     public Response manageVolumeRequest (String reqXML, @PathParam("version") String version) {
406         MsoLogger.setServiceName ("VolumeRequest");
407         if ("v1".equals(version)) {
408             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V1);
409         } else if ("v2".equals(version)) {
410             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V2);
411         } else if ("v3".equals(version)) {
412             return manageVolumeRequestImpl (reqXML, Constants.SCHEMA_VERSION_V3);
413         } else {
414             long startTime = System.currentTimeMillis ();
415             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "Version not found");
416                 return Response.status(HttpStatus.SC_NOT_FOUND).build();
417         }
418     }
419
420     private Response manageVolumeRequestImpl (String reqXML, String version) {
421         String methodName = "VolumeRequest";
422         props = MsoPropertiesUtils.loadMsoProperties ();
423        
424         long startTime = System.currentTimeMillis ();
425         if (MsoPropertiesUtils.getNoPropertiesState()) {
426             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.ServiceNotAvailable, "Application not started, properties file missing or invalid");
427                 return NOT_STARTED_RESPONSE;
428         }
429
430         uriInfo.getRequestUri ();
431
432         // Generate unique request id for the new request
433         UUID requestUUID = UUID.randomUUID ();
434
435         VolumeMsoInfraRequest msoRequest = new VolumeMsoInfraRequest (requestUUID.toString ());
436
437         if (reqXML == null) {
438             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "The input request is null");
439             return Response.status (HttpStatus.SC_NO_CONTENT).entity ("").build ();
440         }
441
442         String requestUri = uriInfo.getRequestUri ().toString ();
443
444         msoLogger.debug ("Incoming Request: " + reqXML);
445
446         msoRequest.setRequestUri (requestUri);
447        
448         msoLogger.debug ("Schema version: " + version);
449         try {
450             msoRequest.parse (reqXML, version, props);
451         } catch (Exception e) {
452             msoLogger.debug ("Validation failed: ", e);
453             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
454             Response response = msoRequest.buildResponseFailedValidation (HttpStatus.SC_BAD_REQUEST, e.getMessage ());
455             if (msoRequest.getRequestId () != null) {
456                 msoLogger.debug ("Logging failed message to the database");
457                 msoRequest.createRequestRecord (Status.FAILED);
458             }
459             msoLogger.error (MessageEnum.APIH_REQUEST_VALIDATION_ERROR, reqXML, "", "", MsoLogger.ErrorCode.DataError, "Exception when parsing reqXML", e);
460             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, "Validation of the input request failed");
461             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
462             return response;
463         }
464         MsoLogger.setServiceName (MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo ().getAction ().name ());
465         msoLogger.debug ("Update serviceName with detailed action info to:" + MsoLogger.getServiceName () + "_" + msoRequest.getRequestInfo ().getAction ().name ());
466         if (msoRequest.getRequestInfo ()
467                       .getAction () == org.openecomp.mso.apihandlerinfra.volumebeans.ActionType.CREATE) {
468             // Check if this request is a duplicate of the one with the same network Name
469             msoLogger.debug ("Checking for a duplicate with the same volume-name");
470             InfraActiveRequests dup = null;
471             try {
472
473                 dup = requestDB.checkDuplicateByVnfName (msoRequest.getVolumeInputs ().getVolumeGroupName (),
474                                                                 msoRequest.getRequestInfo ().getAction ().value (),
475                                                                 "VOLUME");
476
477             } catch (Exception e) {
478                 msoLogger.debug ("Exception", e);
479                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
480                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
481                                                                        ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB,
482                                                                        null,
483                                                                        e.getMessage ());
484                 alarmLogger.sendAlarm ("MsoDatabaseAccessError",
485                                        MsoAlarmLogger.CRITICAL,
486                                        Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_REQUESTS_DB));
487                 msoRequest.createRequestRecord (Status.FAILED);
488                 msoLogger.error (MessageEnum.APIH_DUPLICATE_CHECK_EXC_ATT, "volume-group-name", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for duplicated request", e);
489                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for duplicated request");
490                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
491                 return response;
492             }
493             if (dup != null) {
494                 // Found the duplicate record. Return the appropriate error.
495                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
496                 Response response = msoRequest.buildResponse (HttpStatus.SC_CONFLICT,
497                                                               ErrorNumbers.LOCKED_CREATE_ON_THE_SAME_VNF_NAME_IN_PROGRESS,
498                                                               dup);
499                 msoLogger.warn (MessageEnum.APIH_DUPLICATE_FOUND,
500                                 "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");
501                 msoRequest.createRequestRecord (Status.FAILED);
502                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicates request - CREATE on the same Volume Group 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 volumeGroupId
508             InfraActiveRequests dup = null;
509             msoLogger.debug ("Checking for a duplicate with the same volume-group-id");
510             try {
511                 dup = requestDB.checkDuplicateByVnfId (msoRequest.getVolumeInputs ().getVolumeGroupId (),
512                                                               msoRequest.getRequestInfo ().getAction ().value (),
513                                                               "VOLUME");
514
515             } catch (Exception e) {
516                 msoLogger.debug ("Exception", e);
517                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.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, "volume-group-id", "", "", MsoLogger.ErrorCode.DataError, "Exception while checking for a duplicate request with the sam volume-group-id", e);
527                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while checking for a duplicate request with the sam volume-group-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.volumebeans.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 Volume Group Id already in progress", "", "", MsoLogger.ErrorCode.DataError, "Duplicated request on the same Volume Group Id already in progress");
540                 msoRequest.createRequestRecord (Status.FAILED);
541                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, "Duplicated request on the same Volume Group Id already in progress");
542                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
543                 return response;
544             }
545         }
546
547         String orchestrationURI = "";
548
549         // Query MSO Catalog DB
550         try(CatalogDatabase db = CatalogDatabase.getInstance()) {
551             Recipe recipe = null;
552
553             if (version.equals(Constants.SCHEMA_VERSION_V1)) {
554                 if (msoRequest.getServiceType () != null
555                         && msoRequest.getServiceType ().length () > 0) {
556                     recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
557                             Constants.VOLUME_GROUP_COMPONENT_TYPE,
558                             msoRequest.getRequestInfo ().getAction ().value (),
559                             msoRequest.getServiceType ());
560                 }
561                 if (recipe == null) {
562                     recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
563                             Constants.VOLUME_GROUP_COMPONENT_TYPE,
564                             msoRequest.getRequestInfo ().getAction ().value (),
565                             null);
566                     // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
567                     if (recipe == null) {
568                         recipe = db.getVnfComponentsRecipe (Constants.VNF_TYPE_WILDCARD,
569                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
570                                 msoRequest.getRequestInfo ().getAction ().value (),
571                                 null);
572                     }
573                 }
574             }
575             else if (version.equals (Constants.SCHEMA_VERSION_V2) || version.equals (Constants.SCHEMA_VERSION_V3)) {
576                 switch (msoRequest.getRequestInfo ().getAction ()) {
577                     case CREATE:
578                     case UPDATE:
579                     case DELETE:
580                         // First get recipe for the vnf type given
581                         recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
582                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
583                                 msoRequest.getRequestInfo ().getAction ().value (), null);
584
585                         // If no recipe for the vnf type is found, look for generic recipe with "*" vnf type
586                         if (recipe == null) {
587                             recipe = db.getVnfComponentsRecipe (Constants.VNF_TYPE_WILDCARD,
588                                     Constants.VOLUME_GROUP_COMPONENT_TYPE,
589                                     msoRequest.getRequestInfo ().getAction ().value (), null);
590                         }
591                         break;
592                     case CREATE_VF_MODULE_VOL:
593                     case UPDATE_VF_MODULE_VOL:
594                     case DELETE_VF_MODULE_VOL:
595                         // First get recipe for the vnf type given
596                         recipe = db.getVnfComponentsRecipe (msoRequest.getVolumeInputs ().getVnfType (),
597                                 Constants.VOLUME_GROUP_COMPONENT_TYPE,
598                                 msoRequest.getRequestInfo ().getAction ().value (), null);
599
600                         // If no recipe for the vnf type is found, look for generic recipe with "*" in vf module id
601                         if (recipe == null) {
602                                 recipe = db.getVnfComponentsRecipeByVfModuleModelUUId (Constants.VNF_TYPE_WILDCARD,
603                                     Constants.VOLUME_GROUP_COMPONENT_TYPE,
604                                     msoRequest.getRequestInfo ().getAction ().value ());
605                         }
606                         break;
607                     default:
608                         break;
609                 }
610
611             }
612
613             if (recipe == null) {
614                 msoLogger.error (MessageEnum.APIH_DB_ATTRIBUTE_NOT_FOUND, "VNF Recipe", "", "", MsoLogger.ErrorCode.DataError, "VNF Recipe not found in DB");
615                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
616                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
617                         ErrorNumbers.RECIPE_DOES_NOT_EXIST,
618                         null,
619                         "");
620                 msoRequest.createRequestRecord (Status.FAILED);
621                 db.close ();
622                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, "VNF Recipe not found in DB");
623                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
624                 return response;
625             }
626             orchestrationURI = recipe.getOrchestrationUri ();
627             msoLogger.debug ("Orchestration URI is: " + orchestrationURI);
628             String requestId = msoRequest.getRequestId ();
629             msoLogger.debug ("requestId is: " + requestId);
630             msoLogger.debug ("About to insert a record");
631
632             try {
633                 msoRequest.createRequestRecord (Status.PENDING);
634             } catch (Exception e) {
635                 msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC_REASON, "Exception while creating record in DB", "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception in createRequestRecord", e);
636                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
637                 Response response = msoRequest.buildResponseWithError (HttpStatus.SC_INTERNAL_SERVER_ERROR,
638                         ErrorNumbers.COULD_NOT_WRITE_TO_REQUESTS_DB,
639                         null,
640                         "non-unique request-id specified");
641                 // Cannot create a record of this request here, our communication with MSO DB just failed. Do not try
642                 // to create a failed record
643                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while creating record in DB");
644                 msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
645                 return response;
646             }
647
648             RequestClient requestClient = null;
649             HttpResponse response = null;
650             long subStartTime = System.currentTimeMillis();
651             try {
652                 requestClient = RequestClientFactory.getRequestClient (orchestrationURI, props);
653                 // Capture audit event
654                 msoLogger.debug ("MSO API Handler Posting call to BPEL engine for url: " + requestClient.getUrl ());
655                 response = requestClient.post (msoRequest.getRequestXML (),
656                         requestId,
657                         Integer.toString (recipe.getRecipeTimeout ()).toString (),
658                         version,
659                         null,
660                         null);
661                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from BPMN engine", "BPMN", orchestrationURI, null);
662             } catch (Exception e) {
663                 msoLogger.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine", "BPMN", orchestrationURI, null);
664                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
665                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
666                         ErrorNumbers.NO_COMMUNICATION_TO_BPEL,
667                         null,
668                         e.getMessage ());
669                 alarmLogger.sendAlarm ("MsoConfigurationError",
670                         MsoAlarmLogger.CRITICAL,
671                         Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_BPEL));
672                 msoRequest.updateFinalStatus (Status.FAILED);
673                 msoLogger.error (MessageEnum.APIH_BPEL_COMMUNICATE_ERROR, "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "Exception while communicate with BPMN engine", e);
674                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with BPMN engine");
675                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
676                 return resp;
677             }
678
679             if (response == null) {
680                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
681                 Response resp = msoRequest.buildResponseWithError (HttpStatus.SC_BAD_GATEWAY,
682                         ErrorNumbers.NO_RESPONSE_FROM_BPEL,
683                         null,
684                         "bpelResponse is null");
685                 msoRequest.updateFinalStatus (Status.FAILED);
686                 msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Null response from BPEL", "Camunda", "", MsoLogger.ErrorCode.DataError, "Null response from BPMN engine");
687                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Null response from BPMN engine");
688                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
689                 return resp;
690             }
691
692             ResponseHandler respHandler = new ResponseHandler (response, requestClient.getType ());
693             int bpelStatus = respHandler.getStatus ();
694
695             // BPEL accepted the request, the request is in progress
696             if (bpelStatus == HttpStatus.SC_ACCEPTED) {
697                 String bpelXMLResponseBody = respHandler.getResponseBody ();
698                 msoLogger.debug ("Received from BPEL: " + bpelXMLResponseBody);
699                 msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.IN_PROGRESS);
700                 requestDB.updateInfraStatus (msoRequest.getRequestId (),
701                         Status.IN_PROGRESS.toString (),
702                         Constants.PROGRESS_REQUEST_IN_PROGRESS,
703                         Constants.MODIFIED_BY_APIHANDLER);
704                 Response resp = msoRequest.buildResponse (bpelStatus, null, null);
705                 msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "BPMN accepted the request, the request is in progress");
706                 msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
707                 return resp;
708             } else {
709
710                 String bpelXMLResponseBody = respHandler.getResponseBody ();
711                 if (bpelXMLResponseBody != null && !bpelXMLResponseBody.isEmpty ()) {
712                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
713                     Response resp = msoRequest.buildResponse (bpelStatus, bpelXMLResponseBody, null);
714                     msoRequest.updateFinalStatus (Status.FAILED);
715                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR,
716                             "Response from BPEL engine is failed with HTTP Status=" + bpelStatus, "Camunda", "", MsoLogger.ErrorCode.DataError, "Response from BPEL engine is failed with HTTP Status=" + bpelStatus);
717                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is with status Failed");
718                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
719                     return resp;
720                 } else {
721                     msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
722                     Response resp = msoRequest.buildResponse (bpelStatus, ErrorNumbers.ERROR_FROM_BPEL, null);
723                     msoRequest.updateFinalStatus (Status.FAILED);
724                     msoLogger.error (MessageEnum.APIH_BPEL_RESPONSE_ERROR, "Response from BPEL engine is empty", "Camunda", "", MsoLogger.ErrorCode.DataError, "Response from BPEL engine is empty");
725                     msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, "Response from BPMN engine is empty");
726                     msoLogger.debug ("End of the transaction, the final response is: " + (String) resp.getEntity ());
727                     return resp;
728                 }
729             }
730
731         } catch (Exception e) {
732             msoLogger.error (MessageEnum.APIH_DB_ACCESS_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception while communciate with Catalog DB", e);
733             msoRequest.setStatus (org.openecomp.mso.apihandlerinfra.volumebeans.RequestStatusType.FAILED);
734             Response response = msoRequest.buildResponseWithError (HttpStatus.SC_NOT_FOUND,
735                                                                    ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB,
736                                                                    null,
737                                                                    e.getMessage ());
738             alarmLogger.sendAlarm ("MsoDatabaseAccessError",
739                                    MsoAlarmLogger.CRITICAL,
740                                    Messages.errors.get (ErrorNumbers.NO_COMMUNICATION_TO_CATALOG_DB));
741             msoRequest.createRequestRecord (Status.FAILED);
742             msoLogger.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DBAccessError, "Exception while communciate with DB");
743             msoLogger.debug ("End of the transaction, the final response is: " + (String) response.getEntity ());
744             return response;
745         }
746
747     }
748 }