2 * ============LICENSE_START==========================================
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * ============LICENSE_END=============================================
23 * ====================================================================
26 package org.onap.music.service.impl;
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;
35 import java.util.StringTokenizer;
36 import java.util.concurrent.atomic.AtomicInteger;
37 import javax.ws.rs.core.MultivaluedMap;
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;
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;
73 public class MusicCassaCore implements MusicCoreService {
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);
82 private MusicCassaCore() {
83 // not going to happen
86 public static CassaLockStore getmLockHandle() {
90 //for unit testing purposes
91 static void setmLockHandle(CassaLockStore mLockHandle) {
92 MusicCassaCore.mLockHandle = mLockHandle;
95 public static MusicCassaCore getInstance() {
97 if(musicCassaCoreInstance == null) {
98 musicCassaCoreInstance = new MusicCassaCore();
100 return musicCassaCoreInstance;
103 public static CassaLockStore getLockingServiceHandle() throws MusicLockingException {
104 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
105 long start = System.currentTimeMillis();
107 if (mLockHandle == null) {
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);
115 long end = System.currentTimeMillis();
116 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
120 public String createLockReferenceAtomic(String fullyQualifiedKey) throws MusicLockingException {
121 return createLockReferenceAtomic(fullyQualifiedKey, LockType.WRITE);
123 public String createLockReference(String fullyQualifiedKey, String owner) throws MusicLockingException {
124 return createLockReference(fullyQualifiedKey, LockType.WRITE, owner);
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
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.");
137 String keyspace = splitString[0];
138 String table = splitString[1];
139 String lockName = splitString[2];
141 logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
144 String lockReference = null;
145 LockObject peek = null;
147 /** Lets check for an existing lock.
148 * This will allow us to limit the amount of requests going forward.
150 start = System.currentTimeMillis();
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());
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.");
165 end = System.currentTimeMillis();
166 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for lock reference for key [" + lockName + "]:" + (end - start) + " ms");
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.
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.
177 if ( set.add(fullyQualifiedKey)) {
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);
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());
191 throw new MusicLockingException("Unable to create lock reference for key [" + lockName + "]. Please try again.");
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;
198 //return createLockReference(fullyQualifiedKey, locktype, null);
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.");
206 String keyspace = splitString[0];
207 String table = splitString[1];
208 String lockName = splitString[2];
210 logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
213 String lockReference = null;
215 /* Check for a Deadlock */
217 boolean deadlock = getLockingServiceHandle().checkForDeadlock(keyspace, table, lockName, locktype, owner, false);
219 MusicDeadlockException e = new MusicDeadlockException("Deadlock detected when " + owner + " tried to create lock on " + keyspace + "." + table + "." + lockName);
220 e.setValues(owner, keyspace, table, lockName);
223 } catch (MusicDeadlockException e) {
224 //just threw this, no need to wrap it
226 } catch (MusicServiceException | MusicQueryException e) {
227 logger.error(EELFLoggerDelegate.applicationLogger, e);
228 throw new MusicLockingException("Unable to check for deadlock. " + e.getMessage(), e);
230 end = System.currentTimeMillis();
231 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to check for deadlock for key [" + lockName + "]:" + (end - start) + " ms");
233 start = System.currentTimeMillis();
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);
243 end = System.currentTimeMillis();
244 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference for key [" + lockName + "]:" + (end - start) + " ms");
245 return lockReference;
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
255 logger.info(EELFLoggerDelegate.applicationLogger,"Attempting to promote lock " + lockId);
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);
268 public ReturnType acquireLockWithLease(String fullyQualifiedKey, String lockReference, long leasePeriod)
269 throws MusicLockingException, MusicQueryException, MusicServiceException {
270 evictExpiredLockHolder(fullyQualifiedKey,leasePeriod);
271 return acquireLock(fullyQualifiedKey, lockReference);
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];
281 LockObject currentLockHolderObject = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
283 if (!currentLockHolderObject.getIsLockOwner()) { // no lock holder
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
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");
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
307 LockObject lockInfo = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue, lockRef);
309 if (!lockInfo.getIsLockOwner()) {
310 return new ReturnType(ResultType.FAILURE, lockId + " is not a lock holder");//not top of the lock store q
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);
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!");
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);
336 String cleanQuery = "delete from " + syncTable + " where key='"+localFullyQualifiedKey+"';";
337 PreparedQueryObject deleteQueryObject = new PreparedQueryObject();
338 deleteQueryObject.appendQueryString(cleanQuery);
339 MusicDataStoreHandle.getDSHandle().executePut(deleteQueryObject, "critical");
342 getLockingServiceHandle().updateLockAcquireTime(keyspace, table, primaryKeyValue, lockRef);
344 return new ReturnType(ResultType.SUCCESS, lockRef+" is the lock holder for the key");
351 * @param tableQueryObject
353 * @return Boolean Indicates success or failure
354 * @throws MusicServiceException
357 public ResultType createTable(String keyspace, String table, PreparedQueryObject tableQueryObject,
358 String consistency) throws MusicServiceException {
359 boolean result = false;
362 // create shadow locking table
363 result = getLockingServiceHandle().createLockQueue(keyspace, table);
364 if (result == false) {
365 return ResultType.FAILURE;
369 // create table to track unsynced_keys
370 table = "unsyncedKeys_" + table;
373 "CREATE TABLE IF NOT EXISTS " + keyspace + "." + table + " ( key text,PRIMARY KEY (key) );";
374 PreparedQueryObject queryObject = new PreparedQueryObject();
376 queryObject.appendQueryString(tabQuery);
377 result = MusicDataStoreHandle.getDSHandle().executePut(queryObject, "eventual");
378 if (result == false) {
379 return ResultType.FAILURE;
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());
390 return result ? ResultType.SUCCESS : ResultType.FAILURE;
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();
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
402 DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
403 Object cqlFormattedPrimaryKeyValue =
404 MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
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);
419 public ResultSet quorumGet(PreparedQueryObject query) {
420 ResultSet results = null;
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);
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];
437 LockObject lockOwner = getLockingServiceHandle().peekLockQueue(keyspace, table, primaryKeyValue);
438 if (!lockOwner.getIsLockOwner()) {
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);
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];
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);
464 * @param lockReference
467 public static String getLockNameFromId(String lockReference) {
468 StringTokenizer st = new StringTokenizer(lockReference);
469 return st.nextToken("$");
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];
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());
488 long end = System.currentTimeMillis();
489 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
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];
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());
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, "");
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);
517 return forciblyReleaseLock(fullyQualifiedKey, lockRef);
521 public MusicLockState voluntaryReleaseLock(String fullyQualifiedKey, String lockReference)
522 throws MusicLockingException {
523 MusicLockState result = null;
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());
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];
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);
547 MusicDataStoreHandle.getDSHandle().executePut(queryObject, "critical");
548 } catch (Exception e) {
549 logger.error("Cannot forcibly release lock: " + fullyQualifiedKey + " " + lockReference + ". "
550 + e.getMessage(), e);
553 //now release the lock
554 return destroyLockRef(fullyQualifiedKey, lockReference);
558 public List<String> releaseAllLocksForOwner(String ownerId, String keyspace, String table) throws MusicLockingException, MusicServiceException, MusicQueryException {
559 // System.out.println("IN RELEASEALLLOCKSFOROWNER, ");
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);
573 * @throws MusicLockingException
576 public void deleteLock(String lockName) throws MusicLockingException {
577 throw new MusicLockingException("Depreciated Method Delete Lock");
580 // Prepared Query Additions.
586 * @throws MusicServiceException
588 public ReturnType eventualPut(PreparedQueryObject queryObject) {
589 boolean result = false;
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());
598 return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
600 return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
608 * @throws MusicServiceException
610 public ReturnType eventualPut_nb(PreparedQueryObject queryObject,String keyspace,String tablename,String primaryKey) {
611 boolean result = false;
613 PreparedQueryObject getGaurd = new PreparedQueryObject();
614 getGaurd.appendQueryString("SELECT guard FROM "+keyspace+".lockq_"+tablename+ " WHERE key = ? ;");
615 getGaurd.addValue(primaryKey);
617 ResultSet getGaurdResult = MusicDataStoreHandle.getDSHandle().executeQuorumConsistencyGet(getGaurd);
618 Row row = getGaurdResult.one();
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 ");
628 query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET");
630 queryObject.replaceQueryString(query);
633 } catch (MusicServiceException | MusicQueryException e) {
634 logger.error(EELFLoggerDelegate.applicationLogger,e.getMessage(), e);
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());
645 return new ReturnType(ResultType.SUCCESS, "Eventual Operation Successfully performed");
647 return new ReturnType(ResultType.FAILURE, "Eventual Operation failed to perform");
655 * @param primaryKeyValue
660 public ReturnType criticalPut(String keyspace, String table, String primaryKeyValue,
661 PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
662 long start = System.currentTimeMillis();
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: "
670 LockObject lockObject = getLockingServiceHandle().getLockInfo(keyspace, table, primaryKeyValue,
671 lockId.substring(lockId.lastIndexOf("$") + 1));
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");
682 if (conditionInfo != null) {
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());
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 + " ; ");
703 query = query.replaceFirst("SET", "USING TIMESTAMP " + ts + " SET");
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: "
716 return new ReturnType(ResultType.SUCCESS, "Update performed");
724 * @return Boolean Indicates success or failure
725 * @throws MusicServiceException
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;
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);
740 return result ? ResultType.SUCCESS : ResultType.FAILURE;
744 * This method performs DDL operation on cassandra.
746 * @param queryObject query object containing prepared query and values
748 * @throws MusicServiceException
750 public ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
751 ResultSet results = null;
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());
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.
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.
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("$"));
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: "
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."
788 if ( !lockObject.getIsLockOwner()) {
789 return null;// not top of the lock store q
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());
807 * This method performs DML operation on cassandra, when the lock of the dd is acquired.
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
814 * @throws MusicLockingException
815 * @throws MusicServiceException
816 * @throws MusicQueryException
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());
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());
843 long lockAcqTime = System.currentTimeMillis();
846 * if (!lockAcqResult.getResult().equals(ResultType.SUCCESS)) { logger.info(EELFLoggerDelegate.
847 * applicationLogger,"unable to acquire lock, id " + lockId);
848 * voluntaryReleaseLock(fullyQualifiedKey,lockId); return lockAcqResult; }
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);
863 logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
864 criticalPutResult = lockAcqResult;
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");
873 return criticalPutResult;
879 * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
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
886 * @throws MusicServiceException
887 * @throws MusicLockingException
888 * @throws MusicQueryException
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());
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());
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);
911 logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
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());
930 public Map<String, Object> validateLock(String lockName) {
931 return MusicUtil.validateLock(lockName);
936 public ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
937 PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
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];
949 return getLockingServiceHandle().getLockQueue(keyspace, table, primaryKeyValue);
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];
959 return getLockingServiceHandle().getLockQueueSize(keyspace, table, primaryKeyValue);
964 public ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
965 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
970 //Methods added for ORM changes
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");
980 public ResultType dropKeyspace(JsonKeySpace jsonKeySpaceObject, String consistencyInfo)
981 throws MusicServiceException,MusicQueryException {
982 ResultType result = nonKeyRelatedPut(jsonKeySpaceObject.genDropKeyspaceQuery(),
984 logger.info(EELFLoggerDelegate.applicationLogger, " Keyspace deletion Process completed successfully");
988 public ResultType createTable(JsonTable jsonTableObject, String consistencyInfo)
989 throws MusicServiceException, MusicQueryException {
990 ResultType result = null;
992 result = createTable(jsonTableObject.getKeyspaceName(),
993 jsonTableObject.getTableName(), jsonTableObject.genCreateTableQuery(), consistencyInfo);
995 } catch (MusicServiceException ex) {
996 logger.error(EELFLoggerDelegate.errorLogger, ex.getMessage(), AppMessages.UNKNOWNERROR, ErrorSeverity.WARN,
997 ErrorTypes.MUSICSERVICEERROR);
998 throw new MusicServiceException(ex.getMessage());
1000 logger.info(EELFLoggerDelegate.applicationLogger, " Table Creation Process completed successfully ");
1004 public ResultType dropTable(JsonTable jsonTableObject,String consistencyInfo)
1005 throws MusicServiceException,MusicQueryException {
1006 ResultType result = nonKeyRelatedPut(jsonTableObject.genDropTableQuery(),
1008 logger.info(EELFLoggerDelegate.applicationLogger, " Table deletion Process completed successfully ");
1014 public ResultType createIndex(JsonIndex jsonIndexObject, String consistencyInfo)
1015 throws MusicServiceException, MusicQueryException{
1016 ResultType result = nonKeyRelatedPut(jsonIndexObject.genCreateIndexQuery(),
1019 logger.info(EELFLoggerDelegate.applicationLogger, " Index creation Process completed successfully ");
1024 * This method performs DDL operation on cassandra.
1026 * @param queryObject query object containing prepared query and values
1028 * @throws MusicServiceException
1030 public ResultSet select(JsonSelect jsonSelect, MultivaluedMap<String, String> rowParams)
1031 throws MusicServiceException, MusicQueryException {
1032 ResultSet results = null;
1034 results = get(jsonSelect.genSelectQuery(rowParams));
1035 } catch (MusicServiceException e) {
1036 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
1037 throw new MusicServiceException(e.getMessage());
1045 public ResultSet selectCritical(JsonInsert jsonInsertObj, MultivaluedMap<String, String> rowParams)
1046 throws MusicLockingException, MusicQueryException, MusicServiceException {
1048 ResultSet results = null;
1049 String consistency = "";
1050 if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
1051 consistency = jsonInsertObj.getConsistencyInfo().get("type");
1054 String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
1056 PreparedQueryObject queryObject = jsonInsertObj.genSelectCriticalPreparedQueryObj(rowParams);
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);
1070 * this is insert row into Table
1072 public ReturnType insertIntoTable(JsonInsert jsonInsertObj)
1073 throws MusicLockingException, MusicQueryException, MusicServiceException {
1075 String consistency = "";
1076 if(null != jsonInsertObj && null != jsonInsertObj.getConsistencyInfo()) {
1077 consistency = jsonInsertObj.getConsistencyInfo().get("type");
1080 ReturnType result = null;
1084 PreparedQueryObject queryObj = null;
1085 queryObj = jsonInsertObj.genInsertPreparedQueryObj();
1087 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
1088 result = eventualPut(jsonInsertObj.genInsertPreparedQueryObj());
1089 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1090 String lockId = jsonInsertObj.getConsistencyInfo().get("lockId");
1091 if(lockId == null) {
1092 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1093 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1094 return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1095 + "and acquire lock or use ATOMIC instead of CRITICAL");
1097 result = criticalPut(jsonInsertObj.getKeyspaceName(),
1098 jsonInsertObj.getTableName(), jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), lockId,null);
1099 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1100 result = atomicPut(jsonInsertObj.getKeyspaceName(), jsonInsertObj.getTableName(),
1101 jsonInsertObj.getPrimaryKeyVal(), jsonInsertObj.genInsertPreparedQueryObj(), null);
1103 } catch (Exception ex) {
1104 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity
1105 .WARN, ErrorTypes.MUSICSERVICEERROR, ex);
1106 return new ReturnType(ResultType.FAILURE, ex.getMessage());
1113 * This is insert row into Table
1115 public ReturnType updateTable(JsonUpdate jsonUpdateObj, MultivaluedMap<String, String> rowParams)
1116 throws MusicLockingException, MusicQueryException, MusicServiceException {
1118 ReturnType result = null;
1119 String consistency = "";
1120 if(null != jsonUpdateObj && null != jsonUpdateObj.getConsistencyInfo()) {
1121 consistency = jsonUpdateObj.getConsistencyInfo().get("type");
1123 PreparedQueryObject queryObject = jsonUpdateObj.genUpdatePreparedQueryObj(rowParams);
1125 Condition conditionInfo;
1126 if (jsonUpdateObj.getConditions() == null) {
1127 conditionInfo = null;
1129 // to avoid parsing repeatedly, just send the select query to obtain row
1130 PreparedQueryObject selectQuery = new PreparedQueryObject();
1131 selectQuery.appendQueryString("SELECT * FROM " + jsonUpdateObj.getKeyspaceName() + "." + jsonUpdateObj.getTableName() + " WHERE "
1132 + jsonUpdateObj.getRowIdString() + ";");
1133 selectQuery.addValue(jsonUpdateObj.getPrimarKeyValue());
1134 conditionInfo = new Condition(jsonUpdateObj.getConditions(), selectQuery);
1138 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL)) {
1139 result = eventualPut(queryObject);
1140 } else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1141 String lockId = jsonUpdateObj.getConsistencyInfo().get("lockId");
1142 if(lockId == null) {
1143 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1144 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1146 return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1147 + "and acquire lock or use ATOMIC instead of CRITICAL");
1149 result = criticalPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
1150 queryObject, lockId, conditionInfo);
1151 } else if (consistency.equalsIgnoreCase("atomic_delete_lock")) {
1152 // this function is mainly for the benchmarks
1154 result = atomicPutWithDeleteLock(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(),
1155 jsonUpdateObj.getPrimarKeyValue(), queryObject, conditionInfo);
1156 } catch (MusicLockingException e) {
1157 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN,
1158 ErrorTypes.GENERALSERVICEERROR, e);
1159 throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
1162 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1164 result = atomicPut(jsonUpdateObj.getKeyspaceName(), jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue(),
1165 queryObject, conditionInfo);
1166 } catch (MusicLockingException e) {
1167 logger.error(EELFLoggerDelegate.errorLogger,e, AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR, e);
1168 throw new MusicLockingException(AppMessages.UNKNOWNERROR.toString());
1170 } else if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1172 result = eventualPut_nb(queryObject, jsonUpdateObj.getKeyspaceName(),
1173 jsonUpdateObj.getTableName(), jsonUpdateObj.getPrimarKeyValue());
1174 }catch (Exception e) {
1175 return new ReturnType(ResultType.FAILURE, e.getMessage());
1184 * This method is for Delete From Table
1186 public ReturnType deleteFromTable(JsonDelete jsonDeleteObj, MultivaluedMap<String, String> rowParams)
1187 throws MusicLockingException, MusicQueryException, MusicServiceException {
1189 ReturnType result = null;
1190 String consistency = "";
1191 if(null != jsonDeleteObj && null != jsonDeleteObj.getConsistencyInfo()) {
1192 consistency = jsonDeleteObj.getConsistencyInfo().get("type");
1194 PreparedQueryObject queryObject = jsonDeleteObj.genDeletePreparedQueryObj(rowParams);
1196 // get the conditional, if any
1197 Condition conditionInfo;
1198 if (jsonDeleteObj.getConditions() == null) {
1199 conditionInfo = null;
1201 // to avoid parsing repeatedly, just send the select query to obtain row
1202 PreparedQueryObject selectQuery = new PreparedQueryObject();
1203 selectQuery.appendQueryString("SELECT * FROM " + jsonDeleteObj.getKeyspaceName() + "." + jsonDeleteObj.getTableName() + " WHERE "
1204 + jsonDeleteObj.getRowIdString() + ";");
1205 selectQuery.addValue(jsonDeleteObj.getPrimarKeyValue());
1206 conditionInfo = new Condition(jsonDeleteObj.getConditions(), selectQuery);
1209 if (consistency.equalsIgnoreCase(MusicUtil.EVENTUAL))
1210 result = eventualPut(queryObject);
1211 else if (consistency.equalsIgnoreCase(MusicUtil.CRITICAL)) {
1212 String lockId = jsonDeleteObj.getConsistencyInfo().get("lockId");
1213 if(lockId == null) {
1214 logger.error(EELFLoggerDelegate.errorLogger,"LockId cannot be null. Create lock reference or"
1215 + " use ATOMIC instead of CRITICAL", ErrorSeverity.FATAL, ErrorTypes.MUSICSERVICEERROR);
1217 return new ReturnType(ResultType.FAILURE, "LockId cannot be null. Create lock "
1218 + "and acquire lock or use ATOMIC instead of CRITICAL");
1220 result = criticalPut(jsonDeleteObj.getKeyspaceName(),
1221 jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
1222 queryObject, lockId, conditionInfo);
1223 } else if (consistency.equalsIgnoreCase(MusicUtil.ATOMIC)) {
1224 result = atomicPut(jsonDeleteObj.getKeyspaceName(),
1225 jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue(),
1226 queryObject, conditionInfo);
1227 } else if(consistency.equalsIgnoreCase(MusicUtil.EVENTUAL_NB)) {
1228 result = eventualPut_nb(queryObject, jsonDeleteObj.getKeyspaceName(),
1229 jsonDeleteObj.getTableName(), jsonDeleteObj.getPrimarKeyValue());