2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (c) 2017 AT&T Intellectual Property
6 * ===================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * ============LICENSE_END=============================================
20 * ====================================================================
22 package org.onap.music.main;
25 import java.io.StringWriter;
26 import java.util.HashMap;
28 import java.util.StringTokenizer;
30 import org.onap.music.datastore.MusicDataStore;
31 import org.onap.music.datastore.PreparedQueryObject;
32 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
33 import org.onap.music.eelf.logging.EELFLoggerDelegate;
34 import org.onap.music.eelf.logging.format.AppMessages;
35 import org.onap.music.eelf.logging.format.ErrorSeverity;
36 import org.onap.music.eelf.logging.format.ErrorTypes;
37 import org.onap.music.exceptions.MusicLockingException;
38 import org.onap.music.exceptions.MusicQueryException;
39 import org.onap.music.exceptions.MusicServiceException;
40 import org.onap.music.lockingservice.MusicLockState;
41 import org.onap.music.lockingservice.MusicLockState.LockStatus;
42 import org.onap.music.lockingservice.MusicLockingService;
44 import com.datastax.driver.core.ColumnDefinitions;
45 import com.datastax.driver.core.ColumnDefinitions.Definition;
46 import com.datastax.driver.core.DataType;
47 import com.datastax.driver.core.ResultSet;
48 import com.datastax.driver.core.Row;
49 import com.datastax.driver.core.TableMetadata;
56 public class MusicCore {
58 public static MusicLockingService mLockHandle = null;
59 public static MusicDataStore mDstoreHandle = null;
60 private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class);
62 public static class Condition {
63 Map<String, Object> conditions;
64 PreparedQueryObject selectQueryForTheRow;
66 public Condition(Map<String, Object> conditions, PreparedQueryObject selectQueryForTheRow) {
67 this.conditions = conditions;
68 this.selectQueryForTheRow = selectQueryForTheRow;
71 public boolean testCondition() throws Exception {
72 // first generate the row
73 ResultSet results = quorumGet(selectQueryForTheRow);
74 Row row = results.one();
75 return getDSHandle().doesRowSatisfyCondition(row, conditions);
80 public static MusicLockingService getLockingServiceHandle() throws MusicLockingException {
81 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
82 long start = System.currentTimeMillis();
84 if (mLockHandle == null) {
86 mLockHandle = new MusicLockingService();
87 } catch (Exception e) {
88 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
89 throw new MusicLockingException("Failed to aquire Locl store handle " + e);
92 long end = System.currentTimeMillis();
93 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
102 public static MusicDataStore getDSHandle(String remoteIp) {
103 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
104 long start = System.currentTimeMillis();
105 if (mDstoreHandle == null) {
106 mDstoreHandle = new MusicDataStore(remoteIp);
108 long end = System.currentTimeMillis();
109 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
110 return mDstoreHandle;
116 * @throws MusicServiceException
118 public static MusicDataStore getDSHandle() throws MusicServiceException {
119 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
120 long start = System.currentTimeMillis();
121 if (mDstoreHandle == null) {
122 // Quick Fix - Best to put this into every call to getDSHandle?
123 if (! MusicUtil.getMyCassaHost().equals("localhost") ) {
124 mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost());
126 mDstoreHandle = new MusicDataStore();
129 if(mDstoreHandle.getSession() == null) {
130 String message = "Connection to Cassandra has not been enstablished."
131 + " Please check connection properites and reboot.";
132 logger.info(EELFLoggerDelegate.applicationLogger, message);
133 throw new MusicServiceException(message);
135 long end = System.currentTimeMillis();
136 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
137 return mDstoreHandle;
140 public static String createLockReference(String lockName) {
141 logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
142 long start = System.currentTimeMillis();
143 String lockId = null;
145 lockId = getLockingServiceHandle().createLockId("/" + lockName);
146 } catch (MusicLockingException e) {
147 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
150 long end = System.currentTimeMillis();
151 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms");
160 public static boolean isTableOrKeySpaceLock(String key) {
161 String[] splitString = key.split("\\.");
162 if (splitString.length > 2)
173 public static MusicLockState getMusicLockState(String key) {
174 long start = System.currentTimeMillis();
176 String[] splitString = key.split("\\.");
177 String keyspaceName = splitString[0];
178 String tableName = splitString[1];
179 String primaryKey = splitString[2];
181 String lockName = keyspaceName + "." + tableName + "." + primaryKey;
182 mls = getLockingServiceHandle().getLockState(lockName);
183 long end = System.currentTimeMillis();
184 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms");
186 } catch (NullPointerException | MusicLockingException e) {
187 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
192 public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
194 long start = System.currentTimeMillis();
195 /* check if the current lock has exceeded its lease and if yes, release that lock */
196 MusicLockState mls = getMusicLockState(key);
198 if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
199 logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder()
200 + ". Checking if it has exceeded lease");
201 long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
202 long currentLeasePeriod = mls.getLeasePeriod();
203 if (currentLockPeriod > currentLeasePeriod) {
204 logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod
205 + " has exceeded lease period " + currentLeasePeriod);
206 boolean voluntaryRelease = false;
207 String currentLockHolder = mls.getLockHolder();
208 mls = releaseLock(currentLockHolder, voluntaryRelease);
212 logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
215 * call the traditional acquire lock now and if the result returned is true, set the
216 * begin time-stamp and lease period
218 if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) {
219 mls = getMusicLockState(key);// get latest state
221 logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null");
222 return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null");
224 if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
225 mls.setLeaseStartTime(System.currentTimeMillis());
226 mls.setLeasePeriod(leasePeriod);
227 getLockingServiceHandle().setLockState(key, mls);
229 long end = System.currentTimeMillis();
230 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms");
231 return new ReturnType(ResultType.SUCCESS, "Accquired lock");
233 long end = System.currentTimeMillis();
234 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms");
235 return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
237 } catch (Exception e) {
238 StringWriter sw = new StringWriter();
239 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
241 String exceptionAsString = sw.toString();
242 return new ReturnType(ResultType.FAILURE,
243 "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
247 public static ReturnType acquireLock(String key, String lockId) {
249 * first check if I am on top. Since ids are not reusable there is no need to check
250 * lockStatus If the status is unlocked, then the above call will automatically return
253 Boolean result = false;
255 result = getLockingServiceHandle().isMyTurn(lockId);
256 } catch (MusicLockingException e2) {
257 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2);
260 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock");
262 if (!getLockingServiceHandle().lockIdExists(lockId)) {
263 logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist");
264 return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist");
266 } catch (MusicLockingException e) {
267 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
269 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure");
270 return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock");
274 // this is for backward compatibility where locks could also be acquired on just
275 // keyspaces or tables.
276 if (isTableOrKeySpaceLock(key)) {
277 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
278 return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true");
281 // read the lock name corresponding to the key and if the status is locked or being locked,
283 MusicLockState currentMls = null;
284 MusicLockState newMls = null;
286 currentMls = getMusicLockState(key);
287 String currentLockHolder = currentMls.getLockHolder();
288 if (lockId.equals(currentLockHolder)) {
289 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!");
290 return new ReturnType(ResultType.SUCCESS, "You already have the lock!");
292 } catch (NullPointerException e) {
293 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
296 // change status to "being locked". This state transition is necessary to ensure syncing
297 // before granting the lock
298 String lockHolder = null;
299 boolean needToSyncQuorum = false;
300 if (currentMls != null)
301 needToSyncQuorum = currentMls.isNeedToSyncQuorum();
304 newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
307 getLockingServiceHandle().setLockState(key, newMls);
308 } catch (MusicLockingException e1) {
309 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
311 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked");
313 // do syncing if this was a forced lock release
314 if (needToSyncQuorum) {
315 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!");
318 } catch (Exception e) {
319 logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e);
323 // change status to locked
325 needToSyncQuorum = false;
326 newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
328 getLockingServiceHandle().setLockState(key, newMls);
329 } catch (MusicLockingException e) {
330 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
332 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref "
333 + lockId + " as holder");
335 return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder");
342 * @param keyspaceName
347 public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
352 private static void syncQuorum(String key) throws Exception {
353 logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
354 String[] splitString = key.split("\\.");
355 String keyspaceName = splitString[0];
356 String tableName = splitString[1];
357 String primaryKeyValue = splitString[2];
358 PreparedQueryObject selectQuery = new PreparedQueryObject();
359 PreparedQueryObject updateQuery = new PreparedQueryObject();
361 // get the primary key d
362 TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
363 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
365 DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
366 Object cqlFormattedPrimaryKeyValue =
367 MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
369 // get the row of data from a quorum
370 selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE "
371 + primaryKeyName + "= ?" + ";");
372 selectQuery.addValue(cqlFormattedPrimaryKeyValue);
373 ResultSet results = null;
375 results = getDSHandle().executeCriticalGet(selectQuery);
376 // write it back to a quorum
377 Row row = results.one();
378 ColumnDefinitions colInfo = row.getColumnDefinitions();
379 int totalColumns = colInfo.size();
381 StringBuilder fieldValueString = new StringBuilder("");
382 for (Definition definition : colInfo) {
383 String colName = definition.getName();
384 if (colName.equals(primaryKeyName))
386 DataType colType = definition.getType();
387 Object valueObj = getDSHandle().getColValue(row, colName, colType);
388 Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
389 fieldValueString.append(colName + " = ?");
390 updateQuery.addValue(valueString);
391 if (counter != (totalColumns - 1))
392 fieldValueString.append(",");
393 counter = counter + 1;
395 updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
396 + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
397 updateQuery.addValue(cqlFormattedPrimaryKeyValue);
399 getDSHandle().executePut(updateQuery, "critical");
400 } catch (MusicServiceException | MusicQueryException e) {
401 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR);
413 public static ResultSet quorumGet(PreparedQueryObject query) {
414 ResultSet results = null;
416 results = getDSHandle().executeCriticalGet(query);
417 } catch (MusicServiceException | MusicQueryException e) {
418 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR);
429 * @throws MusicServiceException
431 public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException {
432 return getDSHandle().marshalData(results);
440 public static String whoseTurnIsIt(String lockName) {
443 return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
444 } catch (MusicLockingException e) {
445 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
457 public static String getLockNameFromId(String lockId) {
458 StringTokenizer st = new StringTokenizer(lockId);
459 return st.nextToken("$");
462 public static void destroyLockRef(String lockId) {
463 long start = System.currentTimeMillis();
465 getLockingServiceHandle().unlockAndDeleteId(lockId);
466 } catch (MusicLockingException e) {
467 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
469 long end = System.currentTimeMillis();
470 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
473 public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
474 long start = System.currentTimeMillis();
476 getLockingServiceHandle().unlockAndDeleteId(lockId);
477 } catch (MusicLockingException e1) {
478 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
480 String lockName = getLockNameFromId(lockId);
482 String lockHolder = null;
483 if (voluntaryRelease) {
484 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
485 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId);
487 boolean needToSyncQuorum = true;
488 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
490 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId);
493 getLockingServiceHandle().setLockState(lockName, mls);
494 } catch (MusicLockingException e) {
495 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
497 long end = System.currentTimeMillis();
498 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms");
502 public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{
503 getLockingServiceHandle().unlockAndDeleteId(lockId);
510 public static void deleteLock(String lockName) {
511 long start = System.currentTimeMillis();
512 logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName);
514 getLockingServiceHandle().deleteLock("/" + lockName);
515 } catch (MusicLockingException e) {
516 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
518 long end = System.currentTimeMillis();
519 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms");
529 * @throws MusicServiceException
531 public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException {
532 return getDSHandle().returnColumnMetadata(keyspace, tablename);
540 public static void pureZkCreate(String nodeName) {
542 getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
543 } catch (MusicLockingException e) {
544 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
553 public static void pureZkWrite(String nodeName, byte[] data) {
554 long start = System.currentTimeMillis();
555 logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName);
557 getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
558 } catch (MusicLockingException e) {
559 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
561 logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName);
562 long end = System.currentTimeMillis();
563 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
571 public static byte[] pureZkRead(String nodeName) {
572 long start = System.currentTimeMillis();
575 data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
576 } catch (MusicLockingException e) {
577 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
579 long end = System.currentTimeMillis();
580 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
586 // Prepared Query Additions.
590 * @param keyspaceName
595 * @throws MusicServiceException
597 public static ReturnType eventualPut(PreparedQueryObject queryObject) {
598 boolean result = false;
600 result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
601 } catch (MusicServiceException | MusicQueryException ex) {
602 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
603 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex);
606 return new ReturnType(ResultType.SUCCESS, "Success");
608 return new ReturnType(ResultType.FAILURE, "Failure");
614 * @param keyspaceName
621 public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
622 PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
623 long start = System.currentTimeMillis();
626 MusicLockState mls = getLockingServiceHandle()
627 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
628 if (mls.getLockHolder().equals(lockId) == true) {
629 if (conditionInfo != null)
631 if (conditionInfo.testCondition() == false)
632 return new ReturnType(ResultType.FAILURE,
633 "Lock acquired but the condition is not true");
634 } catch (Exception e) {
635 return new ReturnType(ResultType.FAILURE,
636 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
639 getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
640 long end = System.currentTimeMillis();
641 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
642 return new ReturnType(ResultType.SUCCESS, "Update performed");
644 return new ReturnType(ResultType.FAILURE,
645 "Cannot perform operation since you are the not the lock holder");
646 } catch (MusicQueryException | MusicServiceException e) {
647 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
648 return new ReturnType(ResultType.FAILURE,
649 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
651 }catch(MusicLockingException ex){
652 return new ReturnType(ResultType.FAILURE,ex.getMessage());
661 * @return Boolean Indicates success or failure
662 * @throws MusicServiceException
666 public static boolean nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException {
667 // this is mainly for some functions like keyspace creation etc which does not
668 // really need the bells and whistles of Music locking.
669 boolean result = false;
671 result = getDSHandle().executePut(queryObject, consistency);
672 } catch (MusicQueryException | MusicServiceException ex) {
673 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
674 throw new MusicServiceException(ex.getMessage());
680 * This method performs DDL operation on cassandra.
682 * @param queryObject query object containing prepared query and values
684 * @throws MusicServiceException
686 public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
687 ResultSet results = null;
689 results = getDSHandle().executeEventualGet(queryObject);
690 } catch (MusicQueryException | MusicServiceException e) {
691 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
692 throw new MusicServiceException(e.getMessage());
698 * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
699 * is used to check if the resource is free.
701 * @param keyspaceName name of the keyspace
702 * @param tableName name of the table
703 * @param primaryKey primary key value
704 * @param queryObject query object containing prepared query and values
705 * @param lockId lock ID to check if the resource is free to perform the operation.
708 public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
709 PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
710 ResultSet results = null;
712 MusicLockState mls = getLockingServiceHandle()
713 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
714 if (mls.getLockHolder().equals(lockId)) {
715 results = getDSHandle().executeCriticalGet(queryObject);
717 throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
718 } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
719 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
725 * This method performs DML operation on cassandra, when the lock of the dd is acquired.
727 * @param keyspaceName name of the keyspace
728 * @param tableName name of the table
729 * @param primaryKey primary key value
730 * @param queryObject query object containing prepared query and values
732 * @throws MusicLockingException
734 public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
735 PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
737 long start = System.currentTimeMillis();
738 String key = keyspaceName + "." + tableName + "." + primaryKey;
739 String lockId = createLockReference(key);
740 long lockCreationTime = System.currentTimeMillis();
741 ReturnType lockAcqResult = acquireLock(key, lockId);
742 long lockAcqTime = System.currentTimeMillis();
743 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
744 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
745 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
746 queryObject, lockId, conditionInfo);
747 long criticalPutTime = System.currentTimeMillis();
748 voluntaryReleaseLock(lockId);
749 long lockDeleteTime = System.currentTimeMillis();
750 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
751 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
752 + "|critical put time:" + (criticalPutTime - lockAcqTime)
753 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
754 criticalPutResult.setTimingInfo(timingInfo);
755 return criticalPutResult;
757 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
758 destroyLockRef(lockId);
759 return lockAcqResult;
764 * this function is mainly for the benchmarks to see the effect of lock deletion.
766 * @param keyspaceName
770 * @param conditionInfo
772 * @throws MusicLockingException
774 public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
775 String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
777 long start = System.currentTimeMillis();
778 String key = keyspaceName + "." + tableName + "." + primaryKey;
779 String lockId = createLockReference(key);
780 long lockCreationTime = System.currentTimeMillis();
781 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
782 ReturnType lockAcqResult = acquireLock(key, lockId);
783 long lockAcqTime = System.currentTimeMillis();
784 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
785 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
786 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
787 queryObject, lockId, conditionInfo);
788 long criticalPutTime = System.currentTimeMillis();
790 long lockDeleteTime = System.currentTimeMillis();
791 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
792 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
793 + "|critical put time:" + (criticalPutTime - lockAcqTime)
794 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
795 criticalPutResult.setTimingInfo(timingInfo);
796 return criticalPutResult;
798 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
800 return lockAcqResult;
808 * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
810 * @param keyspaceName name of the keyspace
811 * @param tableName name of the table
812 * @param primaryKey primary key value
813 * @param queryObject query object containing prepared query and values
815 * @throws MusicServiceException
816 * @throws MusicLockingException
818 public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
819 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
820 String key = keyspaceName + "." + tableName + "." + primaryKey;
821 String lockId = createLockReference(key);
822 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
823 ReturnType lockAcqResult = acquireLock(key, lockId);
824 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
825 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
827 criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
828 voluntaryReleaseLock(lockId);
831 destroyLockRef(lockId);
832 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
837 public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
838 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
839 String key = keyspaceName + "." + tableName + "." + primaryKey;
840 String lockId = createLockReference(key);
841 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
843 ReturnType lockAcqResult = acquireLock(key, lockId);
845 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
846 logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
847 ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
852 logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
860 * authenticate user logic
871 public static Map<String, Object> autheticateUser(String nameSpace, String userId,
872 String password, String keyspace, String aid, String operation)
874 Map<String, Object> resultMap = new HashMap<>();
876 resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
878 if (!resultMap.isEmpty())
880 boolean isAAF = CachingUtil.isAAFApplication(nameSpace);
881 if (!isAAF && !(operation.equals("createKeySpace"))) {
883 resultMap.put("Exception", "Aid is mandatory for nonAAF applications ");
886 if(operation.contains("Lock")) {
887 resultMap = CachingUtil.authenticateAIDUserLock(aid, nameSpace);
890 resultMap = CachingUtil.authenticateAIDUser(aid, keyspace);
893 if (!resultMap.isEmpty())
896 if (aid == null && (userId == null || password == null)) {
897 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
898 logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
899 + " :: password: " + password);
900 resultMap.put("Exception",
901 "UserId and Password are mandatory for the operation " + operation);
905 if (isAAF && nameSpace != null && userId != null && password != null) {
906 boolean isValid = true;
908 isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
909 } catch (Exception e) {
910 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
911 logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
912 resultMap.put("Exception", e.getMessage());
915 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
916 resultMap.put("Exception", "User not authenticated...");
918 if (!resultMap.isEmpty())
923 if (operation.equals("createKeySpace")) {
924 logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
925 PreparedQueryObject pQuery = new PreparedQueryObject();
926 pQuery.appendQueryString(
927 "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
928 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
929 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
930 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
931 MusicUtil.DEFAULTKEYSPACENAME));
934 Row rs = MusicCore.get(pQuery).one();
935 uuid = rs.getUUID("uuid").toString();
936 resultMap.put("uuid", "existing");
937 } catch (Exception e) {
938 logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
939 uuid = CachingUtil.generateUUID();
940 resultMap.put("uuid", "new");
943 pQuery = new PreparedQueryObject();
944 pQuery.appendQueryString(
945 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
946 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
947 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
948 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
949 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
950 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
951 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
952 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
953 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
954 //CachingUtil.updateMusicCache(uuid, keyspace);
955 MusicCore.eventualPut(pQuery);
956 resultMap.put("aid", uuid);