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 mDstoreHandle = new MusicDataStore();
124 if(mDstoreHandle.getSession() == null) {
125 String message = "Connection to Cassandra has not been enstablished."
126 + " Please check connection properites and reboot.";
127 logger.info(EELFLoggerDelegate.applicationLogger, message);
128 throw new MusicServiceException(message);
130 long end = System.currentTimeMillis();
131 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire data store handle:" + (end - start) + " ms");
132 return mDstoreHandle;
135 public static String createLockReference(String lockName) {
136 logger.info(EELFLoggerDelegate.applicationLogger,"Creating lock reference for lock name:" + lockName);
137 long start = System.currentTimeMillis();
138 String lockId = null;
140 lockId = getLockingServiceHandle().createLockId("/" + lockName);
141 } catch (MusicLockingException e) {
142 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.CREATELOCK+lockName,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
145 long end = System.currentTimeMillis();
146 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to create lock reference:" + (end - start) + " ms");
155 public static boolean isTableOrKeySpaceLock(String key) {
156 String[] splitString = key.split("\\.");
157 if (splitString.length > 2)
168 public static MusicLockState getMusicLockState(String key) {
169 long start = System.currentTimeMillis();
171 String[] splitString = key.split("\\.");
172 String keyspaceName = splitString[0];
173 String tableName = splitString[1];
174 String primaryKey = splitString[2];
176 String lockName = keyspaceName + "." + tableName + "." + primaryKey;
177 mls = getLockingServiceHandle().getLockState(lockName);
178 long end = System.currentTimeMillis();
179 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to get lock state:" + (end - start) + " ms");
181 } catch (NullPointerException | MusicLockingException e) {
182 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
187 public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
189 long start = System.currentTimeMillis();
190 /* check if the current lock has exceeded its lease and if yes, release that lock */
191 MusicLockState mls = getMusicLockState(key);
193 if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
194 logger.info(EELFLoggerDelegate.applicationLogger,"The current lock holder for " + key + " is " + mls.getLockHolder()
195 + ". Checking if it has exceeded lease");
196 long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
197 long currentLeasePeriod = mls.getLeasePeriod();
198 if (currentLockPeriod > currentLeasePeriod) {
199 logger.info(EELFLoggerDelegate.applicationLogger,"Lock period " + currentLockPeriod
200 + " has exceeded lease period " + currentLeasePeriod);
201 boolean voluntaryRelease = false;
202 String currentLockHolder = mls.getLockHolder();
203 mls = releaseLock(currentLockHolder, voluntaryRelease);
207 logger.error(EELFLoggerDelegate.errorLogger,key, AppMessages.INVALIDLOCK,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
210 * call the traditional acquire lock now and if the result returned is true, set the
211 * begin time-stamp and lease period
213 if (acquireLock(key, lockId).getResult() == ResultType.SUCCESS) {
214 mls = getMusicLockState(key);// get latest state
216 logger.info(EELFLoggerDelegate.applicationLogger,"Music Lock State is null");
217 return new ReturnType(ResultType.FAILURE, "Could not acquire lock, Lock State is null");
219 if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
220 mls.setLeaseStartTime(System.currentTimeMillis());
221 mls.setLeasePeriod(leasePeriod);
222 getLockingServiceHandle().setLockState(key, mls);
224 long end = System.currentTimeMillis();
225 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to acquire leased lock:" + (end - start) + " ms");
226 return new ReturnType(ResultType.SUCCESS, "Accquired lock");
228 long end = System.currentTimeMillis();
229 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to fail to acquire leased lock:" + (end - start) + " ms");
230 return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
232 } catch (Exception e) {
233 StringWriter sw = new StringWriter();
234 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR506E] Failed to aquire lock ",ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
236 String exceptionAsString = sw.toString();
237 return new ReturnType(ResultType.FAILURE,
238 "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
242 public static ReturnType acquireLock(String key, String lockId) {
244 * first check if I am on top. Since ids are not reusable there is no need to check
245 * lockStatus If the status is unlocked, then the above call will automatically return
248 Boolean result = false;
250 result = getLockingServiceHandle().isMyTurn(lockId);
251 } catch (MusicLockingException e2) {
252 logger.error(EELFLoggerDelegate.errorLogger,AppMessages.INVALIDLOCK + lockId + " " + e2);
255 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Not your turn, someone else has the lock");
257 if (!getLockingServiceHandle().lockIdExists(lockId)) {
258 logger.info(EELFLoggerDelegate.applicationLogger, "In acquire lock: this lockId doesn't exist");
259 return new ReturnType(ResultType.FAILURE, "Lockid doesn't exist");
261 } catch (MusicLockingException e) {
262 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
264 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: returning failure");
265 return new ReturnType(ResultType.FAILURE, "Not your turn, someone else has the lock");
269 // this is for backward compatibility where locks could also be acquired on just
270 // keyspaces or tables.
271 if (isTableOrKeySpaceLock(key)) {
272 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
273 return new ReturnType(ResultType.SUCCESS, "A table or keyspace lock so no need to perform sync...so returning true");
276 // read the lock name corresponding to the key and if the status is locked or being locked,
278 MusicLockState currentMls = null;
279 MusicLockState newMls = null;
281 currentMls = getMusicLockState(key);
282 String currentLockHolder = currentMls.getLockHolder();
283 if (lockId.equals(currentLockHolder)) {
284 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: You already have the lock!");
285 return new ReturnType(ResultType.SUCCESS, "You already have the lock!");
287 } catch (NullPointerException e) {
288 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.INVALIDLOCK+lockId,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
291 // change status to "being locked". This state transition is necessary to ensure syncing
292 // before granting the lock
293 String lockHolder = null;
294 boolean needToSyncQuorum = false;
295 if (currentMls != null)
296 needToSyncQuorum = currentMls.isNeedToSyncQuorum();
299 newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
302 getLockingServiceHandle().setLockState(key, newMls);
303 } catch (MusicLockingException e1) {
304 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
306 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to being_locked");
308 // do syncing if this was a forced lock release
309 if (needToSyncQuorum) {
310 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Since there was a forcible release, need to sync quorum!");
313 } catch (Exception e) {
314 logger.error(EELFLoggerDelegate.errorLogger,"Failed to set Lock state " + e);
318 // change status to locked
320 needToSyncQuorum = false;
321 newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
323 getLockingServiceHandle().setLockState(key, newMls);
324 } catch (MusicLockingException e) {
325 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKSTATE+key,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
327 logger.info(EELFLoggerDelegate.applicationLogger,"In acquire lock: Set lock state to locked and assigned current lock ref "
328 + lockId + " as holder");
330 return new ReturnType(result?ResultType.SUCCESS:ResultType.FAILURE, "Set lock state to locked and assigned a lock holder");
337 * @param keyspaceName
342 public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
347 private static void syncQuorum(String key) throws Exception {
348 logger.info(EELFLoggerDelegate.applicationLogger,"Performing sync operation---");
349 String[] splitString = key.split("\\.");
350 String keyspaceName = splitString[0];
351 String tableName = splitString[1];
352 String primaryKeyValue = splitString[2];
353 PreparedQueryObject selectQuery = new PreparedQueryObject();
354 PreparedQueryObject updateQuery = new PreparedQueryObject();
356 // get the primary key d
357 TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
358 String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
360 DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
361 Object cqlFormattedPrimaryKeyValue =
362 MusicUtil.convertToActualDataType(primaryKeyType, primaryKeyValue);
364 // get the row of data from a quorum
365 selectQuery.appendQueryString("SELECT * FROM " + keyspaceName + "." + tableName + " WHERE "
366 + primaryKeyName + "= ?" + ";");
367 selectQuery.addValue(cqlFormattedPrimaryKeyValue);
368 ResultSet results = null;
370 results = getDSHandle().executeCriticalGet(selectQuery);
371 // write it back to a quorum
372 Row row = results.one();
373 ColumnDefinitions colInfo = row.getColumnDefinitions();
374 int totalColumns = colInfo.size();
376 StringBuilder fieldValueString = new StringBuilder("");
377 for (Definition definition : colInfo) {
378 String colName = definition.getName();
379 if (colName.equals(primaryKeyName))
381 DataType colType = definition.getType();
382 Object valueObj = getDSHandle().getColValue(row, colName, colType);
383 Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
384 fieldValueString.append(colName + " = ?");
385 updateQuery.addValue(valueString);
386 if (counter != (totalColumns - 1))
387 fieldValueString.append(",");
388 counter = counter + 1;
390 updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
391 + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
392 updateQuery.addValue(cqlFormattedPrimaryKeyValue);
394 getDSHandle().executePut(updateQuery, "critical");
395 } catch (MusicServiceException | MusicQueryException e) {
396 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.QUERYERROR +""+updateQuery ,ErrorSeverity.MAJOR, ErrorTypes.QUERYERROR);
408 public static ResultSet quorumGet(PreparedQueryObject query) {
409 ResultSet results = null;
411 results = getDSHandle().executeCriticalGet(query);
412 } catch (MusicServiceException | MusicQueryException e) {
413 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.MAJOR, ErrorTypes.GENERALSERVICEERROR);
424 * @throws MusicServiceException
426 public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) throws MusicServiceException {
427 return getDSHandle().marshalData(results);
435 public static String whoseTurnIsIt(String lockName) {
438 return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
439 } catch (MusicLockingException e) {
440 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.LOCKINGERROR+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
452 public static String getLockNameFromId(String lockId) {
453 StringTokenizer st = new StringTokenizer(lockId);
454 return st.nextToken("$");
457 public static void destroyLockRef(String lockId) {
458 long start = System.currentTimeMillis();
460 getLockingServiceHandle().unlockAndDeleteId(lockId);
461 } catch (MusicLockingException e) {
462 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DESTROYLOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
464 long end = System.currentTimeMillis();
465 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to destroy lock reference:" + (end - start) + " ms");
468 public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
469 long start = System.currentTimeMillis();
471 getLockingServiceHandle().unlockAndDeleteId(lockId);
472 } catch (MusicLockingException e1) {
473 logger.error(EELFLoggerDelegate.errorLogger,e1.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
475 String lockName = getLockNameFromId(lockId);
477 String lockHolder = null;
478 if (voluntaryRelease) {
479 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
480 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock voluntarily released for " + lockId);
482 boolean needToSyncQuorum = true;
483 mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
485 logger.info(EELFLoggerDelegate.applicationLogger,"In unlock: lock forcibly released for " + lockId);
488 getLockingServiceHandle().setLockState(lockName, mls);
489 } catch (MusicLockingException e) {
490 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.RELEASELOCK+lockId ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
492 long end = System.currentTimeMillis();
493 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to release lock:" + (end - start) + " ms");
497 public static void voluntaryReleaseLock(String lockId) throws MusicLockingException{
498 getLockingServiceHandle().unlockAndDeleteId(lockId);
505 public static void deleteLock(String lockName) {
506 long start = System.currentTimeMillis();
507 logger.info(EELFLoggerDelegate.applicationLogger,"Deleting lock for " + lockName);
509 getLockingServiceHandle().deleteLock("/" + lockName);
510 } catch (MusicLockingException e) {
511 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.DELTELOCK+lockName ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
513 long end = System.currentTimeMillis();
514 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken to delete lock:" + (end - start) + " ms");
524 * @throws MusicServiceException
526 public static TableMetadata returnColumnMetadata(String keyspace, String tablename) throws MusicServiceException {
527 return getDSHandle().returnColumnMetadata(keyspace, tablename);
535 public static void pureZkCreate(String nodeName) {
537 getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
538 } catch (MusicLockingException e) {
539 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
548 public static void pureZkWrite(String nodeName, byte[] data) {
549 long start = System.currentTimeMillis();
550 logger.info(EELFLoggerDelegate.applicationLogger,"Performing zookeeper write to " + nodeName);
552 getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
553 } catch (MusicLockingException e) {
554 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
556 logger.info(EELFLoggerDelegate.applicationLogger,"Performed zookeeper write to " + nodeName);
557 long end = System.currentTimeMillis();
558 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
566 public static byte[] pureZkRead(String nodeName) {
567 long start = System.currentTimeMillis();
570 data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
571 } catch (MusicLockingException e) {
572 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.CRITICAL, ErrorTypes.LOCKINGERROR);
574 long end = System.currentTimeMillis();
575 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the actual zk put:" + (end - start) + " ms");
581 // Prepared Query Additions.
585 * @param keyspaceName
590 * @throws MusicServiceException
592 public static ReturnType eventualPut(PreparedQueryObject queryObject) {
593 boolean result = false;
595 result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
596 } catch (MusicServiceException | MusicQueryException ex) {
597 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), "[ERR512E] Failed to get ZK Lock Handle " ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
598 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage() + " " + ex.getCause() + " " + ex);
601 return new ReturnType(ResultType.SUCCESS, "Success");
603 return new ReturnType(ResultType.FAILURE, "Failure");
609 * @param keyspaceName
616 public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
617 PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
618 long start = System.currentTimeMillis();
621 MusicLockState mls = getLockingServiceHandle()
622 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
623 if (mls.getLockHolder().equals(lockId) == true) {
624 if (conditionInfo != null)
626 if (conditionInfo.testCondition() == false)
627 return new ReturnType(ResultType.FAILURE,
628 "Lock acquired but the condition is not true");
629 } catch (Exception e) {
630 return new ReturnType(ResultType.FAILURE,
631 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
634 getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
635 long end = System.currentTimeMillis();
636 logger.info(EELFLoggerDelegate.applicationLogger,"Time taken for the critical put:" + (end - start) + " ms");
637 return new ReturnType(ResultType.SUCCESS, "Update performed");
639 return new ReturnType(ResultType.FAILURE,
640 "Cannot perform operation since you are the not the lock holder");
641 } catch (MusicQueryException | MusicServiceException e) {
642 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
643 return new ReturnType(ResultType.FAILURE,
644 "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
646 }catch(MusicLockingException ex){
647 return new ReturnType(ResultType.FAILURE,ex.getMessage());
656 * @return Boolean Indicates success or failure
657 * @throws MusicServiceException
661 public static boolean nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) throws MusicServiceException {
662 // this is mainly for some functions like keyspace creation etc which does not
663 // really need the bells and whistles of Music locking.
664 boolean result = false;
666 result = getDSHandle().executePut(queryObject, consistency);
667 } catch (MusicQueryException | MusicServiceException ex) {
668 logger.error(EELFLoggerDelegate.errorLogger,ex.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
669 throw new MusicServiceException(ex.getMessage());
675 * This method performs DDL operation on cassandra.
677 * @param queryObject query object containing prepared query and values
679 * @throws MusicServiceException
681 public static ResultSet get(PreparedQueryObject queryObject) throws MusicServiceException {
682 ResultSet results = null;
684 results = getDSHandle().executeEventualGet(queryObject);
685 } catch (MusicQueryException | MusicServiceException e) {
686 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage());
687 throw new MusicServiceException(e.getMessage());
693 * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
694 * is used to check if the resource is free.
696 * @param keyspaceName name of the keyspace
697 * @param tableName name of the table
698 * @param primaryKey primary key value
699 * @param queryObject query object containing prepared query and values
700 * @param lockId lock ID to check if the resource is free to perform the operation.
703 public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
704 PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
705 ResultSet results = null;
707 MusicLockState mls = getLockingServiceHandle()
708 .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
709 if (mls.getLockHolder().equals(lockId)) {
710 results = getDSHandle().executeCriticalGet(queryObject);
712 throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
713 } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
714 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.UNKNOWNERROR ,ErrorSeverity.WARN, ErrorTypes.MUSICSERVICEERROR);
720 * This method performs DML operation on cassandra, when the lock of the dd is acquired.
722 * @param keyspaceName name of the keyspace
723 * @param tableName name of the table
724 * @param primaryKey primary key value
725 * @param queryObject query object containing prepared query and values
727 * @throws MusicLockingException
729 public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
730 PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
732 long start = System.currentTimeMillis();
733 String key = keyspaceName + "." + tableName + "." + primaryKey;
734 String lockId = createLockReference(key);
735 long lockCreationTime = System.currentTimeMillis();
736 ReturnType lockAcqResult = acquireLock(key, lockId);
737 long lockAcqTime = System.currentTimeMillis();
738 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
739 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
740 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
741 queryObject, lockId, conditionInfo);
742 long criticalPutTime = System.currentTimeMillis();
743 voluntaryReleaseLock(lockId);
744 long lockDeleteTime = System.currentTimeMillis();
745 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
746 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
747 + "|critical put time:" + (criticalPutTime - lockAcqTime)
748 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
749 criticalPutResult.setTimingInfo(timingInfo);
750 return criticalPutResult;
752 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
753 destroyLockRef(lockId);
754 return lockAcqResult;
759 * this function is mainly for the benchmarks to see the effect of lock deletion.
761 * @param keyspaceName
765 * @param conditionInfo
767 * @throws MusicLockingException
769 public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
770 String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) throws MusicLockingException {
772 long start = System.currentTimeMillis();
773 String key = keyspaceName + "." + tableName + "." + primaryKey;
774 String lockId = createLockReference(key);
775 long lockCreationTime = System.currentTimeMillis();
776 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
777 ReturnType lockAcqResult = acquireLock(key, lockId);
778 long lockAcqTime = System.currentTimeMillis();
779 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
780 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
781 ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
782 queryObject, lockId, conditionInfo);
783 long criticalPutTime = System.currentTimeMillis();
785 long lockDeleteTime = System.currentTimeMillis();
786 String timingInfo = "|lock creation time:" + (lockCreationTime - start)
787 + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
788 + "|critical put time:" + (criticalPutTime - lockAcqTime)
789 + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
790 criticalPutResult.setTimingInfo(timingInfo);
791 return criticalPutResult;
793 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
795 return lockAcqResult;
803 * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
805 * @param keyspaceName name of the keyspace
806 * @param tableName name of the table
807 * @param primaryKey primary key value
808 * @param queryObject query object containing prepared query and values
810 * @throws MusicServiceException
811 * @throws MusicLockingException
813 public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
814 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
815 String key = keyspaceName + "." + tableName + "." + primaryKey;
816 String lockId = createLockReference(key);
817 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
818 ReturnType lockAcqResult = acquireLock(key, lockId);
819 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
820 logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
822 criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
823 voluntaryReleaseLock(lockId);
826 destroyLockRef(lockId);
827 logger.info(EELFLoggerDelegate.applicationLogger,"unable to acquire lock, id " + lockId);
832 public static ResultSet atomicGetWithDeleteLock(String keyspaceName, String tableName, String primaryKey,
833 PreparedQueryObject queryObject) throws MusicServiceException, MusicLockingException {
834 String key = keyspaceName + "." + tableName + "." + primaryKey;
835 String lockId = createLockReference(key);
836 long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
838 ReturnType lockAcqResult = acquireLock(key, lockId);
840 if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
841 logger.info(EELFLoggerDelegate.applicationLogger, "acquired lock with id " + lockId);
842 ResultSet result = criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
847 logger.info(EELFLoggerDelegate.applicationLogger, "unable to acquire lock, id " + lockId);
855 * authenticate user logic
866 public static Map<String, Object> autheticateUser(String nameSpace, String userId,
867 String password, String keyspace, String aid, String operation)
869 Map<String, Object> resultMap = new HashMap<>();
871 resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
873 if (!resultMap.isEmpty())
875 boolean isAAF = CachingUtil.isAAFApplication(nameSpace);
876 if (!isAAF && !(operation.equals("createKeySpace"))) {
878 resultMap.put("Exception", "Aid is mandatory for nonAAF applications ");
881 if(operation.contains("Lock")) {
882 resultMap = CachingUtil.authenticateAIDUserLock(aid, nameSpace);
885 resultMap = CachingUtil.authenticateAIDUser(aid, keyspace);
888 if (!resultMap.isEmpty())
891 if (aid == null && (userId == null || password == null)) {
892 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.DATAERROR);
893 logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: " + userId
894 + " :: password: " + password);
895 resultMap.put("Exception",
896 "UserId and Password are mandatory for the operation " + operation);
900 if (isAAF && nameSpace != null && userId != null && password != null) {
901 boolean isValid = true;
903 isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
904 } catch (Exception e) {
905 logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
906 logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + nameSpace);
907 resultMap.put("Exception", e.getMessage());
910 logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
911 resultMap.put("Exception", "User not authenticated...");
913 if (!resultMap.isEmpty())
918 if (operation.equals("createKeySpace")) {
919 logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
920 PreparedQueryObject pQuery = new PreparedQueryObject();
921 pQuery.appendQueryString(
922 "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
923 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
924 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
925 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
926 MusicUtil.DEFAULTKEYSPACENAME));
929 Row rs = MusicCore.get(pQuery).one();
930 uuid = rs.getUUID("uuid").toString();
931 resultMap.put("uuid", "existing");
932 } catch (Exception e) {
933 logger.info(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.");
934 uuid = CachingUtil.generateUUID();
935 resultMap.put("uuid", "new");
938 pQuery = new PreparedQueryObject();
939 pQuery.appendQueryString(
940 "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
941 + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
942 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
943 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
944 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
945 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
946 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
947 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
948 pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
949 //CachingUtil.updateMusicCache(uuid, keyspace);
950 MusicCore.eventualPut(pQuery);
951 resultMap.put("aid", uuid);