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