X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Fmusic%2Fmain%2FMusicCore.java;h=9f7b060b8b3ce325546f63a5524d6b4248dcc1d2;hb=f1169764cd4cd389882ad09dcaca0cc9c0d94efe;hp=592bae92ab99aac3bdfc780869e4affe1a2110b5;hpb=e99b7fa829bf957c2a46223a1a20a32aebeda91b;p=music.git diff --git a/src/main/java/org/onap/music/main/MusicCore.java b/src/main/java/org/onap/music/main/MusicCore.java index 592bae92..9f7b060b 100644 --- a/src/main/java/org/onap/music/main/MusicCore.java +++ b/src/main/java/org/onap/music/main/MusicCore.java @@ -26,18 +26,23 @@ import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; + +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.KeeperException.NoNodeException; import org.onap.music.datastore.MusicDataStore; import org.onap.music.datastore.PreparedQueryObject; import org.onap.music.datastore.jsonobjects.JsonKeySpace; -// import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.EELFLoggerDelegate; +import org.onap.music.eelf.logging.format.AppMessages; +import org.onap.music.eelf.logging.format.ErrorSeverity; +import org.onap.music.eelf.logging.format.ErrorTypes; import org.onap.music.exceptions.MusicLockingException; import org.onap.music.exceptions.MusicQueryException; import org.onap.music.exceptions.MusicServiceException; import org.onap.music.lockingservice.MusicLockState; import org.onap.music.lockingservice.MusicLockState.LockStatus; import org.onap.music.lockingservice.MusicLockingService; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; + import com.datastax.driver.core.ColumnDefinitions; import com.datastax.driver.core.ColumnDefinitions.Definition; import com.datastax.driver.core.DataType; @@ -54,42 +59,43 @@ public class MusicCore { public static MusicLockingService mLockHandle = null; public static MusicDataStore mDstoreHandle = null; - private static EELFLogger logger = EELFManager.getInstance().getLogger(MusicCore.class); + private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class); public static class Condition { Map conditions; - String selectQueryForTheRow; + PreparedQueryObject selectQueryForTheRow; - public Condition(Map conditions, String selectQueryForTheRow) { + public Condition(Map conditions, PreparedQueryObject selectQueryForTheRow) { this.conditions = conditions; this.selectQueryForTheRow = selectQueryForTheRow; } - public boolean testCondition() { + public boolean testCondition() throws Exception { // first generate the row - PreparedQueryObject query = new PreparedQueryObject(); - query.appendQueryString(selectQueryForTheRow); - ResultSet results = quorumGet(query); - Row row = results.one(); + ResultSet results = quorumGet(selectQueryForTheRow); + Row row = null; + if(results != null) { + row = results.one(); + } return getDSHandle().doesRowSatisfyCondition(row, conditions); } } public static MusicLockingService getLockingServiceHandle() throws MusicLockingException { - logger.info("Acquiring lock store handle"); + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle"); long start = System.currentTimeMillis(); if (mLockHandle == null) { try { mLockHandle = new MusicLockingService(); } catch (Exception e) { - logger.error("Failed to aquire Locl store handle" + e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); throw new MusicLockingException("Failed to aquire Locl store handle " + e); } } long end = System.currentTimeMillis(); - logger.info("Time taken to acquire lock store handle:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms"); return mLockHandle; } @@ -99,42 +105,55 @@ public class MusicCore { * @return */ public static MusicDataStore getDSHandle(String remoteIp) { - logger.info("Acquiring data store handle"); + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle"); long start = System.currentTimeMillis(); if (mDstoreHandle == null) { mDstoreHandle = new MusicDataStore(remoteIp); } long end = System.currentTimeMillis(); - logger.info("Time taken to acquire data store handle:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); return mDstoreHandle; } /** * * @return + * @throws MusicServiceException */ - public static MusicDataStore getDSHandle() { - logger.info("Acquiring data store handle"); + public static MusicDataStore getDSHandle() throws MusicServiceException { + logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle"); long start = System.currentTimeMillis(); if (mDstoreHandle == null) { - mDstoreHandle = new MusicDataStore(); + // Quick Fix - Best to put this into every call to getDSHandle? + if (! "localhost".equals(MusicUtil.getMyCassaHost())) { + mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost()); + } else { + mDstoreHandle = new MusicDataStore(); + } + } + if(mDstoreHandle.getSession() == null) { + String message = "Connection to Cassandra has not been enstablished." + + " Please check connection properites and reboot."; + logger.info(EELFLoggerDelegate.applicationLogger, message); + throw new MusicServiceException(message); } long end = System.currentTimeMillis(); - logger.info("Time taken to acquire data store handle:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms"); return mDstoreHandle; } public static String createLockReference(String lockName) { - logger.info("Creating lock reference for lock name:" + lockName); + logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName); long start = System.currentTimeMillis(); String lockId = null; try { lockId = getLockingServiceHandle().createLockId("/" + lockName); } catch (MusicLockingException e) { - logger.error("Failed to create Lock Reference " + lockName); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } long end = System.currentTimeMillis(); - logger.info("Time taken to create lock reference:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms"); return lockId; } @@ -167,10 +186,10 @@ public class MusicCore { String lockName = keyspaceName + "." + tableName + "." + primaryKey; mls = getLockingServiceHandle().getLockState(lockName); long end = System.currentTimeMillis(); - logger.info("Time taken to get lock state:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms"); return mls; } catch (NullPointerException | MusicLockingException e) { - logger.error("No lock object exists as of now.." + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } return null; } @@ -182,12 +201,12 @@ public class MusicCore { MusicLockState mls = getMusicLockState(key); if (mls != null) { if (mls.getLockStatus().equals(LockStatus.LOCKED)) { - logger.info("The current lock holder for " + key + " is " + mls.getLockHolder() + logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder() + ". Checking if it has exceeded lease"); long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime(); long currentLeasePeriod = mls.getLeasePeriod(); if (currentLockPeriod > currentLeasePeriod) { - logger.info("Lock period " + currentLockPeriod + logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod + " has exceeded lease period " + currentLeasePeriod); boolean voluntaryRelease = false; String currentLockHolder = mls.getLockHolder(); @@ -195,37 +214,42 @@ public class MusicCore { } } } else - logger.debug("There is no lock state object for " + key); - + logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + /* * call the traditional acquire lock now and if the result returned is true, set the * begin time-stamp and lease period */ - if (acquireLock(key, lockId) == true) { + if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) { mls = getMusicLockState(key);// get latest state + if ( mls == null ) { + logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null"); + return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null"); + } if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already mls.setLeaseStartTime(System.currentTimeMillis()); mls.setLeasePeriod(leasePeriod); getLockingServiceHandle().setLockState(key, mls); } long end = System.currentTimeMillis(); - logger.info("Time taken to acquire leased lock:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms"); return new ReturnType(ResultType.SUCCESS, "Accquired lock"); } else { long end = System.currentTimeMillis(); - logger.info("Time taken to fail to acquire leased lock:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms"); return new ReturnType(ResultType.FAILURE, "Could not acquire lock"); } } catch (Exception e) { StringWriter sw = new StringWriter(); - logger.error(e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + String exceptionAsString = sw.toString(); return new ReturnType(ResultType.FAILURE, "Exception thrown in acquireLockWithLease:\n" + exceptionAsString); } } - public static boolean acquireLock(String key, String lockId) { + public static ReturnType acquireLock(String key, String lockId) throws MusicLockingException { /* * first check if I am on top. Since ids are not reusable there is no need to check * lockStatus If the status is unlocked, then the above call will automatically return @@ -235,19 +259,30 @@ public class MusicCore { try { result = getLockingServiceHandle().isMyTurn(lockId); } catch (MusicLockingException e2) { - logger.error("Failed to aquireLock lockId " + lockId + " " + e2); + logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2); + throw new MusicLockingException(); } - if (result == false) { - logger.info("In acquire lock: Not your turn, someone else has the lock"); - return false; + if (!result) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock"); + try { + if (!getLockingServiceHandle().lockIdExists(lockId)) { + logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist"); + return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist"); + } + } catch (MusicLockingException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException(); + } + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure"); + return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock"); } // this is for backward compatibility where locks could also be acquired on just // keyspaces or tables. - if (isTableOrKeySpaceLock(key) == true) { - logger.info("In acquire lock: A table or keyspace lock so no need to perform sync...so returning true"); - return true; + if (isTableOrKeySpaceLock(key)) { + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true"); + return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true"); } // read the lock name corresponding to the key and if the status is locked or being locked, @@ -256,13 +291,14 @@ public class MusicCore { MusicLockState newMls = null; try { currentMls = getMusicLockState(key); - String currentLockHolder = currentMls.getLockHolder(); + String currentLockHolder = null; + if(currentMls != null) { currentLockHolder = currentMls.getLockHolder(); }; if (lockId.equals(currentLockHolder)) { - logger.info("In acquire lock: You already have the lock!"); - return true; + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!"); + return new ReturnType(ResultType.SUCCESS, "You already have the lock!"); } } catch (NullPointerException e) { - logger.error("In acquire lock:No one has tried to acquire the lock yet.."); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } // change status to "being locked". This state transition is necessary to ensure syncing @@ -278,14 +314,18 @@ public class MusicCore { try { getLockingServiceHandle().setLockState(key, newMls); } catch (MusicLockingException e1) { - logger.error("Failed to set Lock state " + key + " " + e1); + logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } - logger.info("In acquire lock: Set lock state to being_locked"); + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked"); // do syncing if this was a forced lock release if (needToSyncQuorum) { - logger.info("In acquire lock: Since there was a forcible release, need to sync quorum!"); - syncQuorum(key); + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!"); + try { + syncQuorum(key); + } catch (Exception e) { + logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e); + } } // change status to locked @@ -295,11 +335,12 @@ public class MusicCore { try { getLockingServiceHandle().setLockState(key, newMls); } catch (MusicLockingException e) { - logger.error("Failed to set Lock state " + key + " " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } - logger.info("In acquire lock: Set lock state to locked and assigned current lock ref " + logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref " + lockId + " as holder"); - return result; + + return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder"); } @@ -316,8 +357,8 @@ public class MusicCore { } - private static void syncQuorum(String key) { - logger.info("Performing sync operation---"); + private static void syncQuorum(String key) throws Exception { + logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---"); String[] splitString = key.split("\\."); String keyspaceName = splitString[0]; String tableName = splitString[1]; @@ -330,15 +371,13 @@ public class MusicCore { String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single // primary key DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType(); - String cqlFormattedPrimaryKeyValue = - MusicUtil.convertToCQLDataType(primaryKeyType, primaryKeyValue); + Object cqlFormattedPrimaryKeyValue = + MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue); // get the row of data from a quorum selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE " + primaryKeyName + "= ?" + ";"); selectQuery.addValue(cqlFormattedPrimaryKeyValue); - // String selectQuery = "SELECT * FROM "+keyspaceName+"."+tableName+ " WHERE - // "+primaryKeyName+"="+cqlFormattedPrimaryKeyValue+";"; ResultSet results = null; try { results = getDSHandle().executeCriticalGet(selectQuery); @@ -347,7 +386,6 @@ public class MusicCore { ColumnDefinitions colInfo = row.getColumnDefinitions(); int totalColumns = colInfo.size(); int counter = 1; - // String fieldValueString=""; StringBuilder fieldValueString = new StringBuilder(""); for (Definition definition : colInfo) { String colName = definition.getName(); @@ -355,8 +393,7 @@ public class MusicCore { continue; DataType colType = definition.getType(); Object valueObj = getDSHandle().getColValue(row, colName, colType); - String valueString = MusicUtil.convertToCQLDataType(colType, valueObj); - // fieldValueString = fieldValueString+ colName+"="+valueString; + Object valueString = MusicUtil.convertToActualDataType(colType, valueObj); fieldValueString.append(colName + " = ?"); updateQuery.addValue(valueString); if (counter != (totalColumns - 1)) @@ -366,54 +403,15 @@ public class MusicCore { updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET " + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";"); updateQuery.addValue(cqlFormattedPrimaryKeyValue); - // String updateQuery = "UPDATE "+keyspaceName+"."+tableName+" SET "+fieldValueString+" - // WHERE "+primaryKeyName+"="+cqlFormattedPrimaryKeyValue+";"; getDSHandle().executePut(updateQuery, "critical"); } catch (MusicServiceException | MusicQueryException e) { - logger.error("Failed to execute update query " + updateQuery + " " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR); } } - /** - * this function is mainly for the benchmarks to see the effect of lock deletion. - * - * @param keyspaceName - * @param tableName - * @param primaryKey - * @param queryObject - * @param conditionInfo - * @return - */ - public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, - String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) { - long start = System.currentTimeMillis(); - String key = keyspaceName + "." + tableName + "." + primaryKey; - String lockId = createLockReference(key); - long lockCreationTime = System.currentTimeMillis(); - long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); - ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod); - long lockAcqTime = System.currentTimeMillis(); - if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { - logger.info("acquired lock with id " + lockId); - ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, - queryObject, lockId, conditionInfo); - long criticalPutTime = System.currentTimeMillis(); - deleteLock(key); - long lockDeleteTime = System.currentTimeMillis(); - String timingInfo = "|lock creation time:" + (lockCreationTime - start) - + "|lock accquire time:" + (lockAcqTime - lockCreationTime) - + "|critical put time:" + (criticalPutTime - lockAcqTime) - + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|"; - criticalPutResult.setTimingInfo(timingInfo); - return criticalPutResult; - } else { - logger.info("unable to acquire lock, id " + lockId); - deleteLock(key); - return lockAcqResult; - } - } + /** * @@ -425,7 +423,8 @@ public class MusicCore { try { results = getDSHandle().executeCriticalGet(query); } catch (MusicServiceException | MusicQueryException e) { - logger.error(e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR); + } return results; @@ -435,8 +434,9 @@ public class MusicCore { * * @param results * @return + * @throws MusicServiceException */ - public static Map> marshallResults(ResultSet results) { + public static Map> marshallResults(ResultSet results) throws MusicServiceException { return getDSHandle().marshalData(results); } @@ -450,7 +450,7 @@ public class MusicCore { try { return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + ""; } catch (MusicLockingException e) { - logger.error("Failed whoseTurnIsIt " + lockName + " " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } return null; @@ -471,11 +471,11 @@ public class MusicCore { long start = System.currentTimeMillis(); try { getLockingServiceHandle().unlockAndDeleteId(lockId); - } catch (MusicLockingException e) { - logger.error("Failed to Destroy Lock Ref " + lockId + " " + e); - } + } catch (MusicLockingException | NoNodeException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } long end = System.currentTimeMillis(); - logger.info("Time taken to destroy lock reference:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms"); } public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) { @@ -483,44 +483,58 @@ public class MusicCore { try { getLockingServiceHandle().unlockAndDeleteId(lockId); } catch (MusicLockingException e1) { - logger.error("Failed to release Lock " + lockId + " " + e1); + logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + } catch (KeeperException.NoNodeException nne) { + logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockId + " " + nne); + MusicLockState mls = new MusicLockState("Lock doesn't exists. Release lock operation failed."); + return mls; } String lockName = getLockNameFromId(lockId); MusicLockState mls; String lockHolder = null; if (voluntaryRelease) { mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder); - logger.info("In unlock: lock voluntarily released for " + lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId); } else { boolean needToSyncQuorum = true; mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder, needToSyncQuorum); - logger.info("In unlock: lock forcibly released for " + lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId); } try { getLockingServiceHandle().setLockState(lockName, mls); } catch (MusicLockingException e) { - logger.error("Failed to release Lock " + lockName + " " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } long end = System.currentTimeMillis(); - logger.info("Time taken to release lock:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms"); return mls; } + + public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{ + try { + getLockingServiceHandle().unlockAndDeleteId(lockId); + } catch (KeeperException.NoNodeException e) { + // ??? No way + } + } /** * * @param lockName + * @throws MusicLockingException */ - public static void deleteLock(String lockName) { + public static void deleteLock(String lockName) throws MusicLockingException { long start = System.currentTimeMillis(); - logger.info("Deleting lock for " + lockName); + logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName); try { getLockingServiceHandle().deleteLock("/" + lockName); } catch (MusicLockingException e) { - logger.error("Failed to Delete Lock " + lockName + " " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); + throw new MusicLockingException(e.getMessage()); } long end = System.currentTimeMillis(); - logger.info("Time taken to delete lock:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms"); } @@ -530,8 +544,9 @@ public class MusicCore { * @param keyspace * @param tablename * @return + * @throws MusicServiceException */ - public static TableMetadata returnColumnMetadata(String keyspace, String tablename) { + public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException { return getDSHandle().returnColumnMetadata(keyspace, tablename); } @@ -544,7 +559,7 @@ public class MusicCore { try { getLockingServiceHandle().getzkLockHandle().createNode(nodeName); } catch (MusicLockingException e) { - logger.error("Failed to get ZK Lock Handle " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } } @@ -555,15 +570,15 @@ public class MusicCore { */ public static void pureZkWrite(String nodeName, byte[] data) { long start = System.currentTimeMillis(); - logger.info("Performing zookeeper write to " + nodeName); + logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName); try { getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data); } catch (MusicLockingException e) { - logger.error("Failed to get ZK Lock Handle " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } - logger.info("Performed zookeeper write to " + nodeName); + logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName); long end = System.currentTimeMillis(); - logger.info("Time taken for the actual zk put:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms"); } /** @@ -577,10 +592,10 @@ public class MusicCore { try { data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName); } catch (MusicLockingException e) { - logger.error("Failed to get ZK Lock Handle " + e); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR); } long end = System.currentTimeMillis(); - logger.info("Time taken for the actual zk put:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms"); return data; } @@ -602,7 +617,9 @@ public class MusicCore { try { result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL); } catch (MusicServiceException | MusicQueryException ex) { - logger.error(ex.getMessage() + " " + ex.getCause() + " " + ex); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex); + return new ReturnType(ResultType.FAILURE, ex.getMessage()); } if (result) { return new ReturnType(ResultType.SUCCESS, "Success"); @@ -628,22 +645,30 @@ public class MusicCore { MusicLockState mls = getLockingServiceHandle() .getLockState(keyspaceName + "." + tableName + "." + primaryKey); if (mls.getLockHolder().equals(lockId) == true) { - if (conditionInfo != null)// check if condition is true + if (conditionInfo != null) + try { if (conditionInfo.testCondition() == false) return new ReturnType(ResultType.FAILURE, "Lock acquired but the condition is not true"); + } catch (Exception e) { + return new ReturnType(ResultType.FAILURE, + "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n" + + e.getMessage()); + } getDSHandle().executePut(queryObject, MusicUtil.CRITICAL); long end = System.currentTimeMillis(); - logger.info("Time taken for the critical put:" + (end - start) + " ms"); + logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms"); return new ReturnType(ResultType.SUCCESS, "Update performed"); } else return new ReturnType(ResultType.FAILURE, "Cannot perform operation since you are the not the lock holder"); - } catch (MusicQueryException | MusicServiceException | MusicLockingException e) { - logger.error(e.getMessage()); + } catch (MusicQueryException | MusicServiceException e) { + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); return new ReturnType(ResultType.FAILURE, "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n" + e.getMessage()); + }catch(MusicLockingException ex){ + return new ReturnType(ResultType.FAILURE,ex.getMessage()); } } @@ -653,19 +678,21 @@ public class MusicCore { * @param queryObject * @param consistency * @return Boolean Indicates success or failure + * @throws MusicServiceException * * */ - public static boolean nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) { + public static ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException { // this is mainly for some functions like keyspace creation etc which does not // really need the bells and whistles of Music locking. boolean result = false; try { result = getDSHandle().executePut(queryObject, consistency); } catch (MusicQueryException | MusicServiceException ex) { - logger.error(ex.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); + throw new MusicServiceException(ex.getMessage()); } - return result; + return result?ResultType.SUCCESS:ResultType.FAILURE; } /** @@ -673,16 +700,34 @@ public class MusicCore { * * @param queryObject query object containing prepared query and values * @return ResultSet + * @throws MusicServiceException */ - public static ResultSet get(PreparedQueryObject queryObject) { + public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException { ResultSet results = null; try { - results = getDSHandle().executeEventualGet(queryObject); + results = getDSHandle().executeEventualGet(queryObject); } catch (MusicQueryException | MusicServiceException e) { - logger.error(e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + throw new MusicServiceException(e.getMessage()); } return results; } + + public static String getMyHostId() { + PreparedQueryObject pQuery = new PreparedQueryObject(); + pQuery.appendQueryString("SELECT HOST_ID FROM SYSTEM.LOCAL"); + ResultSet rs = null; + try { + rs = getDSHandle().executeEventualGet(pQuery); + Row row = rs.one(); + return (row == null) ? "UNKNOWN" : row.getUUID("HOST_ID").toString(); + } catch (Exception e) { + e.printStackTrace(); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage()); + } + logger.error(EELFLoggerDelegate.errorLogger, "Some issue during MusicCore.getMyHostId"); + return "UNKNOW"; + } /** * This method performs DDL operations on cassandra, if the the resource is available. Lock ID @@ -706,7 +751,7 @@ public class MusicCore { } else throw new MusicServiceException("YOU DO NOT HAVE THE LOCK"); } catch (MusicQueryException | MusicServiceException | MusicLockingException e) { - logger.error(e.getMessage()); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR); } return results; } @@ -719,22 +764,63 @@ public class MusicCore { * @param primaryKey primary key value * @param queryObject query object containing prepared query and values * @return ReturnType + * @throws MusicLockingException */ public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject, Condition conditionInfo) { + PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { + + long start = System.currentTimeMillis(); + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long lockCreationTime = System.currentTimeMillis(); + ReturnType lockAcqResult = acquireLock(key, lockId); + long lockAcqTime = System.currentTimeMillis(); + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); + ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, + queryObject, lockId, conditionInfo); + long criticalPutTime = System.currentTimeMillis(); + voluntaryReleaseLock(lockId); + long lockDeleteTime = System.currentTimeMillis(); + String timingInfo = "|lock creation time:" + (lockCreationTime - start) + + "|lock accquire time:" + (lockAcqTime - lockCreationTime) + + "|critical put time:" + (criticalPutTime - lockAcqTime) + + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|"; + criticalPutResult.setTimingInfo(timingInfo); + return criticalPutResult; + } else { + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + destroyLockRef(lockId); + return lockAcqResult; + } + } + + /** + * this function is mainly for the benchmarks to see the effect of lock deletion. + * + * @param keyspaceName + * @param tableName + * @param primaryKey + * @param queryObject + * @param conditionInfo + * @return + * @throws MusicLockingException + */ + public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName, + String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException { + long start = System.currentTimeMillis(); String key = keyspaceName + "." + tableName + "." + primaryKey; String lockId = createLockReference(key); long lockCreationTime = System.currentTimeMillis(); long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); - ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod); + ReturnType lockAcqResult = acquireLock(key, lockId); long lockAcqTime = System.currentTimeMillis(); if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { - logger.info("acquired lock with id " + lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey, queryObject, lockId, conditionInfo); long criticalPutTime = System.currentTimeMillis(); - boolean voluntaryRelease = true; deleteLock(key); long lockDeleteTime = System.currentTimeMillis(); String timingInfo = "|lock creation time:" + (lockCreationTime - start) @@ -744,11 +830,13 @@ public class MusicCore { criticalPutResult.setTimingInfo(timingInfo); return criticalPutResult; } else { - logger.info("unable to acquire lock, id " + lockId); - destroyLockRef(lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); + deleteLock(key); return lockAcqResult; } } + + /** @@ -760,25 +848,48 @@ public class MusicCore { * @param queryObject query object containing prepared query and values * @return ResultSet * @throws MusicServiceException + * @throws MusicLockingException */ public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey, - PreparedQueryObject queryObject) throws MusicServiceException { + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException { String key = keyspaceName + "." + tableName + "." + primaryKey; String lockId = createLockReference(key); long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); - ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod); + ReturnType lockAcqResult = acquireLock(key, lockId); if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { - logger.info("acquired lock with id " + lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId); ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId); - boolean voluntaryRelease = true; - releaseLock(lockId, voluntaryRelease); + voluntaryReleaseLock(lockId); return result; } else { - logger.info("unable to acquire lock, id " + lockId); + destroyLockRef(lockId); + logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId); return null; } } + + public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey, + PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException { + String key = keyspaceName + "." + tableName + "." + primaryKey; + String lockId = createLockReference(key); + long leasePeriod = MusicUtil.getDefaultLockLeasePeriod(); + + ReturnType lockAcqResult = acquireLock(key, lockId); + + if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) { + logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId); + ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId); + deleteLock(key); + return result; + } else { + deleteLock(key); + logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId); + return null; + } + } + + /** * authenticate user logic @@ -801,32 +912,45 @@ public class MusicCore { operation); if (!resultMap.isEmpty()) return resultMap; - if (aid == null && (userId == null || password == null)) { - logger.error("One or more required headers is missing. userId: " + userId + String isAAFApp = null; + try { + isAAFApp= CachingUtil.isAAFApplication(nameSpace); + } catch(MusicServiceException e) { + resultMap.put("Exception", e.getMessage()); + return resultMap; + } + if(isAAFApp == null) { + resultMap.put("Exception", "Namespace: "+nameSpace+" doesn't exist. Please make sure ns(appName)" + + " is correct and Application is onboarded."); + return resultMap; + } + boolean isAAF = Boolean.valueOf(isAAFApp); + if (userId == null || password == null) { + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId + " :: password: " + password); resultMap.put("Exception", "UserId and Password are mandatory for the operation " + operation); return resultMap; } - boolean isAAF = CachingUtil.isAAFApplication(nameSpace); - if (!isAAF && aid != null && aid.length() > 0) { // Non AAF app - resultMap = CachingUtil.authenticateAIDUser(aid, keyspace); + if(!isAAF && !(operation.equals("createKeySpace"))) { + resultMap = CachingUtil.authenticateAIDUser(nameSpace, userId, password, keyspace); if (!resultMap.isEmpty()) return resultMap; + } if (isAAF && nameSpace != null && userId != null && password != null) { boolean isValid = true; try { - isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace); + isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace); } catch (Exception e) { - logger.error("Got exception while AAF authentication for namespace " + nameSpace); + logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); + logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace); resultMap.put("Exception", e.getMessage()); - // return resultMap; } if (!isValid) { - logger.error("User not authenticated with AAF."); + logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR); resultMap.put("Exception", "User not authenticated..."); - // return resultMap; } if (!resultMap.isEmpty()) return resultMap; @@ -834,7 +958,7 @@ public class MusicCore { } if (operation.equals("createKeySpace")) { - logger.info("AID is not provided. Creating new UUID for keyspace."); + logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace."); PreparedQueryObject pQuery = new PreparedQueryObject(); pQuery.appendQueryString( "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering"); @@ -848,27 +972,31 @@ public class MusicCore { uuid = rs.getUUID("uuid").toString(); resultMap.put("uuid", "existing"); } catch (Exception e) { - logger.info("No UUID found in DB. So creating new UUID."); + logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID."); uuid = CachingUtil.generateUUID(); resultMap.put("uuid", "new"); } - - pQuery = new PreparedQueryObject(); - pQuery.appendQueryString( - "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, " - + "password, username, is_aaf) values (?,?,?,?,?,?,?)"); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True")); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId)); - pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF)); - CachingUtil.updateMusicCache(uuid, keyspace); - MusicCore.eventualPut(pQuery); resultMap.put("aid", uuid); } return resultMap; } + + /** + * @param lockName + * @return + */ + public static Map validateLock(String lockName) { + Map resultMap = new HashMap<>(); + String[] locks = lockName.split("\\."); + if(locks.length < 3) { + resultMap.put("Exception", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey"); + return resultMap; + } + String keyspace= locks[0]; + if(keyspace.startsWith("$")) + keyspace = keyspace.substring(1); + resultMap.put("keyspace",keyspace); + return resultMap; + } }