Some Sonar and CLM issues resolved.
[music.git] / src / main / java / org / onap / music / main / MusicCore.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
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  * 
19  * ============LICENSE_END=============================================
20  * ====================================================================
21  */
22 package org.onap.music.main;
23
24
25 import java.io.StringWriter;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.StringTokenizer;
29
30 import org.onap.music.datastore.MusicDataStore;
31 import org.onap.music.datastore.PreparedQueryObject;
32 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
33 import org.onap.music.eelf.logging.EELFLoggerDelegate;
34 import org.onap.music.exceptions.MusicLockingException;
35 import org.onap.music.exceptions.MusicQueryException;
36 import org.onap.music.exceptions.MusicServiceException;
37 import org.onap.music.lockingservice.MusicLockState;
38 import org.onap.music.lockingservice.MusicLockState.LockStatus;
39 import org.onap.music.lockingservice.MusicLockingService;
40
41 import com.datastax.driver.core.ColumnDefinitions;
42 import com.datastax.driver.core.ColumnDefinitions.Definition;
43 import com.datastax.driver.core.DataType;
44 import com.datastax.driver.core.ResultSet;
45 import com.datastax.driver.core.Row;
46 import com.datastax.driver.core.TableMetadata;
47
48 /**
49  * This class .....
50  * 
51  *
52  */
53 public class MusicCore {
54
55     public static MusicLockingService mLockHandle = null;
56     public static MusicDataStore mDstoreHandle = null;
57     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class);
58
59     public static class Condition {
60         Map<String, Object> conditions;
61         PreparedQueryObject selectQueryForTheRow;
62
63         public Condition(Map<String, Object> conditions, PreparedQueryObject selectQueryForTheRow) {
64             this.conditions = conditions;
65             this.selectQueryForTheRow = selectQueryForTheRow;
66         }
67
68         public boolean testCondition() throws Exception {
69             // first generate the row
70             ResultSet results = quorumGet(selectQueryForTheRow);
71             Row row = results.one();
72             return getDSHandle().doesRowSatisfyCondition(row, conditions);
73         }
74     }
75
76
77     public static MusicLockingService getLockingServiceHandle() throws MusicLockingException {
78         logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
79         long start = System.currentTimeMillis();
80
81         if (mLockHandle == null) {
82             try {
83                 mLockHandle = new MusicLockingService();
84             } catch (Exception e) {
85                 logger.error(EELFLoggerDelegate.errorLogger,"Failed to aquire Locl store handle" + e.getMessage());
86                 throw new MusicLockingException("Failed to aquire Locl store handle " + e);
87             }
88         }
89         long end = System.currentTimeMillis();
90         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
91         return mLockHandle;
92     }
93
94     /**
95      * 
96      * @param remoteIp
97      * @return
98      */
99     public static MusicDataStore getDSHandle(String remoteIp) {
100         logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
101         long start = System.currentTimeMillis();
102         if (mDstoreHandle == null) {
103             mDstoreHandle = new MusicDataStore(remoteIp);
104         }
105         long end = System.currentTimeMillis();
106         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
107         return mDstoreHandle;
108     }
109
110     /**
111      * 
112      * @return
113      * @throws MusicServiceException 
114      */
115     public static MusicDataStore getDSHandle() throws MusicServiceException {
116         logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
117         long start = System.currentTimeMillis();
118         if (mDstoreHandle == null) {
119             mDstoreHandle = new MusicDataStore();
120         }
121         if(mDstoreHandle.getSession() == null) {
122                 String message = "Connection to Cassandra has not been enstablished."
123                                 + " Please check connection properites and reboot.";
124                 logger.info(EELFLoggerDelegate.applicationLogger, message);
125             throw new MusicServiceException(message);
126         }
127         long end = System.currentTimeMillis();
128         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
129         return mDstoreHandle;
130     }
131
132     public static String createLockReference(String lockName) {
133         logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
134         long start = System.currentTimeMillis();
135         String lockId = null;
136         try {
137             lockId = getLockingServiceHandle().createLockId("/" + lockName);
138         } catch (MusicLockingException e) {
139             logger.error(EELFLoggerDelegate.errorLogger,"Failed to create Lock Reference " + lockName);
140         }
141         long end = System.currentTimeMillis();
142         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms");
143         return lockId;
144     }
145
146     /**
147      * 
148      * @param key
149      * @return
150      */
151     public static boolean isTableOrKeySpaceLock(String key) {
152         String[] splitString = key.split("\\.");
153         if (splitString.length > 2)
154             return false;
155         else
156             return true;
157     }
158
159     /**
160      * 
161      * @param key
162      * @return
163      */
164     public static MusicLockState getMusicLockState(String key) {
165         long start = System.currentTimeMillis();
166         try {
167             String[] splitString = key.split("\\.");
168             String keyspaceName = splitString[0];
169             String tableName = splitString[1];
170             String primaryKey = splitString[2];
171             MusicLockState mls;
172             String lockName = keyspaceName + "." + tableName + "." + primaryKey;
173             mls = getLockingServiceHandle().getLockState(lockName);
174             long end = System.currentTimeMillis();
175             logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms");
176             return mls;
177         } catch (NullPointerException | MusicLockingException e) {
178             logger.error(EELFLoggerDelegate.errorLogger,"No lock object exists as of now.." + e);
179         }
180         return null;
181     }
182
183     public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
184         try {
185             long start = System.currentTimeMillis();
186             /* check if the current lock has exceeded its lease and if yes, release that lock */
187             MusicLockState mls = getMusicLockState(key);
188             if (mls != null) {
189                 if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
190                     logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder()
191                                     + ". Checking if it has exceeded lease");
192                     long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
193                     long currentLeasePeriod = mls.getLeasePeriod();
194                     if (currentLockPeriod > currentLeasePeriod) {
195                         logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod
196                                         + " has exceeded lease period " + currentLeasePeriod);
197                         boolean voluntaryRelease = false;
198                         String currentLockHolder = mls.getLockHolder();
199                         mls = releaseLock(currentLockHolder, voluntaryRelease);
200                     }
201                 }
202             } else
203                 logger.debug("There is no lock state object for " + key);
204
205             /*
206              * call the traditional acquire lock now and if the result returned is true, set the
207              * begin time-stamp and lease period
208              */
209             if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) {
210                 mls = getMusicLockState(key);// get latest state
211                 if ( mls == null ) {
212                     logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null");
213                     return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null");                    
214                 }
215                 if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
216                     mls.setLeaseStartTime(System.currentTimeMillis());
217                     mls.setLeasePeriod(leasePeriod);
218                     getLockingServiceHandle().setLockState(key, mls);
219                 }
220                 long end = System.currentTimeMillis();
221                 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms");
222                 return new ReturnType(ResultType.SUCCESS, "Accquired lock");
223             } else {
224                 long end = System.currentTimeMillis();
225                 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms");
226                 return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
227             }
228         } catch (Exception e) {
229             StringWriter sw = new StringWriter();
230             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
231             String exceptionAsString = sw.toString();
232             return new ReturnType(ResultType.FAILURE,
233                             "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
234         }
235     }
236
237     public static ReturnType acquireLock(String key, String lockId) {
238         /*
239          * first check if I am on top. Since ids are not reusable there is no need to check
240          * lockStatus If the status is unlocked, then the above call will automatically return
241          * false.
242          */
243         Boolean result = false;
244         try {
245             result = getLockingServiceHandle().isMyTurn(lockId);
246         } catch (MusicLockingException e2) {
247             logger.error(EELFLoggerDelegate.errorLogger,"Failed to aquireLock lockId " + lockId + " " + e2);
248         }
249         if (!result) {
250             logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock");
251             try {
252                                 if (!getLockingServiceHandle().lockIdExists(lockId)) {
253                                         logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist");
254                                         return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist");
255                                 }
256                         } catch (MusicLockingException e) {
257                                 logger.error(EELFLoggerDelegate.errorLogger,"Failed to check if lockid exists - lockId " + lockId + " " + e);
258                         }
259             logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure");
260             return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock");
261         }
262
263
264         // this is for backward compatibility where locks could also be acquired on just
265         // keyspaces or tables.
266         if (isTableOrKeySpaceLock(key)) {
267             logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
268             return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true");
269         }
270
271         // read the lock name corresponding to the key and if the status is locked or being locked,
272         // then return false
273         MusicLockState currentMls = null;
274         MusicLockState newMls = null;
275         try {
276             currentMls = getMusicLockState(key);
277             String currentLockHolder = currentMls.getLockHolder();
278             if (lockId.equals(currentLockHolder)) {
279                 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!");
280                 return new ReturnType(ResultType.SUCCESS, "You already have the lock!");
281             }
282         } catch (NullPointerException e) {
283             logger.error(EELFLoggerDelegate.errorLogger,"In acquire lock:No one has tried to acquire the lock yet..");
284         }
285
286         // change status to "being locked". This state transition is necessary to ensure syncing
287         // before granting the lock
288         String lockHolder = null;
289         boolean needToSyncQuorum = false;
290         if (currentMls != null)
291             needToSyncQuorum = currentMls.isNeedToSyncQuorum();
292
293
294         newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
295                         needToSyncQuorum);
296         try {
297             getLockingServiceHandle().setLockState(key, newMls);
298         } catch (MusicLockingException e1) {
299             logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + key + " " + e1);
300         }
301         logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked");
302
303         // do syncing if this was a forced lock release
304         if (needToSyncQuorum) {
305             logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!");
306             try {
307               syncQuorum(key);
308             } catch (Exception e) {
309               logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e);
310             }
311         }
312
313         // change status to locked
314         lockHolder = lockId;
315         needToSyncQuorum = false;
316         newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
317         try {
318             getLockingServiceHandle().setLockState(key, newMls);
319         } catch (MusicLockingException e) {
320             logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + key + " " + e);
321         }
322         logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref "
323                         + lockId + " as holder");
324         
325         return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder");
326     }
327
328
329
330     /**
331      * 
332      * @param keyspaceName
333      * @param kspObject
334      * @return
335      * @throws Exception
336      */
337     public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
338         return true;
339     }
340
341
342     private static void syncQuorum(String key) throws Exception {
343         logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
344         String[] splitString = key.split("\\.");
345         String keyspaceName = splitString[0];
346         String tableName = splitString[1];
347         String primaryKeyValue = splitString[2];
348         PreparedQueryObject selectQuery = new PreparedQueryObject();
349         PreparedQueryObject updateQuery = new PreparedQueryObject();
350
351         // get the primary key d
352         TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
353         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
354                                                                            // primary key
355         DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
356         Object cqlFormattedPrimaryKeyValue =
357                         MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
358
359         // get the row of data from a quorum
360         selectQuery.appendQueryString("SELECT *  FROM " + keyspaceName + "." + tableName + " WHERE "
361                         + primaryKeyName + "= ?" + ";");
362         selectQuery.addValue(cqlFormattedPrimaryKeyValue);
363         ResultSet results = null;
364         try {
365             results = getDSHandle().executeCriticalGet(selectQuery);
366             // write it back to a quorum
367             Row row = results.one();
368             ColumnDefinitions colInfo = row.getColumnDefinitions();
369             int totalColumns = colInfo.size();
370             int counter = 1;
371             StringBuilder fieldValueString = new StringBuilder("");
372             for (Definition definition : colInfo) {
373                 String colName = definition.getName();
374                 if (colName.equals(primaryKeyName))
375                     continue;
376                 DataType colType = definition.getType();
377                 Object valueObj = getDSHandle().getColValue(row, colName, colType);
378                 Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
379                 fieldValueString.append(colName + " = ?");
380                 updateQuery.addValue(valueString);
381                 if (counter != (totalColumns - 1))
382                     fieldValueString.append(",");
383                 counter = counter + 1;
384             }
385             updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
386                             + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
387             updateQuery.addValue(cqlFormattedPrimaryKeyValue);
388
389             getDSHandle().executePut(updateQuery, "critical");
390         } catch (MusicServiceException | MusicQueryException e) {
391             logger.error(EELFLoggerDelegate.errorLogger,"Failed to execute update query " + updateQuery + " " + e);
392         }
393     }
394
395
396
397
398     /**
399      * 
400      * @param query
401      * @return ResultSet
402      */
403     public static ResultSet quorumGet(PreparedQueryObject query) {
404         ResultSet results = null;
405         try {
406             results = getDSHandle().executeCriticalGet(query);
407         } catch (MusicServiceException | MusicQueryException e) {
408             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
409         }
410         return results;
411
412     }
413
414     /**
415      * 
416      * @param results
417      * @return
418      * @throws MusicServiceException 
419      */
420     public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException {
421         return getDSHandle().marshalData(results);
422     }
423
424     /**
425      * 
426      * @param lockName
427      * @return
428      */
429     public static String whoseTurnIsIt(String lockName) {
430
431         try {
432             return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
433         } catch (MusicLockingException e) {
434             logger.error(EELFLoggerDelegate.errorLogger,"Failed whoseTurnIsIt  " + lockName + " " + e);
435         }
436         return null;
437
438
439     }
440
441     /**
442      * 
443      * @param lockId
444      * @return
445      */
446     public static String getLockNameFromId(String lockId) {
447         StringTokenizer st = new StringTokenizer(lockId);
448         return st.nextToken("$");
449     }
450
451     public static void destroyLockRef(String lockId) {
452         long start = System.currentTimeMillis();
453         try {
454             getLockingServiceHandle().unlockAndDeleteId(lockId);
455         } catch (MusicLockingException e) {
456             logger.error(EELFLoggerDelegate.errorLogger,"Failed to Destroy Lock Ref  " + lockId + " " + e);
457         }
458         long end = System.currentTimeMillis();
459         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
460     }
461
462     public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
463         long start = System.currentTimeMillis();
464         try {
465             getLockingServiceHandle().unlockAndDeleteId(lockId);
466         } catch (MusicLockingException e1) {
467             logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockId + " " + e1);
468         }
469         String lockName = getLockNameFromId(lockId);
470         MusicLockState mls;
471         String lockHolder = null;
472         if (voluntaryRelease) {
473             mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
474             logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId);
475         } else {
476             boolean needToSyncQuorum = true;
477             mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
478                             needToSyncQuorum);
479             logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId);
480         }
481         try {
482             getLockingServiceHandle().setLockState(lockName, mls);
483         } catch (MusicLockingException e) {
484             logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockName + " " + e);
485         }
486         long end = System.currentTimeMillis();
487         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms");
488         return mls;
489     }
490     
491     public static  void  voluntaryReleaseLock(String lockId) throws MusicLockingException{
492                 getLockingServiceHandle().unlockAndDeleteId(lockId);
493         }
494
495     /**
496      * 
497      * @param lockName
498      */
499     public static void deleteLock(String lockName) {
500         long start = System.currentTimeMillis();
501         logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName);
502         try {
503             getLockingServiceHandle().deleteLock("/" + lockName);
504         } catch (MusicLockingException e) {
505             logger.error(EELFLoggerDelegate.errorLogger,"Failed to Delete Lock " + lockName + " " + e);
506         }
507         long end = System.currentTimeMillis();
508         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms");
509     }
510
511
512
513     /**
514      * 
515      * @param keyspace
516      * @param tablename
517      * @return
518      * @throws MusicServiceException 
519      */
520     public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException {
521         return getDSHandle().returnColumnMetadata(keyspace, tablename);
522     }
523
524
525     /**
526      * 
527      * @param nodeName
528      */
529     public static void pureZkCreate(String nodeName) {
530         try {
531             getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
532         } catch (MusicLockingException e) {
533             logger.error(EELFLoggerDelegate.errorLogger,"Failed to get ZK Lock Handle " + e);
534         }
535     }
536
537     /**
538      * 
539      * @param nodeName
540      * @param data
541      */
542     public static void pureZkWrite(String nodeName, byte[] data) {
543         long start = System.currentTimeMillis();
544         logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName);
545         try {
546             getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
547         } catch (MusicLockingException e) {
548             logger.error(EELFLoggerDelegate.errorLogger,"Failed to get ZK Lock Handle " + e);
549         }
550         logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName);
551         long end = System.currentTimeMillis();
552         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
553     }
554
555     /**
556      * 
557      * @param nodeName
558      * @return
559      */
560     public static byte[] pureZkRead(String nodeName) {
561         long start = System.currentTimeMillis();
562         byte[] data = null;
563         try {
564             data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
565         } catch (MusicLockingException e) {
566             logger.error(EELFLoggerDelegate.errorLogger,"Failed to get ZK Lock Handle " + e);
567         }
568         long end = System.currentTimeMillis();
569         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
570         return data;
571     }
572
573
574
575     // Prepared Query Additions.
576
577     /**
578      * 
579      * @param keyspaceName
580      * @param tableName
581      * @param primaryKey
582      * @param queryObject
583      * @return ReturnType
584      * @throws MusicServiceException
585      */
586     public static ReturnType eventualPut(PreparedQueryObject queryObject) {
587         boolean result = false;
588         try {
589             result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
590         } catch (MusicServiceException | MusicQueryException ex) {
591             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + "  " + ex.getCause() + " " + ex);
592         }
593         if (result) {
594             return new ReturnType(ResultType.SUCCESS, "Success");
595         } else {
596             return new ReturnType(ResultType.FAILURE, "Failure");
597         }
598     }
599
600     /**
601      * 
602      * @param keyspaceName
603      * @param tableName
604      * @param primaryKey
605      * @param queryObject
606      * @param lockId
607      * @return
608      */
609     public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
610                     PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
611         long start = System.currentTimeMillis();
612
613         try {
614             MusicLockState mls = getLockingServiceHandle()
615                             .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
616             if (mls.getLockHolder().equals(lockId) == true) {
617                 if (conditionInfo != null)
618                   try {
619                     if (conditionInfo.testCondition() == false)
620                         return new ReturnType(ResultType.FAILURE,
621                                         "Lock acquired but the condition is not true");
622                   } catch (Exception e) {
623                     return new ReturnType(ResultType.FAILURE,
624                             "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
625                                             + e.getMessage());
626                   }
627                 getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
628                 long end = System.currentTimeMillis();
629                 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
630                 return new ReturnType(ResultType.SUCCESS, "Update performed");
631             } else
632                 return new ReturnType(ResultType.FAILURE,
633                                 "Cannot perform operation since you are the not the lock holder");
634         } catch (MusicQueryException | MusicServiceException  e) {
635             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
636             return new ReturnType(ResultType.FAILURE,
637                             "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
638                                             + e.getMessage());
639         }catch(MusicLockingException ex){
640             return new ReturnType(ResultType.FAILURE,ex.getMessage());
641         }
642
643     }
644
645     /**
646      * 
647      * @param queryObject
648      * @param consistency
649      * @return Boolean Indicates success or failure
650      * @throws MusicServiceException 
651      * 
652      * 
653      */
654     public static boolean nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException {
655         // this is mainly for some functions like keyspace creation etc which does not
656         // really need the bells and whistles of Music locking.
657         boolean result = false;
658         try {
659             result = getDSHandle().executePut(queryObject, consistency);
660         } catch (MusicQueryException | MusicServiceException ex) {
661             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage());
662             throw new MusicServiceException(ex.getMessage());
663         }
664         return result;
665     }
666
667     /**
668      * This method performs DDL operation on cassandra.
669      * 
670      * @param queryObject query object containing prepared query and values
671      * @return ResultSet
672      * @throws MusicServiceException 
673      */
674     public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
675         ResultSet results = null;
676         try {
677                         results = getDSHandle().executeEventualGet(queryObject);
678         } catch (MusicQueryException | MusicServiceException e) {
679             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
680             throw new MusicServiceException(e.getMessage());
681         }
682         return results;
683     }
684
685     /**
686      * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
687      * is used to check if the resource is free.
688      * 
689      * @param keyspaceName name of the keyspace
690      * @param tableName name of the table
691      * @param primaryKey primary key value
692      * @param queryObject query object containing prepared query and values
693      * @param lockId lock ID to check if the resource is free to perform the operation.
694      * @return ResultSet
695      */
696     public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
697                     PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
698         ResultSet results = null;
699         try {
700             MusicLockState mls = getLockingServiceHandle()
701                             .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
702             if (mls.getLockHolder().equals(lockId)) {
703                 results = getDSHandle().executeCriticalGet(queryObject);
704             } else
705                 throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
706         } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
707             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
708         }
709         return results;
710     }
711
712     /**
713      * This method performs DML operation on cassandra, when the lock of the dd is acquired.
714      * 
715      * @param keyspaceName name of the keyspace
716      * @param tableName name of the table
717      * @param primaryKey primary key value
718      * @param queryObject query object containing prepared query and values
719      * @return ReturnType
720      * @throws MusicLockingException 
721      */
722     public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
723                     PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
724
725         long start = System.currentTimeMillis();
726         String key = keyspaceName + "." + tableName + "." + primaryKey;
727         String lockId = createLockReference(key);
728         long lockCreationTime = System.currentTimeMillis();
729         ReturnType lockAcqResult = acquireLock(key, lockId);
730         long lockAcqTime = System.currentTimeMillis();
731         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
732             logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
733             ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
734                             queryObject, lockId, conditionInfo);
735             long criticalPutTime = System.currentTimeMillis();
736             voluntaryReleaseLock(lockId);
737             long lockDeleteTime = System.currentTimeMillis();
738             String timingInfo = "|lock creation time:" + (lockCreationTime - start)
739                             + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
740                             + "|critical put time:" + (criticalPutTime - lockAcqTime)
741                             + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
742             criticalPutResult.setTimingInfo(timingInfo);
743             return criticalPutResult;
744         } else {
745             logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
746             destroyLockRef(lockId);
747             return lockAcqResult;
748         }
749     }
750     
751     /**
752      * this function is mainly for the benchmarks to see the effect of lock deletion.
753      * 
754      * @param keyspaceName
755      * @param tableName
756      * @param primaryKey
757      * @param queryObject
758      * @param conditionInfo
759      * @return
760      * @throws MusicLockingException 
761      */
762     public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
763                     String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
764
765         long start = System.currentTimeMillis();
766         String key = keyspaceName + "." + tableName + "." + primaryKey;
767         String lockId = createLockReference(key);
768         long lockCreationTime = System.currentTimeMillis();
769         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
770         ReturnType lockAcqResult = acquireLock(key, lockId);
771         long lockAcqTime = System.currentTimeMillis();
772         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
773             logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
774             ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
775                             queryObject, lockId, conditionInfo);
776             long criticalPutTime = System.currentTimeMillis();
777             deleteLock(key);
778             long lockDeleteTime = System.currentTimeMillis();
779             String timingInfo = "|lock creation time:" + (lockCreationTime - start)
780                             + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
781                             + "|critical put time:" + (criticalPutTime - lockAcqTime)
782                             + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
783             criticalPutResult.setTimingInfo(timingInfo);
784             return criticalPutResult;
785         } else {
786             logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
787             deleteLock(key);
788             return lockAcqResult;
789         }
790     }
791     
792
793
794
795     /**
796      * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
797      * 
798      * @param keyspaceName name of the keyspace
799      * @param tableName name of the table
800      * @param primaryKey primary key value
801      * @param queryObject query object containing prepared query and values
802      * @return ResultSet
803      * @throws MusicServiceException
804      * @throws MusicLockingException 
805      */
806     public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
807                     PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
808         String key = keyspaceName + "." + tableName + "." + primaryKey;
809         String lockId = createLockReference(key);
810         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
811         ReturnType lockAcqResult = acquireLock(key, lockId);
812         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
813             logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
814             ResultSet result =
815                             criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
816             voluntaryReleaseLock(lockId);
817             return result;
818         } else {
819                 destroyLockRef(lockId);
820             logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
821             return null;
822         }
823     }
824     
825         public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
826                         PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
827                 String key = keyspaceName + "." + tableName + "." + primaryKey;
828                 String lockId = createLockReference(key);
829                 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
830
831                 ReturnType lockAcqResult = acquireLock(key, lockId);
832
833                 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
834                         logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
835                         ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
836                         deleteLock(key);
837                         return result;
838                 } else {
839                         deleteLock(key);
840                         logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
841                         return null;
842                 }
843         }
844     
845     
846
847     /**
848      * authenticate user logic
849      * 
850      * @param nameSpace
851      * @param userId
852      * @param password
853      * @param keyspace
854      * @param aid
855      * @param operation
856      * @return
857      * @throws Exception
858      */
859     public static Map<String, Object> autheticateUser(String nameSpace, String userId,
860                     String password, String keyspace, String aid, String operation)
861                     throws Exception {
862         Map<String, Object> resultMap = new HashMap<>();
863         String uuid = null;
864         resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
865                         operation);
866         if (!resultMap.isEmpty())
867             return resultMap;
868         boolean isAAF = CachingUtil.isAAFApplication(nameSpace);
869         if (!isAAF && !(operation.equals("createKeySpace"))) {
870                 if(aid == null) {
871                         resultMap.put("Exception", "Aid is mandatory for nonAAF applications ");
872                         return resultMap;
873                 }
874                 if(operation.contains("Lock")) {
875                         resultMap = CachingUtil.authenticateAIDUserLock(aid, nameSpace);
876                 }
877                 else {
878                         resultMap = CachingUtil.authenticateAIDUser(aid, keyspace);
879                 }
880             
881             if (!resultMap.isEmpty())
882                 return resultMap;
883         }
884         if (aid == null && (userId == null || password == null)) {
885             logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
886                             + " :: password: " + password);
887             resultMap.put("Exception",
888                             "UserId and Password are mandatory for the operation " + operation);
889             return resultMap;
890         }
891         
892         if (isAAF && nameSpace != null && userId != null && password != null) {
893             boolean isValid = true;
894             try {
895                  isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
896             } catch (Exception e) {
897                 logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
898                 resultMap.put("Exception", e.getMessage());
899             }
900             if (!isValid) {
901                 logger.error(EELFLoggerDelegate.errorLogger,"User not authenticated with AAF.");
902                 resultMap.put("Exception", "User not authenticated...");
903             }
904             if (!resultMap.isEmpty())
905                 return resultMap;
906
907         }
908
909         if (operation.equals("createKeySpace")) {
910             logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
911             PreparedQueryObject pQuery = new PreparedQueryObject();
912             pQuery.appendQueryString(
913                             "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
914             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
915             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
916             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
917                             MusicUtil.DEFAULTKEYSPACENAME));
918
919             try {
920                 Row rs = MusicCore.get(pQuery).one();
921                 uuid = rs.getUUID("uuid").toString();
922                 resultMap.put("uuid", "existing");
923             } catch (Exception e) {
924                 logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
925                 uuid = CachingUtil.generateUUID();
926                 resultMap.put("uuid", "new");
927             }
928
929             pQuery = new PreparedQueryObject();
930             pQuery.appendQueryString(
931                             "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
932                                             + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
933             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
934             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
935             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
936             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
937             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
938             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
939             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
940             CachingUtil.updateMusicCache(uuid, keyspace);
941             MusicCore.eventualPut(pQuery);
942             resultMap.put("aid", uuid);
943         }
944
945         return resultMap;
946     }
947 }