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.apache.zookeeper.KeeperException;
31 import org.apache.zookeeper.KeeperException.NoNodeException;
32 import org.onap.music.datastore.MusicDataStore;
33 import org.onap.music.datastore.PreparedQueryObject;
34 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
35 import org.onap.music.eelf.logging.EELFLoggerDelegate;
36 import org.onap.music.eelf.logging.format.AppMessages;
37 import org.onap.music.eelf.logging.format.ErrorSeverity;
38 import org.onap.music.eelf.logging.format.ErrorTypes;
39 import org.onap.music.exceptions.MusicLockingException;
40 import org.onap.music.exceptions.MusicQueryException;
41 import org.onap.music.exceptions.MusicServiceException;
42 import org.onap.music.lockingservice.MusicLockState;
43 import org.onap.music.lockingservice.MusicLockState.LockStatus;
44 import org.onap.music.lockingservice.MusicLockingService;
46 import com.datastax.driver.core.ColumnDefinitions;
47 import com.datastax.driver.core.ColumnDefinitions.Definition;
48 import com.datastax.driver.core.DataType;
49 import com.datastax.driver.core.ResultSet;
50 import com.datastax.driver.core.Row;
51 import com.datastax.driver.core.TableMetadata;
58 public class MusicCore {
60 public static MusicLockingService mLockHandle = null;
61 public static MusicDataStore mDstoreHandle = null;
62 private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicCore.class);
64 public static class Condition {
65 Map<String, Object> conditions;
66 PreparedQueryObject selectQueryForTheRow;
68 public Condition(Map<String, Object> conditions, PreparedQueryObject selectQueryForTheRow) {
69 this.conditions = conditions;
70 this.selectQueryForTheRow = selectQueryForTheRow;
73 public boolean testCondition() throws Exception {
74 // first generate the row
75 ResultSet results = quorumGet(selectQueryForTheRow);
76 Row row = results.one();
77 return getDSHandle().doesRowSatisfyCondition(row, conditions);
82 public static MusicLockingService getLockingServiceHandle() throws MusicLockingException {
83 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring lock store handle");
84 long start = System.currentTimeMillis();
86 if (mLockHandle == null) {
88 mLockHandle = new MusicLockingService();
89 } catch (Exception e) {
90 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKHANDLE,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
91 throw new MusicLockingException("Failed to aquire Locl store handle " + e);
94 long end = System.currentTimeMillis();
95 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire lock store handle:" + (end - start) + " ms");
104 public static MusicDataStore getDSHandle(String remoteIp) {
105 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
106 long start = System.currentTimeMillis();
107 if (mDstoreHandle == null) {
108 mDstoreHandle = new MusicDataStore(remoteIp);
110 long end = System.currentTimeMillis();
111 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
112 return mDstoreHandle;
118 * @throws MusicServiceException
120 public static MusicDataStore getDSHandle() throws MusicServiceException {
121 logger.info(EELFLoggerDelegate.applicationLogger,"Acquiring data store handle");
122 long start = System.currentTimeMillis();
123 if (mDstoreHandle == null) {
124 // Quick Fix - Best to put this into every call to getDSHandle?
125 if (! MusicUtil.getMyCassaHost().equals("localhost") ) {
126 mDstoreHandle = new MusicDataStore(MusicUtil.getMyCassaHost());
128 mDstoreHandle = new MusicDataStore();
131 if(mDstoreHandle.getSession() == null) {
132 String message = "Connection to Cassandra has not been enstablished."
133 + " Please check connection properites and reboot.";
134 logger.info(EELFLoggerDelegate.applicationLogger, message);
135 throw new MusicServiceException(message);
137 long end = System.currentTimeMillis();
138 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
139 return mDstoreHandle;
142 public static String createLockReference(String lockName) {
143 logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
144 long start = System.currentTimeMillis();
145 String lockId = null;
147 lockId = getLockingServiceHandle().createLockId("/" + lockName);
148 } catch (MusicLockingException e) {
149 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
152 long end = System.currentTimeMillis();
153 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms");
162 public static boolean isTableOrKeySpaceLock(String key) {
163 String[] splitString = key.split("\\.");
164 if (splitString.length > 2)
175 public static MusicLockState getMusicLockState(String key) {
176 long start = System.currentTimeMillis();
178 String[] splitString = key.split("\\.");
179 String keyspaceName = splitString[0];
180 String tableName = splitString[1];
181 String primaryKey = splitString[2];
183 String lockName = keyspaceName + "." + tableName + "." + primaryKey;
184 mls = getLockingServiceHandle().getLockState(lockName);
185 long end = System.currentTimeMillis();
186 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms");
188 } catch (NullPointerException | MusicLockingException e) {
189 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
194 public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
196 long start = System.currentTimeMillis();
197 /* check if the current lock has exceeded its lease and if yes, release that lock */
198 MusicLockState mls = getMusicLockState(key);
200 if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
201 logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder()
202 + ". Checking if it has exceeded lease");
203 long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
204 long currentLeasePeriod = mls.getLeasePeriod();
205 if (currentLockPeriod > currentLeasePeriod) {
206 logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod
207 + " has exceeded lease period " + currentLeasePeriod);
208 boolean voluntaryRelease = false;
209 String currentLockHolder = mls.getLockHolder();
210 mls = releaseLock(currentLockHolder, voluntaryRelease);
214 logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
217 * call the traditional acquire lock now and if the result returned is true, set the
218 * begin time-stamp and lease period
220 if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) {
221 mls = getMusicLockState(key);// get latest state
223 logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null");
224 return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null");
226 if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
227 mls.setLeaseStartTime(System.currentTimeMillis());
228 mls.setLeasePeriod(leasePeriod);
229 getLockingServiceHandle().setLockState(key, mls);
231 long end = System.currentTimeMillis();
232 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms");
233 return new ReturnType(ResultType.SUCCESS, "Accquired lock");
235 long end = System.currentTimeMillis();
236 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms");
237 return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
239 } catch (Exception e) {
240 StringWriter sw = new StringWriter();
241 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
243 String exceptionAsString = sw.toString();
244 return new ReturnType(ResultType.FAILURE,
245 "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
249 public static ReturnType acquireLock(String key, String lockId) throws MusicLockingException {
251 * first check if I am on top. Since ids are not reusable there is no need to check
252 * lockStatus If the status is unlocked, then the above call will automatically return
255 Boolean result = false;
257 result = getLockingServiceHandle().isMyTurn(lockId);
258 } catch (MusicLockingException e2) {
259 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2);
260 throw new MusicLockingException();
263 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock");
265 if (!getLockingServiceHandle().lockIdExists(lockId)) {
266 logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist");
267 return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist");
269 } catch (MusicLockingException e) {
270 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
271 throw new MusicLockingException();
273 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure");
274 return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock");
278 // this is for backward compatibility where locks could also be acquired on just
279 // keyspaces or tables.
280 if (isTableOrKeySpaceLock(key)) {
281 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
282 return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true");
285 // read the lock name corresponding to the key and if the status is locked or being locked,
287 MusicLockState currentMls = null;
288 MusicLockState newMls = null;
290 currentMls = getMusicLockState(key);
291 String currentLockHolder = currentMls.getLockHolder();
292 if (lockId.equals(currentLockHolder)) {
293 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!");
294 return new ReturnType(ResultType.SUCCESS, "You already have the lock!");
296 } catch (NullPointerException e) {
297 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
300 // change status to "being locked". This state transition is necessary to ensure syncing
301 // before granting the lock
302 String lockHolder = null;
303 boolean needToSyncQuorum = false;
304 if (currentMls != null)
305 needToSyncQuorum = currentMls.isNeedToSyncQuorum();
308 newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
311 getLockingServiceHandle().setLockState(key, newMls);
312 } catch (MusicLockingException e1) {
313 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
315 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked");
317 // do syncing if this was a forced lock release
318 if (needToSyncQuorum) {
319 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!");
322 } catch (Exception e) {
323 logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e);
327 // change status to locked
329 needToSyncQuorum = false;
330 newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
332 getLockingServiceHandle().setLockState(key, newMls);
333 } catch (MusicLockingException e) {
334 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
336 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref "
337 + lockId + " as holder");
339 return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder");
346 * @param keyspaceName
351 public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
356 private static void syncQuorum(String key) throws Exception {
357 logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
358 String[] splitString = key.split("\\.");
359 String keyspaceName = splitString[0];
360 String tableName = splitString[1];
361 String primaryKeyValue = splitString[2];
362 PreparedQueryObject selectQuery = new PreparedQueryObject();
363 PreparedQueryObject updateQuery = new PreparedQueryObject();
365 // get the primary key d
366 TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
367 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
369 DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
370 Object cqlFormattedPrimaryKeyValue =
371 MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
373 // get the row of data from a quorum
374 selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE "
375 + primaryKeyName + "= ?" + ";");
376 selectQuery.addValue(cqlFormattedPrimaryKeyValue);
377 ResultSet results = null;
379 results = getDSHandle().executeCriticalGet(selectQuery);
380 // write it back to a quorum
381 Row row = results.one();
382 ColumnDefinitions colInfo = row.getColumnDefinitions();
383 int totalColumns = colInfo.size();
385 StringBuilder fieldValueString = new StringBuilder("");
386 for (Definition definition : colInfo) {
387 String colName = definition.getName();
388 if (colName.equals(primaryKeyName))
390 DataType colType = definition.getType();
391 Object valueObj = getDSHandle().getColValue(row, colName, colType);
392 Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
393 fieldValueString.append(colName + " = ?");
394 updateQuery.addValue(valueString);
395 if (counter != (totalColumns - 1))
396 fieldValueString.append(",");
397 counter = counter + 1;
399 updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
400 + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
401 updateQuery.addValue(cqlFormattedPrimaryKeyValue);
403 getDSHandle().executePut(updateQuery, "critical");
404 } catch (MusicServiceException | MusicQueryException e) {
405 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR);
417 public static ResultSet quorumGet(PreparedQueryObject query) {
418 ResultSet results = null;
420 results = getDSHandle().executeCriticalGet(query);
421 } catch (MusicServiceException | MusicQueryException e) {
422 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR);
433 * @throws MusicServiceException
435 public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException {
436 return getDSHandle().marshalData(results);
444 public static String whoseTurnIsIt(String lockName) {
447 return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
448 } catch (MusicLockingException e) {
449 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
461 public static String getLockNameFromId(String lockId) {
462 StringTokenizer st = new StringTokenizer(lockId);
463 return st.nextToken("$");
466 public static void destroyLockRef(String lockId) {
467 long start = System.currentTimeMillis();
469 getLockingServiceHandle().unlockAndDeleteId(lockId);
470 } catch (MusicLockingException | NoNodeException e) {
471 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
473 long end = System.currentTimeMillis();
474 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
477 public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
478 long start = System.currentTimeMillis();
480 getLockingServiceHandle().unlockAndDeleteId(lockId);
481 } catch (MusicLockingException e1) {
482 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
483 } catch (KeeperException.NoNodeException nne) {
484 logger.error(EELFLoggerDelegate.errorLogger,"Failed to release Lock " + lockId + " " + nne);
485 MusicLockState mls = new MusicLockState("Lock doesn't exists. Release lock operation failed.");
488 String lockName = getLockNameFromId(lockId);
490 String lockHolder = null;
491 if (voluntaryRelease) {
492 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
493 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId);
495 boolean needToSyncQuorum = true;
496 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
498 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId);
501 getLockingServiceHandle().setLockState(lockName, mls);
502 } catch (MusicLockingException e) {
503 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
505 long end = System.currentTimeMillis();
506 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms");
510 public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{
512 getLockingServiceHandle().unlockAndDeleteId(lockId);
513 } catch (KeeperException.NoNodeException e) {
521 * @throws MusicLockingException
523 public static void deleteLock(String lockName) throws MusicLockingException {
524 long start = System.currentTimeMillis();
525 logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName);
527 getLockingServiceHandle().deleteLock("/" + lockName);
528 } catch (MusicLockingException e) {
529 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
530 throw new MusicLockingException(e.getMessage());
532 long end = System.currentTimeMillis();
533 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms");
543 * @throws MusicServiceException
545 public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException {
546 return getDSHandle().returnColumnMetadata(keyspace, tablename);
554 public static void pureZkCreate(String nodeName) {
556 getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
557 } catch (MusicLockingException e) {
558 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
567 public static void pureZkWrite(String nodeName, byte[] data) {
568 long start = System.currentTimeMillis();
569 logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName);
571 getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
572 } catch (MusicLockingException e) {
573 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
575 logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName);
576 long end = System.currentTimeMillis();
577 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
585 public static byte[] pureZkRead(String nodeName) {
586 long start = System.currentTimeMillis();
589 data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
590 } catch (MusicLockingException e) {
591 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
593 long end = System.currentTimeMillis();
594 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
600 // Prepared Query Additions.
604 * @param keyspaceName
609 * @throws MusicServiceException
611 public static ReturnType eventualPut(PreparedQueryObject queryObject) {
612 boolean result = false;
614 result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
615 } catch (MusicServiceException | MusicQueryException ex) {
616 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
617 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex);
618 return new ReturnType(ResultType.FAILURE, ex.getMessage());
621 return new ReturnType(ResultType.SUCCESS, "Success");
623 return new ReturnType(ResultType.FAILURE, "Failure");
629 * @param keyspaceName
636 public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
637 PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
638 long start = System.currentTimeMillis();
641 MusicLockState mls = getLockingServiceHandle()
642 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
643 if (mls.getLockHolder().equals(lockId) == true) {
644 if (conditionInfo != null)
646 if (conditionInfo.testCondition() == false)
647 return new ReturnType(ResultType.FAILURE,
648 "Lock acquired but the condition is not true");
649 } catch (Exception e) {
650 return new ReturnType(ResultType.FAILURE,
651 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
654 getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
655 long end = System.currentTimeMillis();
656 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
657 return new ReturnType(ResultType.SUCCESS, "Update performed");
659 return new ReturnType(ResultType.FAILURE,
660 "Cannot perform operation since you are the not the lock holder");
661 } catch (MusicQueryException | MusicServiceException e) {
662 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
663 return new ReturnType(ResultType.FAILURE,
664 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
666 }catch(MusicLockingException ex){
667 return new ReturnType(ResultType.FAILURE,ex.getMessage());
676 * @return Boolean Indicates success or failure
677 * @throws MusicServiceException
681 public static ResultType nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException {
682 // this is mainly for some functions like keyspace creation etc which does not
683 // really need the bells and whistles of Music locking.
684 boolean result = false;
686 result = getDSHandle().executePut(queryObject, consistency);
687 } catch (MusicQueryException | MusicServiceException ex) {
688 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
689 throw new MusicServiceException(ex.getMessage());
691 return result?ResultType.SUCCESS:ResultType.FAILURE;
695 * This method performs DDL operation on cassandra.
697 * @param queryObject query object containing prepared query and values
699 * @throws MusicServiceException
701 public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
702 ResultSet results = null;
704 results = getDSHandle().executeEventualGet(queryObject);
705 } catch (MusicQueryException | MusicServiceException e) {
706 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
707 throw new MusicServiceException(e.getMessage());
713 * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
714 * is used to check if the resource is free.
716 * @param keyspaceName name of the keyspace
717 * @param tableName name of the table
718 * @param primaryKey primary key value
719 * @param queryObject query object containing prepared query and values
720 * @param lockId lock ID to check if the resource is free to perform the operation.
723 public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
724 PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
725 ResultSet results = null;
727 MusicLockState mls = getLockingServiceHandle()
728 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
729 if (mls.getLockHolder().equals(lockId)) {
730 results = getDSHandle().executeCriticalGet(queryObject);
732 throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
733 } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
734 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
740 * This method performs DML operation on cassandra, when the lock of the dd is acquired.
742 * @param keyspaceName name of the keyspace
743 * @param tableName name of the table
744 * @param primaryKey primary key value
745 * @param queryObject query object containing prepared query and values
747 * @throws MusicLockingException
749 public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
750 PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
752 long start = System.currentTimeMillis();
753 String key = keyspaceName + "." + tableName + "." + primaryKey;
754 String lockId = createLockReference(key);
755 long lockCreationTime = System.currentTimeMillis();
756 ReturnType lockAcqResult = acquireLock(key, lockId);
757 long lockAcqTime = System.currentTimeMillis();
758 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
759 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
760 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
761 queryObject, lockId, conditionInfo);
762 long criticalPutTime = System.currentTimeMillis();
763 voluntaryReleaseLock(lockId);
764 long lockDeleteTime = System.currentTimeMillis();
765 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
766 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
767 + "|critical put time:" + (criticalPutTime - lockAcqTime)
768 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
769 criticalPutResult.setTimingInfo(timingInfo);
770 return criticalPutResult;
772 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
773 destroyLockRef(lockId);
774 return lockAcqResult;
779 * this function is mainly for the benchmarks to see the effect of lock deletion.
781 * @param keyspaceName
785 * @param conditionInfo
787 * @throws MusicLockingException
789 public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
790 String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
792 long start = System.currentTimeMillis();
793 String key = keyspaceName + "." + tableName + "." + primaryKey;
794 String lockId = createLockReference(key);
795 long lockCreationTime = System.currentTimeMillis();
796 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
797 ReturnType lockAcqResult = acquireLock(key, lockId);
798 long lockAcqTime = System.currentTimeMillis();
799 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
800 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
801 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
802 queryObject, lockId, conditionInfo);
803 long criticalPutTime = System.currentTimeMillis();
805 long lockDeleteTime = System.currentTimeMillis();
806 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
807 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
808 + "|critical put time:" + (criticalPutTime - lockAcqTime)
809 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
810 criticalPutResult.setTimingInfo(timingInfo);
811 return criticalPutResult;
813 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
815 return lockAcqResult;
823 * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
825 * @param keyspaceName name of the keyspace
826 * @param tableName name of the table
827 * @param primaryKey primary key value
828 * @param queryObject query object containing prepared query and values
830 * @throws MusicServiceException
831 * @throws MusicLockingException
833 public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
834 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
835 String key = keyspaceName + "." + tableName + "." + primaryKey;
836 String lockId = createLockReference(key);
837 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
838 ReturnType lockAcqResult = acquireLock(key, lockId);
839 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
840 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
842 criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
843 voluntaryReleaseLock(lockId);
846 destroyLockRef(lockId);
847 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
852 public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
853 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
854 String key = keyspaceName + "." + tableName + "." + primaryKey;
855 String lockId = createLockReference(key);
856 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
858 ReturnType lockAcqResult = acquireLock(key, lockId);
860 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
861 logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
862 ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
867 logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
875 * authenticate user logic
886 public static Map<String, Object> autheticateUser(String nameSpace, String userId,
887 String password, String keyspace, String aid, String operation)
889 Map<String, Object> resultMap = new HashMap<>();
891 resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
893 if (!resultMap.isEmpty())
895 String isAAFApp = null;
897 isAAFApp= CachingUtil.isAAFApplication(nameSpace);
898 } catch(MusicServiceException e) {
899 resultMap.put("Exception", e.getMessage());
902 if(isAAFApp == null) {
903 resultMap.put("Exception", "Namespace: "+nameSpace+" doesn't exist. Please make sure ns(appName)"
904 + " is correct and Application is onboarded.");
907 boolean isAAF = Boolean.valueOf(isAAFApp);
908 if (userId == null || password == null) {
909 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
910 logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
911 + " :: password: " + password);
912 resultMap.put("Exception",
913 "UserId and Password are mandatory for the operation " + operation);
916 if(!isAAF && !(operation.equals("createKeySpace"))) {
917 resultMap = CachingUtil.authenticateAIDUser(nameSpace, userId, password, keyspace);
918 if (!resultMap.isEmpty())
922 if (isAAF && nameSpace != null && userId != null && password != null) {
923 boolean isValid = true;
925 isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
926 } catch (Exception e) {
927 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
928 logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
929 resultMap.put("Exception", e.getMessage());
932 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
933 resultMap.put("Exception", "User not authenticated...");
935 if (!resultMap.isEmpty())
940 if (operation.equals("createKeySpace")) {
941 logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
942 PreparedQueryObject pQuery = new PreparedQueryObject();
943 pQuery.appendQueryString(
944 "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
945 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
946 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
947 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
948 MusicUtil.DEFAULTKEYSPACENAME));
951 Row rs = MusicCore.get(pQuery).one();
952 uuid = rs.getUUID("uuid").toString();
953 resultMap.put("uuid", "existing");
954 } catch (Exception e) {
955 logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
956 uuid = CachingUtil.generateUUID();
957 resultMap.put("uuid", "new");
959 resultMap.put("aid", uuid);
969 public static Map<String, Object> validateLock(String lockName) {
970 Map<String, Object> resultMap = new HashMap<>();
971 String[] locks = lockName.split("\\.");
972 if(locks.length < 3) {
973 resultMap.put("Exception", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey");
976 String keyspace= locks[0];
977 if(keyspace.startsWith("$"))
978 keyspace = keyspace.substring(1);
979 resultMap.put("keyspace",keyspace);