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