d29ba32b4082c81547b95d1f9630fa4d04df591b
[music.git] / music-core / src / main / java / org / onap / music / service / impl / MusicCassaCore.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
6  *  Modifications Copyright (c) 2018 IBM. 
7  * ===================================================================
8  *  Modifications Copyright (c) 2019 Samsung
9  * ===================================================================
10  *  Licensed under the Apache License, Version 2.0 (the "License");
11  *  you may not use this file except in compliance with the License.
12  *  You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *  Unless required by applicable law or agreed to in writing, software
17  *  distributed under the License is distributed on an "AS IS" BASIS,
18  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  *  See the License for the specific language governing permissions and
20  *  limitations under the License.
21  *
22  * ============LICENSE_END=============================================
23  * ====================================================================
24  */
25
26 package org.onap.music.service.impl;
27
28 import java.io.StringWriter;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.StringTokenizer;
36 import java.util.concurrent.atomic.AtomicInteger;
37 import javax.ws.rs.core.MultivaluedMap;
38
39 import org.onap.music.datastore.Condition;
40 import org.onap.music.datastore.MusicDataStore;
41 import org.onap.music.datastore.MusicDataStoreHandle;
42 import org.onap.music.datastore.PreparedQueryObject;
43 import org.onap.music.datastore.jsonobjects.JsonDelete;
44 import org.onap.music.datastore.jsonobjects.JsonIndex;
45 import org.onap.music.datastore.jsonobjects.JsonInsert;
46 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
47 import org.onap.music.datastore.jsonobjects.JsonSelect;
48 import org.onap.music.datastore.jsonobjects.JsonTable;
49 import org.onap.music.datastore.jsonobjects.JsonUpdate;
50 import org.onap.music.eelf.logging.EELFLoggerDelegate;
51 import org.onap.music.eelf.logging.format.AppMessages;
52 import org.onap.music.eelf.logging.format.ErrorSeverity;
53 import org.onap.music.eelf.logging.format.ErrorTypes;
54 import org.onap.music.exceptions.MusicDeadlockException;
55 import org.onap.music.exceptions.MusicLockingException;
56 import org.onap.music.exceptions.MusicQueryException;
57 import org.onap.music.exceptions.MusicServiceException;
58 import org.onap.music.lockingservice.cassandra.CassaLockStore;
59 import org.onap.music.lockingservice.cassandra.CassaLockStore.LockObject;
60 import org.onap.music.lockingservice.cassandra.LockType;
61 import org.onap.music.lockingservice.cassandra.MusicLockState;
62 import org.onap.music.lockingservice.cassandra.MusicLockState.LockStatus;
63 import org.onap.music.main.MusicUtil;
64 import org.onap.music.main.ResultType;
65 import org.onap.music.main.ReturnType;
66 import org.onap.music.service.MusicCoreService;
67
68 import com.datastax.driver.core.DataType;
69 import com.datastax.driver.core.ResultSet;
70 import com.datastax.driver.core.Row;
71 import com.datastax.driver.core.TableMetadata;
72
73 public class MusicCassaCore implements MusicCoreService {
74
75     private static CassaLockStore mLockHandle = null;
76     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCassaCore.class);
77     private static MusicCassaCore musicCassaCoreInstance = null;
78     private static Set<String> set = Collections.synchronizedSet(new HashSet<String>());
79     HashMap<String, Integer> map = new HashMap<>();
80     AtomicInteger wait = new AtomicInteger(0);
81     
82     private MusicCassaCore() {
83         // not going to happen
84     }
85     
86     public static CassaLockStore getmLockHandle() {
87         return mLockHandle;
88     }
89
90     //for unit testing purposes
91     static void setmLockHandle(CassaLockStore mLockHandle) {
92         MusicCassaCore.mLockHandle = mLockHandle;
93     }
94     
95     public static MusicCassaCore getInstance() {
96
97         if(musicCassaCoreInstance == null) {
98             musicCassaCoreInstance = new MusicCassaCore();
99         }
100         return musicCassaCoreInstance;
101     }
102
103     public static CassaLockStore getLockingServiceHandle() throws MusicLockingException {
104         logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
105         long start = System.currentTimeMillis();
106
107         if (mLockHandle == null) {
108             try {
109                 mLockHandle = new CassaLockStore(MusicDataStoreHandle.getDSHandle());
110             } catch (Exception e) {
111                 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
112                 throw new MusicLockingException("Failed to aquire Locl store handle " + e);
113             }
114         }
115         long end = System.currentTimeMillis();
116         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
117         return mLockHandle;
118     }
119
120     public String createLockReferenceAtomic(String fullyQualifiedKey) throws MusicLockingException {
121         return createLockReferenceAtomic(fullyQualifiedKey, LockType.WRITE);
122     }
123     public String createLockReference(String fullyQualifiedKey, String owner) throws MusicLockingException {
124         return createLockReference(fullyQualifiedKey, LockType.WRITE, owner);
125     }
126     
127     
128     /**
129      * This will be called for Atomic calls
130      * it ensures that only one thread tries to create a lock on each key at a time
131      */
132     public String createLockReferenceAtomic(String fullyQualifiedKey, LockType locktype) throws MusicLockingException {
133         String[] splitString = fullyQualifiedKey.split("\\.");
134         if (splitString.length < 3) {
135             throw new MusicLockingException("Missing or incorrect lock details. Check table or key name.");
136         }
137         String keyspace = splitString[0];
138         String table = splitString[1];
139         String lockName = splitString[2];
140
141         logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
142         long start = 0L;
143         long end = 0L;
144         String lockReference = null;
145         LockObject peek = null;
146
147         /** Lets check for an existing lock. 
148          * This will allow us to limit the amount of requests going forward.
149          */
150         start = System.currentTimeMillis();
151         try {
152             peek = getLockingServiceHandle().peekLockQueue(keyspace, table, lockName);
153         } catch (MusicServiceException | MusicQueryException e) {
154             //logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(),e);
155             throw new MusicLockingException("Error getting lockholder info for key [" + lockName +"]:" + e.getMessage());
156         }
157         
158         if(peek!=null && (peek.getLocktype()!=null && peek.getLocktype().equals(LockType.WRITE)) && peek.getAcquireTime()!=null && peek.getLockRef()!=null) {
159             long currentTime = System.currentTimeMillis();
160             if((currentTime-Long.parseLong(peek.getAcquireTime()))<MusicUtil.getDefaultLockLeasePeriod()){
161                 //logger.info(EELFLoggerDelegate.applicationLogger,"Lock holder exists and lease not expired. Please try again for key="+lockName);
162                 throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again.");
163             }
164         }
165         end = System.currentTimeMillis();
166         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for lock reference for key [" + lockName + "]:" + (end - start) + " ms");
167
168         start = System.currentTimeMillis();
169         /* We are Creating a Thread safe set and adding the key to the set. 
170         * if a key exists then it wil be passed over and not go to the lock creation. 
171         * If a key doesn't exist then it will set the value in the set and continue to create a lock. 
172         *
173         * This will ensure that no 2 threads using the same key will be able to try to create a lock
174         * This wil in turn squash the amout of LWT Chatter in Cassandra an reduce the amount of
175         * WriteTimeoutExceptions being experiences on single keys.
176         */
177         if ( set.add(fullyQualifiedKey)) {
178             try {
179                 lockReference = "" + getLockingServiceHandle().genLockRefandEnQueue(keyspace, table, lockName, locktype,null);
180                 set.remove(fullyQualifiedKey);
181             } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
182                 set.remove(fullyQualifiedKey);
183                 throw new MusicLockingException(e.getMessage());
184             } catch (Exception e) {
185                 set.remove(fullyQualifiedKey);
186                 e.printStackTrace();
187                 logger.error(EELFLoggerDelegate.applicationLogger,"Exception in creatLockEnforced:"+ e.getMessage(),e);
188                 throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. " + e.getMessage());
189             }
190         } else {
191             throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again.");
192         }
193         end = System.currentTimeMillis();
194         logger.info(EELFLoggerDelegate.debugLogger,"### Set = " + set);
195         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference  for key [" + lockName + "]:" + (end - start) + " ms");
196         return lockReference;
197
198         //return createLockReference(fullyQualifiedKey, locktype, null);
199     }
200
201     public String createLockReference(String fullyQualifiedKey, LockType locktype, String owner) throws MusicLockingException {
202         String[] splitString = fullyQualifiedKey.split("\\.");
203         if (splitString.length < 3) {
204             throw new MusicLockingException("Missing or incorrect lock details. Check table or key name.");
205         }
206         String keyspace = splitString[0];
207         String table = splitString[1];
208         String lockName = splitString[2];
209
210         logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
211         long start = 0L;
212         long end = 0L;
213         String lockReference = null;
214
215         /* Check for a Deadlock */
216         try {
217             boolean deadlock = getLockingServiceHandle().checkForDeadlock(keyspace, table, lockName, locktype, owner, false);
218             if (deadlock) {
219                 MusicDeadlockException e = new MusicDeadlockException("Deadlock detected when " + owner + " tried to create lock on " + keyspace + "." + table + "." + lockName);
220                 e.setValues(owner, keyspace, table, lockName);
221                 throw e;
222             }
223         } catch (MusicDeadlockException e) {
224             //just threw this, no need to wrap it
225             throw e;
226         } catch (MusicServiceException | MusicQueryException e) {
227             logger.error(EELFLoggerDelegate.applicationLogger, e);
228             throw new MusicLockingException("Unable to check for deadlock. " + e.getMessage(), e);
229         }
230         end = System.currentTimeMillis();
231         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for deadlock for key [" + lockName + "]:" + (end - start) + " ms");
232
233         start = System.currentTimeMillis();
234         try {
235             lockReference = "" + getLockingServiceHandle().genLockRefandEnQueue(keyspace, table, lockName, locktype, owner);
236         } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
237             logger.info(EELFLoggerDelegate.applicationLogger,e.getMessage(),e);
238             throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again: " + e.getMessage());
239         } catch (Exception e) {
240             logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage(),e);
241             throw new MusicLockingException("Unable to create lock reference. " + e.getMessage(), e);
242         }
243         end = System.currentTimeMillis();
244         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference  for key [" + lockName + "]:" + (end - start) + " ms");
245         return lockReference;
246     }
247     
248     public ReturnType promoteLock(String lockId) throws MusicLockingException {
249         String[] splitString = lockId.split("\\.");
250         String keyspace = splitString[0].substring(1);//remove '$'
251         String table = splitString[1];
252         String primaryKeyValue = splitString[2].substring(0, splitString[2].lastIndexOf("$"));
253         String lockRef = lockId.substring(lockId.lastIndexOf("$")+1); //lockRef is "$" to end
254         
255         logger.info(EELFLoggerDelegate.applicationLogger,"Attempting to promote lock " + lockId);
256
257         try {
258             return getLockingServiceHandle().promoteLock(keyspace, table, primaryKeyValue, lockRef);
259         } catch (MusicServiceException e) {
260             throw new MusicLockingException("Unable to promote lock. ", e);
261         } catch (MusicQueryException e) {
262             throw new MusicLockingException("Unable to promote lock. ", e);
263         }
264         
265     }
266
267
268     public ReturnType acquireLockWithLease(String fullyQualifiedKey, String lockReference, long leasePeriod)
269             throws MusicLockingException, MusicQueryException, MusicServiceException  {
270         evictExpiredLockHolder(fullyQualifiedKey,leasePeriod);
271         return acquireLock(fullyQualifiedKey, lockReference);
272     }
273
274     private void evictExpiredLockHolder(String fullyQualifiedKey, long leasePeriod)
275             throws MusicLockingException, MusicQueryException, MusicServiceException {
276         String[] splitString = fullyQualifiedKey.split("\\.");
277         String keyspace = splitString[0];
278         String table = splitString[1];
279         String primaryKeyValue = splitString[2];
280
281         LockObject currentLockHolderObject = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
282
283         if (!currentLockHolderObject.getIsLockOwner()) { // no lock holder
284             return;
285         }
286         /*
287          * Release the lock of the previous holder if it has expired. if the update to the acquire time has
288          * not reached due to network delays, simply use the create time as the reference
289          */
290         long referenceTime = Math.max(Long.parseLong(currentLockHolderObject.getAcquireTime()),
291                 Long.parseLong(currentLockHolderObject.getCreateTime()));
292         if ((System.currentTimeMillis() - referenceTime) > leasePeriod) {
293             forciblyReleaseLock(fullyQualifiedKey, currentLockHolderObject.getLockRef() + "");
294             logger.info(EELFLoggerDelegate.applicationLogger, currentLockHolderObject.getLockRef() + " forcibly released");
295         }
296     }
297
298     public ReturnType acquireLock(String fullyQualifiedKey, String lockId)
299             throws MusicLockingException, MusicQueryException, MusicServiceException {
300         String[] splitString = lockId.split("\\.");
301         String keyspace = splitString[0].substring(1);//remove '$'
302         String table = splitString[1];
303         String primaryKeyValue = splitString[2].substring(0, splitString[2].lastIndexOf("$"));
304         String localFullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$"));
305         String lockRef = lockId.substring(lockId.lastIndexOf("$")+1); //lockRef is "$" to end
306
307         LockObject lockInfo = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue, lockRef);
308
309         if (!lockInfo.getIsLockOwner()) {
310             return new ReturnType(ResultType.FAILURE, lockId + " is not a lock holder");//not top of the lock store q
311         }
312         
313         if (getLockingServiceHandle().checkForDeadlock(keyspace, table, primaryKeyValue, lockInfo.getLocktype(), lockInfo.getOwner(), true)) {
314             MusicDeadlockException e = new MusicDeadlockException("Deadlock detected when " + lockInfo.getOwner()  + " tried to create lock on " + keyspace + "." + table + "." + primaryKeyValue);
315             e.setValues(lockInfo.getOwner(), keyspace, table, primaryKeyValue);
316             throw e;
317         }
318
319         //check to see if the value of the key has to be synced in case there was a forceful release
320         String syncTable = keyspace+".unsyncedKeys_"+table;
321         String query = "select * from "+syncTable+" where key='"+localFullyQualifiedKey+"';";
322         PreparedQueryObject readQueryObject = new PreparedQueryObject();
323         readQueryObject.appendQueryString(query);
324         ResultSet results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(readQueryObject);
325         if (!results.all().isEmpty()) {
326             logger.info("In acquire lock: Since there was a forcible release, need to sync quorum!");
327             try {
328                 syncQuorum(keyspace, table, primaryKeyValue);
329             } catch (Exception e) {
330                 StringWriter sw = new StringWriter();
331                     logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",
332                         ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e);
333                 String exceptionAsString = sw.toString();
334                 return new ReturnType(ResultType.FAILURE, "Exception thrown while syncing key:\n" + exceptionAsString);
335             }
336             String cleanQuery = "delete from " + syncTable + " where key='"+localFullyQualifiedKey+"';";
337             PreparedQueryObject deleteQueryObject = new PreparedQueryObject();
338             deleteQueryObject.appendQueryString(cleanQuery);
339             MusicDataStoreHandle.getDSHandle().executePut(deleteQueryObject, "critical");
340         }
341
342         getLockingServiceHandle().updateLockAcquireTime(keyspace, table, primaryKeyValue, lockRef);
343
344         return new ReturnType(ResultType.SUCCESS, lockRef+" is the lock holder for the key");
345     }
346
347
348
349     /**
350      *
351      * @param tableQueryObject
352      * @param consistency
353      * @return Boolean Indicates success or failure
354      * @throws MusicServiceException
355      *
356      */
357     public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject,
358             String consistency) throws MusicServiceException {
359         boolean result = false;
360
361         try {
362             // create shadow locking table
363             result = getLockingServiceHandle().createLockQueue(keyspace, table);
364             if (result == false) {
365                 return ResultType.FAILURE;
366             }
367             result = false;
368
369             // create table to track unsynced_keys
370             table = "unsyncedKeys_" + table;
371
372             String tabQuery =
373                     "CREATE TABLE IF NOT EXISTS " + keyspace + "." + table + " ( key text,PRIMARY KEY (key) );";
374             PreparedQueryObject queryObject = new PreparedQueryObject();
375
376             queryObject.appendQueryString(tabQuery);
377             result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual");
378             if (result == false) {
379                 return ResultType.FAILURE;
380             }
381             result = false;
382
383             // create actual table
384             result = MusicDataStoreHandle.getDSHandle().executePut(tableQueryObject, consistency);
385         } catch (MusicQueryException | MusicServiceException | MusicLockingException ex) {
386             logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.WARN,
387                     ErrorTypes.MUSICSERVICEERROR);
388             throw new MusicServiceException(ex.getMessage());
389         }
390         return result ? ResultType.SUCCESS : ResultType.FAILURE;
391     }
392
393     private static void syncQuorum(String keyspace, String table, String primaryKeyValue) throws Exception {
394         logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
395         PreparedQueryObject selectQuery = new PreparedQueryObject();
396         PreparedQueryObject updateQuery = new PreparedQueryObject();
397
398         // get the primary key d
399         TableMetadata tableInfo = MusicDataStoreHandle.returnColumnMetadata(keyspace, table);
400         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName(); // we only support single
401                                                                             // primary key
402         DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
403         Object cqlFormattedPrimaryKeyValue =
404                         MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
405
406         // get the row of data from a quorum
407         selectQuery.appendQueryString("SELECT *  FROM " + keyspace + "." + table + " WHERE "
408                         + primaryKeyName + "= ?" + ";");
409         selectQuery.addValue(cqlFormattedPrimaryKeyValue);
410         MusicUtil.writeBackToQuorum(selectQuery, primaryKeyName, updateQuery, keyspace, table,
411             cqlFormattedPrimaryKeyValue);
412     }
413
414     /**
415      *
416      * @param query
417      * @return ResultSet
418      */
419     public ResultSet quorumGet(PreparedQueryObject query) {
420         ResultSet results = null;
421         try {
422             results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(query);
423         } catch (MusicServiceException | MusicQueryException e) {
424             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR,
425                 ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR, e);
426
427         }
428         return results;
429     }
430
431     public String whoseTurnIsIt(String fullyQualifiedKey) {
432         String[] splitString = fullyQualifiedKey.split("\\.");
433         String keyspace = splitString[0];
434         String table = splitString[1];
435         String primaryKeyValue = splitString[2];
436         try {
437             LockObject lockOwner = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
438             if (!lockOwner.getIsLockOwner()) {
439                 return null;
440             }
441             return "$" + fullyQualifiedKey + "$" + lockOwner.getLockRef();
442         } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
443             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.LOCKINGERROR + fullyQualifiedKey,
444                     ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
445         }
446         return null;
447     }
448     
449     public List<String> getCurrentLockHolders(String fullyQualifiedKey) {
450         String[] splitString = fullyQualifiedKey.split("\\.");
451         String keyspace = splitString[0];
452         String table = splitString[1];
453         String primaryKeyValue = splitString[2];
454         try {
455             return getLockingServiceHandle().getCurrentLockHolders(keyspace, table, primaryKeyValue);
456         } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
457             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+fullyQualifiedKey ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
458         }
459         return null;
460     }
461
462     /**
463      *
464      * @param lockReference
465      * @return
466      */
467     public static String getLockNameFromId(String lockReference) {
468         StringTokenizer st = new StringTokenizer(lockReference);
469         return st.nextToken("$");
470     }
471
472     @Override
473     public void destroyLockRef(String lockId) throws MusicLockingException {
474         long start = System.currentTimeMillis();
475         String fullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$"));
476         String lockRef = lockId.substring(lockId.lastIndexOf('$')+1);
477         String[] splitString = fullyQualifiedKey.split("\\.");
478         String keyspace = splitString[0];
479         String table = splitString[1];
480         String primaryKeyValue = splitString[2];
481         try {
482             getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockRef,MusicUtil.getRetryCount());
483         } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
484             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockRef,
485                 ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR, e);
486             throw new MusicLockingException(e.getMessage());
487         }
488         long end = System.currentTimeMillis();
489         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
490     }
491
492     public MusicLockState destroyLockRef(String fullyQualifiedKey, String lockReference) throws MusicLockingException {
493         long start = System.currentTimeMillis();
494         String[] splitString = fullyQualifiedKey.split("\\.");
495         String keyspace = splitString[0];
496         String table = splitString[1];
497         String primaryKeyValue = splitString[2];
498         try {
499             getLockingServiceHandle().deQueueLockRef(keyspace, table, primaryKeyValue, lockReference,MusicUtil.getRetryCount());
500         } catch (MusicLockingException | MusicServiceException | MusicQueryException e) {
501             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK + lockReference,
502                 ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR,e);
503             throw new MusicLockingException(e.getMessage());
504         }
505         long end = System.currentTimeMillis();
506         logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
507         return new MusicLockState(LockStatus.UNLOCKED, "");
508     }
509
510     @Override
511     public MusicLockState releaseLock(String lockId, boolean voluntaryRelease) throws MusicLockingException {
512         String fullyQualifiedKey = lockId.substring(1, lockId.lastIndexOf("$"));
513         String lockRef = lockId.substring(lockId.lastIndexOf('$')+1);
514         if (voluntaryRelease) {
515             return voluntaryReleaseLock(fullyQualifiedKey, lockRef);
516         } else {
517             return forciblyReleaseLock(fullyQualifiedKey, lockRef);
518         }
519     }
520
521     public MusicLockState voluntaryReleaseLock(String fullyQualifiedKey, String lockReference)
522             throws MusicLockingException {
523         MusicLockState result = null;
524         try {
525             result = destroyLockRef(fullyQualifiedKey, lockReference);
526         } catch (Exception ex) {
527             logger.info(EELFLoggerDelegate.applicationLogger,
528                     "Exception in voluntaryReleaseLock() for " + fullyQualifiedKey + "ref: " + lockReference);
529             throw new MusicLockingException(ex.getMessage());
530         }
531         return result;
532     }
533
534     public MusicLockState forciblyReleaseLock(String fullyQualifiedKey, String lockReference) throws MusicLockingException {
535         String[] splitString = fullyQualifiedKey.split("\\.");
536         String keyspace = splitString[0];
537         String table = splitString[1];
538
539         //leave a signal that this key could potentially be unsynchronized
540         String syncTable = keyspace+".unsyncedKeys_"+table;
541         PreparedQueryObject queryObject = new PreparedQueryObject();
542         String values = "(?)";
543         queryObject.addValue(fullyQualifiedKey);
544         String insQuery = "insert into "+syncTable+" (key) values "+values+";";
545         queryObject.appendQueryString(insQuery);
546         try {
547             MusicDataStoreHandle.getDSHandle().executePut(queryObject, "critical");
548         } catch (Exception e) {
549             logger.error("Cannot forcibly release lock: " + fullyQualifiedKey + " " + lockReference + ". "
550                         + e.getMessage(), e);
551         }
552
553         //now release the lock
554         return destroyLockRef(fullyQualifiedKey, lockReference);
555     }
556
557     @Override
558     public List<String> releaseAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicLockingException, MusicServiceException, MusicQueryException {
559 //        System.out.println("IN RELEASEALLLOCKSFOROWNER, ");
560
561         List<String> lockIds = getLockingServiceHandle().getAllLocksForOwner(ownerId, keyspace, table);
562         for (String lockId : lockIds) {
563 //            System.out.println(" LOCKID = " + lockId);
564             //return "$" + keyspace + "." + table + "." + lockName + "$" + String.valueOf(lockRef);
565             releaseLock("$" + keyspace + "." + table + "." + lockId, true);
566         }
567         return lockIds;
568     }
569
570     /**
571      *
572      * @param lockName
573      * @throws MusicLockingException
574      */
575     @Deprecated
576     public  void deleteLock(String lockName) throws MusicLockingException {
577         throw new MusicLockingException("Depreciated Method Delete Lock");
578     }
579
580     // Prepared Query Additions.
581
582     /**
583      *
584      * @param queryObject
585      * @return ReturnType
586      * @throws MusicServiceException
587      */
588     public  ReturnType eventualPut(PreparedQueryObject queryObject) {
589         boolean result = false;
590         try {
591             result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
592         } catch (MusicServiceException | MusicQueryException ex) {
593             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get Lock Handle "  ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
594             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + "  " + ex.getCause() + " " + ex);
595             return new ReturnType(ResultType.FAILURE, ex.getMessage());
596         }
597         if (result) {
598             return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
599         } else {
600             return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
601         }
602     }
603
604     /**
605      *
606      * @param queryObject
607      * @return ReturnType
608      * @throws MusicServiceException
609      */
610     public  ReturnType eventualPut_nb(PreparedQueryObject queryObject,String keyspace,String tablename,String primaryKey) {
611         boolean result = false;
612         long guard = 0;
613         PreparedQueryObject getGaurd = new PreparedQueryObject();
614         getGaurd.appendQueryString("SELECT guard FROM "+keyspace+".lockq_"+tablename+ " WHERE key = ? ;");
615         getGaurd.addValue(primaryKey);
616         try {
617             ResultSet getGaurdResult = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(getGaurd);
618             Row row = getGaurdResult.one();
619             if (row != null) {
620                 guard = row.getLong("guard");
621                 long timeOfWrite = System.currentTimeMillis();
622                 long ts = MusicUtil.v2sTimeStampInMicroseconds(guard, timeOfWrite);
623                 String query = queryObject.getQuery();
624                 if (!queryObject.getQuery().contains("USING TIMESTAMP")) {
625                     if (queryObject.getOperation().equalsIgnoreCase("delete"))
626                         query = query.replaceFirst("WHERE", " USING TIMESTAMP " + ts + " WHERE ");
627                     else
628                         query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET");
629                 }
630                 queryObject.replaceQueryString(query);
631             }
632
633         } catch (MusicServiceException | MusicQueryException e) {
634             logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage(), e);
635         }
636         try {
637             result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
638         } catch (MusicServiceException | MusicQueryException ex) {
639             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(),"[ERR512E] Failed to get Lock Handle ",
640                 ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
641             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + "  " + ex.getCause() + " ", ex);
642             return new ReturnType(ResultType.FAILURE, ex.getMessage());
643         }
644         if (result) {
645             return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
646         } else {
647             return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
648         }
649     }
650
651     /**
652      *
653      * @param keyspace
654      * @param table
655      * @param primaryKeyValue
656      * @param queryObject
657      * @param lockId
658      * @return
659      */
660     public ReturnType criticalPut(String keyspace, String table, String primaryKeyValue,
661             PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
662         long start = System.currentTimeMillis();
663         try {
664             String keyLock = lockId.substring(lockId.lastIndexOf(".") + 1,lockId.lastIndexOf("$"));
665             if (lockId.contains(".") && !keyLock.equals(primaryKeyValue)) {
666                 return new ReturnType(ResultType.FAILURE,"Lock value '" + keyLock + "' and key value '"
667                 + primaryKeyValue + "' not match. Please check your values: " 
668                 + lockId + " .");
669             }
670             LockObject lockObject = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue,
671                     lockId.substring(lockId.lastIndexOf("$") + 1));
672
673             if ( lockObject == null ) {
674                 return new ReturnType(ResultType.FAILURE, lockId + " does not exist.");
675             } else if (!lockObject.getIsLockOwner()) {
676                 return new ReturnType(ResultType.FAILURE, lockId + " is not the lock holder");
677             } else if (lockObject.getLocktype() != LockType.WRITE) {
678                 return new ReturnType(ResultType.FAILURE,
679                         "Attempting to do write operation, but " + lockId + " is a read lock");
680             }
681
682             if (conditionInfo != null) {
683                 try {
684                     if (conditionInfo.testCondition() == false)
685                         return new ReturnType(ResultType.FAILURE, "Lock acquired but the condition is not true");
686                 } catch (Exception e) {
687                     logger.error(EELFLoggerDelegate.errorLogger, e);
688                     return new ReturnType(ResultType.FAILURE,
689                             "Exception thrown while checking the condition, check its sanctity:\n" + e.getMessage());
690                 }
691             }
692             String query = queryObject.getQuery();
693             long timeOfWrite = System.currentTimeMillis();
694             long lockOrdinal = Long.parseLong(lockId.substring(lockId.lastIndexOf("$") + 1));
695             long ts = MusicUtil.v2sTimeStampInMicroseconds(lockOrdinal, timeOfWrite);
696             // TODO: use Statement instead of modifying query
697             if (!queryObject.getQuery().contains("USING TIMESTAMP")) {
698                 if (queryObject.getOperation().equalsIgnoreCase("delete"))
699                     query = query.replaceFirst("WHERE", " USING TIMESTAMP " + ts + " WHERE ");
700                 else if (queryObject.getOperation().equalsIgnoreCase("insert"))
701                     query = query.replaceFirst(";", " USING TIMESTAMP " + ts + " ; ");
702                 else
703                     query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET");
704             }
705             queryObject.replaceQueryString(query);
706             MusicDataStore dsHandle = MusicDataStoreHandle.getDSHandle();
707             dsHandle.executePut(queryObject, MusicUtil.CRITICAL);
708             long end = System.currentTimeMillis();
709             logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
710         } catch (MusicQueryException | MusicServiceException | MusicLockingException  e) {
711             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), e);
712             return new ReturnType(ResultType.FAILURE,
713                 "Exception thrown while doing the critical put: "
714                 + e.getMessage());
715         }
716         return new ReturnType(ResultType.SUCCESS, "Update performed");
717     }
718
719
720     /**
721      *
722      * @param queryObject
723      * @param consistency
724      * @return Boolean Indicates success or failure
725      * @throws MusicServiceException
726      *
727      *
728      */
729     public ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException,MusicQueryException {
730         // this is mainly for some functions like keyspace creation etc which does not
731         // really need the bells and whistles of Music locking.
732         boolean result = false;
733 //        try {
734         result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, consistency);
735 //        } catch (MusicQueryException | MusicServiceException ex) {
736             // logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR,
737             //     ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR, ex);
738 //            throw new MusicServiceException(ex.getMessage(),ex);
739 //        }
740         return result ? ResultType.SUCCESS : ResultType.FAILURE;
741     }
742
743     /**
744      * This method performs DDL operation on cassandra.
745      *
746      * @param queryObject query object containing prepared query and values
747      * @return ResultSet
748      * @throws MusicServiceException
749      */
750     public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
751         ResultSet results = null;
752         try {
753             results = MusicDataStoreHandle.getDSHandle().executeOneConsistencyGet(queryObject);
754         } catch (MusicQueryException | MusicServiceException e) {
755             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), e);
756             throw new MusicServiceException(e.getMessage());
757         }
758         return results;
759     }
760
761     /**
762      * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
763      * is used to check if the resource is free.
764      *
765      * @param keyspace name of the keyspace
766      * @param table name of the table
767      * @param primaryKeyValue primary key value
768      * @param queryObject query object containing prepared query and values
769      * @param lockId lock ID to check if the resource is free to perform the operation.
770      * @return ResultSet
771      */
772     public ResultSet criticalGet(String keyspace, String table, String primaryKeyValue,
773                     PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
774         ResultSet results = null;
775         String keyLock = lockId.substring(lockId.lastIndexOf(".") + 1,lockId.lastIndexOf("$"));
776         try {
777             if (lockId.contains(".") && !keyLock.equals(primaryKeyValue)) {
778                 throw new MusicLockingException("Lock value '" + keyLock + "' and key value '"
779                 + primaryKeyValue + "' do not match. Please check your values: " 
780                 + lockId + " .");
781             }
782             LockObject lockObject = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue,
783                 lockId.substring(lockId.lastIndexOf("$") + 1));
784             if (null == lockObject) {
785                 throw new MusicLockingException("No Lock Object. Please check if lock name or key is correct." 
786                     + lockId + " .");
787             }
788             if ( !lockObject.getIsLockOwner()) {
789                 return null;// not top of the lock store q
790             }
791             results = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(queryObject);
792         } catch ( MusicLockingException e ) {
793             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity
794                     .WARN, ErrorTypes.MUSICSERVICEERROR);
795                 throw new MusicServiceException(
796                     "Cannot perform critical get for key: " + primaryKeyValue + " : " + e.getMessage());
797         } catch (MusicQueryException | MusicServiceException e) {
798             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity
799                     .WARN, ErrorTypes.MUSICSERVICEERROR, e);
800                 throw new MusicServiceException(
801                     "Cannot perform critical get for key: " + primaryKeyValue + " : " + e.getMessage());    
802         }
803         return results;
804     }
805
806     /**
807      * This method performs DML operation on cassandra, when the lock of the dd is acquired.
808      *
809      * @param keyspaceName name of the keyspace
810      * @param tableName name of the table
811      * @param primaryKey primary key value
812      * @param queryObject query object containing prepared query and values
813      * @return ReturnType
814      * @throws MusicLockingException
815      * @throws MusicServiceException
816      * @throws MusicQueryException
817      */
818     public ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
819             PreparedQueryObject queryObject, Condition conditionInfo)
820             throws MusicLockingException, MusicQueryException, MusicServiceException {
821         long start = System.currentTimeMillis();
822         String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey;
823         String lockId = createLockReferenceAtomic(fullyQualifiedKey, LockType.WRITE);
824         long lockCreationTime = System.currentTimeMillis();
825         ReturnType lockAcqResult = null;
826         logger.info(EELFLoggerDelegate.applicationLogger,
827                 "***Acquiring lock for atomicPut() query : " + queryObject.getQuery() + " : " + primaryKey);
828         logger.info(EELFLoggerDelegate.applicationLogger,
829                 "***Acquiring lock for atomicPut() values: " + queryObject.getValues().toString());
830         if (conditionInfo != null) {
831             logger.info(EELFLoggerDelegate.applicationLogger,
832                     "***Acquiring lock for atomicPut() conditions: " + conditionInfo.toString());
833         }
834         try {
835             lockAcqResult = acquireLockWithLease(fullyQualifiedKey, lockId, MusicUtil.getDefaultLockLeasePeriod());
836         } catch (MusicLockingException ex) {
837             logger.error(EELFLoggerDelegate.errorLogger,
838                     "Exception while acquireLockWithLease() in atomic put for key: " + primaryKey);
839             logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage());
840             throw new MusicServiceException(
841                     "Cannot perform atomic put for key: " + primaryKey + " : " + ex.getMessage());
842         }
843         long lockAcqTime = System.currentTimeMillis();
844
845         /*
846          * if (!lockAcqResult.getResult().equals(ResultType.SUCCESS)) { logger.info(EELFLoggerDelegate.
847          * applicationLogger,"unable to acquire lock, id " + lockId);
848          * voluntaryReleaseLock(fullyQualifiedKey,lockId); return lockAcqResult; }
849          */
850
851         logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
852         String lockRef = lockId.substring(lockId.lastIndexOf("$"));
853         ReturnType criticalPutResult = null;
854         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
855             criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, queryObject, lockRef, conditionInfo);
856             long criticalPutTime = System.currentTimeMillis();
857             long lockDeleteTime = System.currentTimeMillis();
858             String timingInfo = "|lock creation time:" + (lockCreationTime - start) + "|lock accquire time:"
859                     + (lockAcqTime - lockCreationTime) + "|critical put time:" + (criticalPutTime - lockAcqTime)
860                     + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
861             criticalPutResult.setTimingInfo(timingInfo);
862         } else {
863             logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
864             criticalPutResult = lockAcqResult;
865         }
866         try {
867             voluntaryReleaseLock(fullyQualifiedKey, lockId);
868         } catch (MusicLockingException ex) {
869             logger.info(EELFLoggerDelegate.applicationLogger,
870                     "Exception occured while deleting lock after atomic put for key: " + primaryKey);
871             criticalPutResult.setMessage(criticalPutResult.getMessage() + "Lock release failed");
872         }
873         return criticalPutResult;
874     }
875
876
877
878     /**
879      * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
880      *
881      * @param keyspaceName name of the keyspace
882      * @param tableName name of the table
883      * @param primaryKey primary key value
884      * @param queryObject query object containing prepared query and values
885      * @return ResultSet
886      * @throws MusicServiceException
887      * @throws MusicLockingException
888      * @throws MusicQueryException
889      */
890     public ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
891             PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException, MusicQueryException {
892         String fullyQualifiedKey = keyspaceName + "." + tableName + "." + primaryKey;
893         String lockId = createLockReferenceAtomic(fullyQualifiedKey, LockType.READ);
894         ReturnType lockAcqResult = null;
895         ResultSet result = null;
896         logger.info(EELFLoggerDelegate.applicationLogger, "Acquiring lock for atomicGet() : " + queryObject.getQuery());
897         try {
898             lockAcqResult = acquireLockWithLease(fullyQualifiedKey, lockId, MusicUtil.getDefaultLockLeasePeriod());
899         } catch (MusicLockingException ex) {
900             logger.error(EELFLoggerDelegate.errorLogger,
901                     "Exception while acquireLockWithLease() in atomic get for key: " + primaryKey);
902             logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage());
903             throw new MusicServiceException(
904                     "Cannot perform atomic get for key: " + primaryKey + " : " + ex.getMessage());
905         }
906         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
907             logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
908             String lockRef = lockId.substring(lockId.lastIndexOf("$"));
909             result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockRef);
910         } else {
911             logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
912         }
913         try {
914             voluntaryReleaseLock(fullyQualifiedKey, lockId);
915         } catch (MusicLockingException ex) {
916             logger.info(EELFLoggerDelegate.applicationLogger,
917                     "Exception occured while deleting lock after atomic put for key: " + primaryKey);
918             throw new MusicLockingException(ex.getMessage());
919         }
920
921         return result;
922     }
923
924
925
926     /**
927      * @param lockName
928      * @return
929      */
930     public Map<String, Object> validateLock(String lockName) {
931         return MusicUtil.validateLock(lockName);
932     }
933
934     @Override
935     @Deprecated
936     public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
937         PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
938         return null;
939     }
940
941     @Override
942     public List<String> getLockQueue(String fullyQualifiedKey)
943         throws MusicServiceException, MusicQueryException, MusicLockingException {
944         String[] splitString = fullyQualifiedKey.split("\\.");
945         String keyspace = splitString[0];
946         String table = splitString[1];
947         String primaryKeyValue = splitString[2];
948
949         return getLockingServiceHandle().getLockQueue(keyspace, table, primaryKeyValue);
950     }
951     @Override
952     public long getLockQueueSize(String fullyQualifiedKey)
953         throws MusicServiceException, MusicQueryException, MusicLockingException {
954         String[] splitString = fullyQualifiedKey.split("\\.");
955         String keyspace = splitString[0];
956         String table = splitString[1];
957         String primaryKeyValue = splitString[2];
958
959         return getLockingServiceHandle().getLockQueueSize(keyspace, table, primaryKeyValue);
960     }
961
962     @Override
963     @Deprecated
964     public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
965             PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
966         //deprecated
967         return null;
968     }
969     
970     //Methods added for ORM changes
971     
972     public ResultType createKeyspace(JsonKeySpace jsonKeySpaceObject,String consistencyInfo) 
973             throws MusicServiceException,MusicQueryException {
974         ResultType result = nonKeyRelatedPut(jsonKeySpaceObject.genCreateKeyspaceQuery(), consistencyInfo);
975         logger.info(EELFLoggerDelegate.applicationLogger, " Keyspace Creation Process completed successfully");
976
977         return result;
978     }
979     
980     public ResultType dropKeyspace(JsonKeySpace jsonKeySpaceObject, String consistencyInfo) 
981             throws MusicServiceException,MusicQueryException {
982         ResultType result = nonKeyRelatedPut(jsonKeySpaceObject.genDropKeyspaceQuery(),
983                     consistencyInfo);
984         logger.info(EELFLoggerDelegate.applicationLogger, " Keyspace deletion Process completed successfully");
985         return result;
986     }
987     
988     public ResultType createTable(JsonTable jsonTableObject, String consistencyInfo) 
989             throws MusicServiceException, MusicQueryException {
990         ResultType result = null;
991         try {
992             result = createTable(jsonTableObject.getKeyspaceName(), 
993                     jsonTableObject.getTableName(), jsonTableObject.genCreateTableQuery(), consistencyInfo);
994             
995         } catch (MusicServiceException ex) {
996             logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.WARN,
997                     ErrorTypes.MUSICSERVICEERROR);
998             throw new MusicServiceException(ex.getMessage());
999         }
1000         logger.info(EELFLoggerDelegate.applicationLogger, " Table Creation Process completed successfully ");
1001         return result;
1002     }
1003     
1004     public ResultType dropTable(JsonTable jsonTableObject,String consistencyInfo) 
1005             throws MusicServiceException,MusicQueryException {
1006         ResultType result = nonKeyRelatedPut(jsonTableObject.genDropTableQuery(),
1007                     consistencyInfo);
1008         logger.info(EELFLoggerDelegate.applicationLogger, " Table deletion Process completed successfully ");
1009         
1010         return result;
1011     }
1012     
1013     @Override
1014     public ResultType createIndex(JsonIndex jsonIndexObject, String consistencyInfo) 
1015             throws MusicServiceException, MusicQueryException{
1016         ResultType result = nonKeyRelatedPut(jsonIndexObject.genCreateIndexQuery(),
1017                     consistencyInfo);
1018         
1019         logger.info(EELFLoggerDelegate.applicationLogger, " Index creation Process completed successfully ");
1020         return result;
1021     }
1022     
1023     /**
1024      * This method performs DDL operation on cassandra.
1025      *
1026      * @param queryObject query object containing prepared query and values
1027      * @return ResultSet
1028      * @throws MusicServiceException
1029      */
1030     public  ResultSet select(JsonSelect jsonSelect, MultivaluedMap<String, String> rowParams) 
1031             throws MusicServiceException, MusicQueryException {
1032         ResultSet results = null;
1033         try {
1034             results = get(jsonSelect.genSelectQuery(rowParams));
1035         } catch (MusicServiceException e) {
1036             logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1037             throw new MusicServiceException(e.getMessage());
1038         }
1039         return results;
1040     }
1041     
1042     /**
1043      * Select Critical
1044      */
1045     public ResultSet selectCritical(JsonInsert jsonInsertObj, MultivaluedMap<String, String> rowParams)
1046             throws MusicLockingException, MusicQueryException, MusicServiceException {
1047         
1048         ResultSet results = null;
1049         String consistency = "";
1050         if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
1051             consistency = jsonInsertObj.getConsistencyInfo().get("type");
1052         }
1053         
1054         String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
1055         
1056         PreparedQueryObject queryObject = jsonInsertObj.genSelectCriticalPreparedQueryObj(rowParams);
1057         
1058         if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1059             results = criticalGet(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(), 
1060                     jsonInsertObj.getPrimaryKeyVal(), queryObject,lockId);
1061         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1062             results = atomicGet(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(),
1063                     jsonInsertObj.getPrimaryKeyVal(), queryObject);
1064         }
1065         
1066         return results;
1067     }
1068     
1069     /**
1070      * this is insert row into Table
1071      */
1072     public ReturnType insertIntoTable(JsonInsert jsonInsertObj)
1073             throws MusicLockingException, MusicQueryException, MusicServiceException {
1074         
1075         String consistency = "";
1076         if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
1077             consistency = jsonInsertObj.getConsistencyInfo().get("type");
1078         }
1079         
1080         ReturnType result = null;
1081         
1082         try {
1083             PreparedQueryObject queryObj = null;
1084             queryObj = jsonInsertObj.genInsertPreparedQueryObj();
1085             
1086             if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
1087                 result = eventualPut(jsonInsertObj.genInsertPreparedQueryObj());
1088             } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1089                 String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
1090                 if(lockId == null) {
1091                     logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1092                             + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1093                     return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1094                             + "and acquire lock or use ATOMIC instead of CRITICAL");
1095                 }
1096                 result = criticalPut(jsonInsertObj.getKeyspaceName(), 
1097                         jsonInsertObj.getTableName(), jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), lockId,null);
1098             } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1099                 result = atomicPut(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(), 
1100                         jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), null);
1101             }
1102         } catch (Exception ex) {
1103             logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR  ,ErrorSeverity
1104                 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
1105             return new ReturnType(ResultType.FAILURE, ex.getMessage());
1106         }
1107         
1108         return result;
1109     }
1110     
1111      /**
1112      * This is insert row into Table
1113      */
1114     public ReturnType updateTable(JsonUpdate jsonUpdateObj, MultivaluedMap<String, String> rowParams)
1115             throws MusicLockingException, MusicQueryException, MusicServiceException {
1116         
1117         ReturnType result = null;
1118         String consistency = "";
1119         if(null != jsonUpdateObj && null != jsonUpdateObj.getConsistencyInfo()) {
1120             consistency = jsonUpdateObj.getConsistencyInfo().get("type");
1121         }
1122         PreparedQueryObject queryObject = jsonUpdateObj.genUpdatePreparedQueryObj(rowParams);
1123         
1124         Condition conditionInfo;
1125         if (jsonUpdateObj.getConditions() == null) {
1126             conditionInfo = null;
1127         } else {
1128             // to avoid parsing repeatedly, just send the select query to obtain row
1129             PreparedQueryObject selectQuery = new PreparedQueryObject();
1130             selectQuery.appendQueryString("SELECT *  FROM " + jsonUpdateObj.getKeyspaceName() + "." + jsonUpdateObj.getTableName() + " WHERE "
1131                 + jsonUpdateObj.getRowIdString() + ";");
1132             selectQuery.addValue(jsonUpdateObj.getPrimarKeyValue());
1133             conditionInfo = new Condition(jsonUpdateObj.getConditions(), selectQuery);
1134         }
1135
1136         
1137         if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
1138             result = eventualPut(queryObject);
1139         } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1140             String lockId = jsonUpdateObj.getConsistencyInfo().get("lockId");
1141             if(lockId == null) {
1142                 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1143                         + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1144                
1145                 return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1146                         + "and acquire lock or use ATOMIC instead of CRITICAL");
1147             }
1148             result = criticalPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
1149                             queryObject, lockId, conditionInfo);
1150         } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
1151             // this function is mainly for the benchmarks
1152             try {
1153                 result = atomicPutWithDeleteLock(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(),
1154                         jsonUpdateObj.getPrimarKeyValue(), queryObject, conditionInfo);
1155             } catch (MusicLockingException e) {
1156                 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN,
1157                     ErrorTypes.GENERALSERVICEERROR, e);
1158                 throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
1159                 
1160             }
1161         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1162             try {
1163                 result = atomicPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
1164                     queryObject, conditionInfo);
1165             } catch (MusicLockingException e) {
1166                 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR  ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e);
1167                 throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
1168             }
1169         } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1170             try {
1171                 result = eventualPut_nb(queryObject, jsonUpdateObj.getKeyspaceName(),
1172                         jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue());
1173             }catch (Exception e) {
1174                 return new ReturnType(ResultType.FAILURE, e.getMessage());
1175             }
1176             
1177         }
1178         
1179         return result;
1180     }
1181     
1182     /**
1183      * This method is for Delete From Table
1184      */
1185     public ReturnType deleteFromTable(JsonDelete jsonDeleteObj, MultivaluedMap<String, String> rowParams)
1186             throws MusicLockingException, MusicQueryException, MusicServiceException {
1187         
1188         ReturnType result = null;
1189         String consistency = "";
1190         if(null != jsonDeleteObj && null != jsonDeleteObj.getConsistencyInfo()) {
1191             consistency = jsonDeleteObj.getConsistencyInfo().get("type");
1192         }
1193         PreparedQueryObject queryObject = jsonDeleteObj.genDeletePreparedQueryObj(rowParams);
1194         
1195         // get the conditional, if any
1196         Condition conditionInfo;
1197         if (jsonDeleteObj.getConditions() == null) {
1198             conditionInfo = null;
1199         } else {
1200             // to avoid parsing repeatedly, just send the select query to obtain row
1201             PreparedQueryObject selectQuery = new PreparedQueryObject();
1202             selectQuery.appendQueryString("SELECT *  FROM " + jsonDeleteObj.getKeyspaceName() + "." + jsonDeleteObj.getTableName() + " WHERE "
1203                 + jsonDeleteObj.getRowIdString() + ";");
1204             selectQuery.addValue(jsonDeleteObj.getPrimarKeyValue());
1205             conditionInfo = new Condition(jsonDeleteObj.getConditions(), selectQuery);
1206         }
1207         
1208         if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1209             result = eventualPut(queryObject);
1210         else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1211             String lockId = jsonDeleteObj.getConsistencyInfo().get("lockId");
1212             if(lockId == null) {
1213                 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1214                     + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1215                
1216                 return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1217                         + "and acquire lock or use ATOMIC instead of CRITICAL");
1218             }
1219             result = criticalPut(jsonDeleteObj.getKeyspaceName(), 
1220                     jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
1221                 queryObject, lockId, conditionInfo);
1222         } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1223             result = atomicPut(jsonDeleteObj.getKeyspaceName(), 
1224                     jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
1225                 queryObject, conditionInfo);
1226         } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {                    
1227             result = eventualPut_nb(queryObject, jsonDeleteObj.getKeyspaceName(), 
1228                     jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue());
1229         }
1230         
1231         return result;
1232     }
1233
1234
1235 }