Initial code Import.
[music.git] / src / main / java / org / onap / music / main / MusicCore.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
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
10  * 
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  * 
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.
18  * 
19  * ============LICENSE_END=============================================
20  * ====================================================================
21  */
22 package org.onap.music.main;
23
24
25 import java.io.StringWriter;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.StringTokenizer;
29 import org.onap.music.datastore.MusicDataStore;
30 import org.onap.music.datastore.PreparedQueryObject;
31 import org.onap.music.datastore.jsonobjects.JsonKeySpace;
32 // import org.onap.music.eelf.logging.EELFLoggerDelegate;
33 import org.onap.music.exceptions.MusicLockingException;
34 import org.onap.music.exceptions.MusicQueryException;
35 import org.onap.music.exceptions.MusicServiceException;
36 import org.onap.music.lockingservice.MusicLockState;
37 import org.onap.music.lockingservice.MusicLockState.LockStatus;
38 import org.onap.music.lockingservice.MusicLockingService;
39 import com.att.eelf.configuration.EELFLogger;
40 import com.att.eelf.configuration.EELFManager;
41 import com.datastax.driver.core.ColumnDefinitions;
42 import com.datastax.driver.core.ColumnDefinitions.Definition;
43 import com.datastax.driver.core.DataType;
44 import com.datastax.driver.core.ResultSet;
45 import com.datastax.driver.core.Row;
46 import com.datastax.driver.core.TableMetadata;
47
48 /**
49  * This class .....
50  * 
51  *
52  */
53 public class MusicCore {
54
55     public static MusicLockingService mLockHandle = null;
56     public static MusicDataStore mDstoreHandle = null;
57     private static EELFLogger logger = EELFManager.getInstance().getLogger(MusicCore.class);
58
59     public static class Condition {
60         Map<String, Object> conditions;
61         String selectQueryForTheRow;
62
63         public Condition(Map<String, Object> conditions, String selectQueryForTheRow) {
64             this.conditions = conditions;
65             this.selectQueryForTheRow = selectQueryForTheRow;
66         }
67
68         public boolean testCondition() {
69             // first generate the row
70             PreparedQueryObject query = new PreparedQueryObject();
71             query.appendQueryString(selectQueryForTheRow);
72             ResultSet results = quorumGet(query);
73             Row row = results.one();
74             return getDSHandle().doesRowSatisfyCondition(row, conditions);
75         }
76     }
77
78
79     public static MusicLockingService getLockingServiceHandle() throws MusicLockingException {
80         logger.info("Acquiring lock store handle");
81         long start = System.currentTimeMillis();
82
83         if (mLockHandle == null) {
84             try {
85                 mLockHandle = new MusicLockingService();
86             } catch (Exception e) {
87                 logger.error("Failed to aquire Locl store handle" + e.getMessage());
88                 throw new MusicLockingException("Failed to aquire Locl store handle " + e);
89             }
90         }
91         long end = System.currentTimeMillis();
92         logger.info("Time taken to acquire lock store handle:" + (end - start) + " ms");
93         return mLockHandle;
94     }
95
96     /**
97      * 
98      * @param remoteIp
99      * @return
100      */
101     public static MusicDataStore getDSHandle(String remoteIp) {
102         logger.info("Acquiring data store handle");
103         long start = System.currentTimeMillis();
104         if (mDstoreHandle == null) {
105             mDstoreHandle = new MusicDataStore(remoteIp);
106         }
107         long end = System.currentTimeMillis();
108         logger.info("Time taken to acquire data store handle:" + (end - start) + " ms");
109         return mDstoreHandle;
110     }
111
112     /**
113      * 
114      * @return
115      */
116     public static MusicDataStore getDSHandle() {
117         logger.info("Acquiring data store handle");
118         long start = System.currentTimeMillis();
119         if (mDstoreHandle == null) {
120             mDstoreHandle = new MusicDataStore();
121         }
122         long end = System.currentTimeMillis();
123         logger.info("Time taken to acquire data store handle:" + (end - start) + " ms");
124         return mDstoreHandle;
125     }
126
127     public static String createLockReference(String lockName) {
128         logger.info("Creating lock reference for lock name:" + lockName);
129         long start = System.currentTimeMillis();
130         String lockId = null;
131         try {
132             lockId = getLockingServiceHandle().createLockId("/" + lockName);
133         } catch (MusicLockingException e) {
134             logger.error("Failed to create Lock Reference " + lockName);
135         }
136         long end = System.currentTimeMillis();
137         logger.info("Time taken to create lock reference:" + (end - start) + " ms");
138         return lockId;
139     }
140
141     /**
142      * 
143      * @param key
144      * @return
145      */
146     public static boolean isTableOrKeySpaceLock(String key) {
147         String[] splitString = key.split("\\.");
148         if (splitString.length > 2)
149             return false;
150         else
151             return true;
152     }
153
154     /**
155      * 
156      * @param key
157      * @return
158      */
159     public static MusicLockState getMusicLockState(String key) {
160         long start = System.currentTimeMillis();
161         try {
162             String[] splitString = key.split("\\.");
163             String keyspaceName = splitString[0];
164             String tableName = splitString[1];
165             String primaryKey = splitString[2];
166             MusicLockState mls;
167             String lockName = keyspaceName + "." + tableName + "." + primaryKey;
168             mls = getLockingServiceHandle().getLockState(lockName);
169             long end = System.currentTimeMillis();
170             logger.info("Time taken to get lock state:" + (end - start) + " ms");
171             return mls;
172         } catch (NullPointerException | MusicLockingException e) {
173             logger.error("No lock object exists as of now.." + e);
174         }
175         return null;
176     }
177
178     public static ReturnType acquireLockWithLease(String key, String lockId, long leasePeriod) {
179         try {
180             long start = System.currentTimeMillis();
181             /* check if the current lock has exceeded its lease and if yes, release that lock */
182             MusicLockState mls = getMusicLockState(key);
183             if (mls != null) {
184                 if (mls.getLockStatus().equals(LockStatus.LOCKED)) {
185                     logger.info("The current lock holder for " + key + " is " + mls.getLockHolder()
186                                     + ". Checking if it has exceeded lease");
187                     long currentLockPeriod = System.currentTimeMillis() - mls.getLeaseStartTime();
188                     long currentLeasePeriod = mls.getLeasePeriod();
189                     if (currentLockPeriod > currentLeasePeriod) {
190                         logger.info("Lock period " + currentLockPeriod
191                                         + " has exceeded lease period " + currentLeasePeriod);
192                         boolean voluntaryRelease = false;
193                         String currentLockHolder = mls.getLockHolder();
194                         mls = releaseLock(currentLockHolder, voluntaryRelease);
195                     }
196                 }
197             } else
198                 logger.debug("There is no lock state object for " + key);
199
200             /*
201              * call the traditional acquire lock now and if the result returned is true, set the
202              * begin time-stamp and lease period
203              */
204             if (acquireLock(key, lockId) == true) {
205                 mls = getMusicLockState(key);// get latest state
206                 if (mls.getLeaseStartTime() == -1) {// set it again only if it is not set already
207                     mls.setLeaseStartTime(System.currentTimeMillis());
208                     mls.setLeasePeriod(leasePeriod);
209                     getLockingServiceHandle().setLockState(key, mls);
210                 }
211                 long end = System.currentTimeMillis();
212                 logger.info("Time taken to acquire leased lock:" + (end - start) + " ms");
213                 return new ReturnType(ResultType.SUCCESS, "Accquired lock");
214             } else {
215                 long end = System.currentTimeMillis();
216                 logger.info("Time taken to fail to acquire leased lock:" + (end - start) + " ms");
217                 return new ReturnType(ResultType.FAILURE, "Could not acquire lock");
218             }
219         } catch (Exception e) {
220             StringWriter sw = new StringWriter();
221             logger.error(e.getMessage());
222             String exceptionAsString = sw.toString();
223             return new ReturnType(ResultType.FAILURE,
224                             "Exception thrown in acquireLockWithLease:\n" + exceptionAsString);
225         }
226     }
227
228     public static boolean acquireLock(String key, String lockId) {
229         /*
230          * first check if I am on top. Since ids are not reusable there is no need to check
231          * lockStatus If the status is unlocked, then the above call will automatically return
232          * false.
233          */
234         Boolean result = false;
235         try {
236             result = getLockingServiceHandle().isMyTurn(lockId);
237         } catch (MusicLockingException e2) {
238             logger.error("Failed to aquireLock lockId " + lockId + " " + e2);
239         }
240         if (result == false) {
241             logger.info("In acquire lock: Not your turn, someone else has the lock");
242             return false;
243         }
244
245
246         // this is for backward compatibility where locks could also be acquired on just
247         // keyspaces or tables.
248         if (isTableOrKeySpaceLock(key) == true) {
249             logger.info("In acquire lock: A table or keyspace lock so no need to perform sync...so returning true");
250             return true;
251         }
252
253         // read the lock name corresponding to the key and if the status is locked or being locked,
254         // then return false
255         MusicLockState currentMls = null;
256         MusicLockState newMls = null;
257         try {
258             currentMls = getMusicLockState(key);
259             String currentLockHolder = currentMls.getLockHolder();
260             if (lockId.equals(currentLockHolder)) {
261                 logger.info("In acquire lock: You already have the lock!");
262                 return true;
263             }
264         } catch (NullPointerException e) {
265             logger.error("In acquire lock:No one has tried to acquire the lock yet..");
266         }
267
268         // change status to "being locked". This state transition is necessary to ensure syncing
269         // before granting the lock
270         String lockHolder = null;
271         boolean needToSyncQuorum = false;
272         if (currentMls != null)
273             needToSyncQuorum = currentMls.isNeedToSyncQuorum();
274
275
276         newMls = new MusicLockState(MusicLockState.LockStatus.BEING_LOCKED, lockHolder,
277                         needToSyncQuorum);
278         try {
279             getLockingServiceHandle().setLockState(key, newMls);
280         } catch (MusicLockingException e1) {
281             logger.error("Failed to set Lock state " + key + " " + e1);
282         }
283         logger.info("In acquire lock: Set lock state to being_locked");
284
285         // do syncing if this was a forced lock release
286         if (needToSyncQuorum) {
287             logger.info("In acquire lock: Since there was a forcible release, need to sync quorum!");
288             syncQuorum(key);
289         }
290
291         // change status to locked
292         lockHolder = lockId;
293         needToSyncQuorum = false;
294         newMls = new MusicLockState(MusicLockState.LockStatus.LOCKED, lockHolder, needToSyncQuorum);
295         try {
296             getLockingServiceHandle().setLockState(key, newMls);
297         } catch (MusicLockingException e) {
298             logger.error("Failed to set Lock state " + key + " " + e);
299         }
300         logger.info("In acquire lock: Set lock state to locked and assigned current lock ref "
301                         + lockId + " as holder");
302         return result;
303     }
304
305
306
307     /**
308      * 
309      * @param keyspaceName
310      * @param kspObject
311      * @return
312      * @throws Exception
313      */
314     public boolean createKeyspace(String keyspaceName, JsonKeySpace kspObject) throws Exception {
315         return true;
316     }
317
318
319     private static void syncQuorum(String key) {
320         logger.info("Performing sync operation---");
321         String[] splitString = key.split("\\.");
322         String keyspaceName = splitString[0];
323         String tableName = splitString[1];
324         String primaryKeyValue = splitString[2];
325         PreparedQueryObject selectQuery = new PreparedQueryObject();
326         PreparedQueryObject updateQuery = new PreparedQueryObject();
327
328         // get the primary key d
329         TableMetadata tableInfo = returnColumnMetadata(keyspaceName, tableName);
330         String primaryKeyName = tableInfo.getPrimaryKey().get(0).getName();// we only support single
331                                                                            // primary key
332         DataType primaryKeyType = tableInfo.getPrimaryKey().get(0).getType();
333         String cqlFormattedPrimaryKeyValue =
334                         MusicUtil.convertToCQLDataType(primaryKeyType, primaryKeyValue);
335
336         // get the row of data from a quorum
337         selectQuery.appendQueryString("SELECT *  FROM " + keyspaceName + "." + tableName + " WHERE "
338                         + primaryKeyName + "= ?" + ";");
339         selectQuery.addValue(cqlFormattedPrimaryKeyValue);
340         // String selectQuery = "SELECT * FROM "+keyspaceName+"."+tableName+ " WHERE
341         // "+primaryKeyName+"="+cqlFormattedPrimaryKeyValue+";";
342         ResultSet results = null;
343         try {
344             results = getDSHandle().executeCriticalGet(selectQuery);
345             // write it back to a quorum
346             Row row = results.one();
347             ColumnDefinitions colInfo = row.getColumnDefinitions();
348             int totalColumns = colInfo.size();
349             int counter = 1;
350             // String fieldValueString="";
351             StringBuilder fieldValueString = new StringBuilder("");
352             for (Definition definition : colInfo) {
353                 String colName = definition.getName();
354                 if (colName.equals(primaryKeyName))
355                     continue;
356                 DataType colType = definition.getType();
357                 Object valueObj = getDSHandle().getColValue(row, colName, colType);
358                 String valueString = MusicUtil.convertToCQLDataType(colType, valueObj);
359                 // fieldValueString = fieldValueString+ colName+"="+valueString;
360                 fieldValueString.append(colName + " = ?");
361                 updateQuery.addValue(valueString);
362                 if (counter != (totalColumns - 1))
363                     fieldValueString.append(",");
364                 counter = counter + 1;
365             }
366             updateQuery.appendQueryString("UPDATE " + keyspaceName + "." + tableName + " SET "
367                             + fieldValueString + " WHERE " + primaryKeyName + "= ? " + ";");
368             updateQuery.addValue(cqlFormattedPrimaryKeyValue);
369             // String updateQuery = "UPDATE "+keyspaceName+"."+tableName+" SET "+fieldValueString+"
370             // WHERE "+primaryKeyName+"="+cqlFormattedPrimaryKeyValue+";";
371
372             getDSHandle().executePut(updateQuery, "critical");
373         } catch (MusicServiceException | MusicQueryException e) {
374             logger.error("Failed to execute update query " + updateQuery + " " + e);
375         }
376     }
377
378
379     /**
380      * this function is mainly for the benchmarks to see the effect of lock deletion.
381      * 
382      * @param keyspaceName
383      * @param tableName
384      * @param primaryKey
385      * @param queryObject
386      * @param conditionInfo
387      * @return
388      */
389     public static ReturnType atomicPutWithDeleteLock(String keyspaceName, String tableName,
390                     String primaryKey, PreparedQueryObject queryObject, Condition conditionInfo) {
391         long start = System.currentTimeMillis();
392         String key = keyspaceName + "." + tableName + "." + primaryKey;
393         String lockId = createLockReference(key);
394         long lockCreationTime = System.currentTimeMillis();
395         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
396         ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod);
397         long lockAcqTime = System.currentTimeMillis();
398         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
399             logger.info("acquired lock with id " + lockId);
400             ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
401                             queryObject, lockId, conditionInfo);
402             long criticalPutTime = System.currentTimeMillis();
403             deleteLock(key);
404             long lockDeleteTime = System.currentTimeMillis();
405             String timingInfo = "|lock creation time:" + (lockCreationTime - start)
406                             + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
407                             + "|critical put time:" + (criticalPutTime - lockAcqTime)
408                             + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
409             criticalPutResult.setTimingInfo(timingInfo);
410             return criticalPutResult;
411         } else {
412             logger.info("unable to acquire lock, id " + lockId);
413             deleteLock(key);
414             return lockAcqResult;
415         }
416     }
417
418     /**
419      * 
420      * @param query
421      * @return ResultSet
422      */
423     public static ResultSet quorumGet(PreparedQueryObject query) {
424         ResultSet results = null;
425         try {
426             results = getDSHandle().executeCriticalGet(query);
427         } catch (MusicServiceException | MusicQueryException e) {
428             logger.error(e.getMessage());
429         }
430         return results;
431
432     }
433
434     /**
435      * 
436      * @param results
437      * @return
438      */
439     public static Map<String, HashMap<String, Object>> marshallResults(ResultSet results) {
440         return getDSHandle().marshalData(results);
441     }
442
443     /**
444      * 
445      * @param lockName
446      * @return
447      */
448     public static String whoseTurnIsIt(String lockName) {
449
450         try {
451             return getLockingServiceHandle().whoseTurnIsIt("/" + lockName) + "";
452         } catch (MusicLockingException e) {
453             logger.error("Failed whoseTurnIsIt  " + lockName + " " + e);
454         }
455         return null;
456
457
458     }
459
460     /**
461      * 
462      * @param lockId
463      * @return
464      */
465     public static String getLockNameFromId(String lockId) {
466         StringTokenizer st = new StringTokenizer(lockId);
467         return st.nextToken("$");
468     }
469
470     public static void destroyLockRef(String lockId) {
471         long start = System.currentTimeMillis();
472         try {
473             getLockingServiceHandle().unlockAndDeleteId(lockId);
474         } catch (MusicLockingException e) {
475             logger.error("Failed to Destroy Lock Ref  " + lockId + " " + e);
476         }
477         long end = System.currentTimeMillis();
478         logger.info("Time taken to destroy lock reference:" + (end - start) + " ms");
479     }
480
481     public static MusicLockState releaseLock(String lockId, boolean voluntaryRelease) {
482         long start = System.currentTimeMillis();
483         try {
484             getLockingServiceHandle().unlockAndDeleteId(lockId);
485         } catch (MusicLockingException e1) {
486             logger.error("Failed to release Lock " + lockId + " " + e1);
487         }
488         String lockName = getLockNameFromId(lockId);
489         MusicLockState mls;
490         String lockHolder = null;
491         if (voluntaryRelease) {
492             mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder);
493             logger.info("In unlock: lock voluntarily released for " + lockId);
494         } else {
495             boolean needToSyncQuorum = true;
496             mls = new MusicLockState(MusicLockState.LockStatus.UNLOCKED, lockHolder,
497                             needToSyncQuorum);
498             logger.info("In unlock: lock forcibly released for " + lockId);
499         }
500         try {
501             getLockingServiceHandle().setLockState(lockName, mls);
502         } catch (MusicLockingException e) {
503             logger.error("Failed to release Lock " + lockName + " " + e);
504         }
505         long end = System.currentTimeMillis();
506         logger.info("Time taken to release lock:" + (end - start) + " ms");
507         return mls;
508     }
509
510     /**
511      * 
512      * @param lockName
513      */
514     public static void deleteLock(String lockName) {
515         long start = System.currentTimeMillis();
516         logger.info("Deleting lock for " + lockName);
517         try {
518             getLockingServiceHandle().deleteLock("/" + lockName);
519         } catch (MusicLockingException e) {
520             logger.error("Failed to Delete Lock " + lockName + " " + e);
521         }
522         long end = System.currentTimeMillis();
523         logger.info("Time taken to delete lock:" + (end - start) + " ms");
524     }
525
526
527
528     /**
529      * 
530      * @param keyspace
531      * @param tablename
532      * @return
533      */
534     public static TableMetadata returnColumnMetadata(String keyspace, String tablename) {
535         return getDSHandle().returnColumnMetadata(keyspace, tablename);
536     }
537
538
539     /**
540      * 
541      * @param nodeName
542      */
543     public static void pureZkCreate(String nodeName) {
544         try {
545             getLockingServiceHandle().getzkLockHandle().createNode(nodeName);
546         } catch (MusicLockingException e) {
547             logger.error("Failed to get ZK Lock Handle " + e);
548         }
549     }
550
551     /**
552      * 
553      * @param nodeName
554      * @param data
555      */
556     public static void pureZkWrite(String nodeName, byte[] data) {
557         long start = System.currentTimeMillis();
558         logger.info("Performing zookeeper write to " + nodeName);
559         try {
560             getLockingServiceHandle().getzkLockHandle().setNodeData(nodeName, data);
561         } catch (MusicLockingException e) {
562             logger.error("Failed to get ZK Lock Handle " + e);
563         }
564         logger.info("Performed zookeeper write to " + nodeName);
565         long end = System.currentTimeMillis();
566         logger.info("Time taken for the actual zk put:" + (end - start) + " ms");
567     }
568
569     /**
570      * 
571      * @param nodeName
572      * @return
573      */
574     public static byte[] pureZkRead(String nodeName) {
575         long start = System.currentTimeMillis();
576         byte[] data = null;
577         try {
578             data = getLockingServiceHandle().getzkLockHandle().getNodeData(nodeName);
579         } catch (MusicLockingException e) {
580             logger.error("Failed to get ZK Lock Handle " + e);
581         }
582         long end = System.currentTimeMillis();
583         logger.info("Time taken for the actual zk put:" + (end - start) + " ms");
584         return data;
585     }
586
587
588
589     // Prepared Query Additions.
590
591     /**
592      * 
593      * @param keyspaceName
594      * @param tableName
595      * @param primaryKey
596      * @param queryObject
597      * @return ReturnType
598      * @throws MusicServiceException
599      */
600     public static ReturnType eventualPut(PreparedQueryObject queryObject) {
601         boolean result = false;
602         try {
603             result = getDSHandle().executePut(queryObject, MusicUtil.EVENTUAL);
604         } catch (MusicServiceException | MusicQueryException ex) {
605             logger.error(ex.getMessage() + "  " + ex.getCause() + " " + ex);
606         }
607         if (result) {
608             return new ReturnType(ResultType.SUCCESS, "Success");
609         } else {
610             return new ReturnType(ResultType.FAILURE, "Failure");
611         }
612     }
613
614     /**
615      * 
616      * @param keyspaceName
617      * @param tableName
618      * @param primaryKey
619      * @param queryObject
620      * @param lockId
621      * @return
622      */
623     public static ReturnType criticalPut(String keyspaceName, String tableName, String primaryKey,
624                     PreparedQueryObject queryObject, String lockId, Condition conditionInfo) {
625         long start = System.currentTimeMillis();
626
627         try {
628             MusicLockState mls = getLockingServiceHandle()
629                             .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
630             if (mls.getLockHolder().equals(lockId) == true) {
631                 if (conditionInfo != null)// check if condition is true
632                     if (conditionInfo.testCondition() == false)
633                         return new ReturnType(ResultType.FAILURE,
634                                         "Lock acquired but the condition is not true");
635                 getDSHandle().executePut(queryObject, MusicUtil.CRITICAL);
636                 long end = System.currentTimeMillis();
637                 logger.info("Time taken for the critical put:" + (end - start) + " ms");
638                 return new ReturnType(ResultType.SUCCESS, "Update performed");
639             } else
640                 return new ReturnType(ResultType.FAILURE,
641                                 "Cannot perform operation since you are the not the lock holder");
642         } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
643             logger.error(e.getMessage());
644             return new ReturnType(ResultType.FAILURE,
645                             "Exception thrown while doing the critical put, check sanctity of the row/conditions:\n"
646                                             + e.getMessage());
647         }
648
649     }
650
651     /**
652      * 
653      * @param queryObject
654      * @param consistency
655      * @return Boolean Indicates success or failure
656      * 
657      * 
658      */
659     public static boolean nonKeyRelatedPut(PreparedQueryObject queryObject, String consistency) {
660         // this is mainly for some functions like keyspace creation etc which does not
661         // really need the bells and whistles of Music locking.
662         boolean result = false;
663         try {
664             result = getDSHandle().executePut(queryObject, consistency);
665         } catch (MusicQueryException | MusicServiceException ex) {
666             logger.error(ex.getMessage());
667         }
668         return result;
669     }
670
671     /**
672      * This method performs DDL operation on cassandra.
673      * 
674      * @param queryObject query object containing prepared query and values
675      * @return ResultSet
676      */
677     public static ResultSet get(PreparedQueryObject queryObject) {
678         ResultSet results = null;
679         try {
680             results = getDSHandle().executeEventualGet(queryObject);
681         } catch (MusicQueryException | MusicServiceException e) {
682             logger.error(e.getMessage());
683         }
684         return results;
685     }
686
687     /**
688      * This method performs DDL operations on cassandra, if the the resource is available. Lock ID
689      * is used to check if the resource is free.
690      * 
691      * @param keyspaceName name of the keyspace
692      * @param tableName name of the table
693      * @param primaryKey primary key value
694      * @param queryObject query object containing prepared query and values
695      * @param lockId lock ID to check if the resource is free to perform the operation.
696      * @return ResultSet
697      */
698     public static ResultSet criticalGet(String keyspaceName, String tableName, String primaryKey,
699                     PreparedQueryObject queryObject, String lockId) throws MusicServiceException {
700         ResultSet results = null;
701         try {
702             MusicLockState mls = getLockingServiceHandle()
703                             .getLockState(keyspaceName + "." + tableName + "." + primaryKey);
704             if (mls.getLockHolder().equals(lockId)) {
705                 results = getDSHandle().executeCriticalGet(queryObject);
706             } else
707                 throw new MusicServiceException("YOU DO NOT HAVE THE LOCK");
708         } catch (MusicQueryException | MusicServiceException | MusicLockingException e) {
709             logger.error(e.getMessage());
710         }
711         return results;
712     }
713
714     /**
715      * This method performs DML operation on cassandra, when the lock of the dd is acquired.
716      * 
717      * @param keyspaceName name of the keyspace
718      * @param tableName name of the table
719      * @param primaryKey primary key value
720      * @param queryObject query object containing prepared query and values
721      * @return ReturnType
722      */
723     public static ReturnType atomicPut(String keyspaceName, String tableName, String primaryKey,
724                     PreparedQueryObject queryObject, Condition conditionInfo) {
725         long start = System.currentTimeMillis();
726         String key = keyspaceName + "." + tableName + "." + primaryKey;
727         String lockId = createLockReference(key);
728         long lockCreationTime = System.currentTimeMillis();
729         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
730         ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod);
731         long lockAcqTime = System.currentTimeMillis();
732         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
733             logger.info("acquired lock with id " + lockId);
734             ReturnType criticalPutResult = criticalPut(keyspaceName, tableName, primaryKey,
735                             queryObject, lockId, conditionInfo);
736             long criticalPutTime = System.currentTimeMillis();
737             boolean voluntaryRelease = true;
738             deleteLock(key);
739             long lockDeleteTime = System.currentTimeMillis();
740             String timingInfo = "|lock creation time:" + (lockCreationTime - start)
741                             + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
742                             + "|critical put time:" + (criticalPutTime - lockAcqTime)
743                             + "|lock delete time:" + (lockDeleteTime - criticalPutTime) + "|";
744             criticalPutResult.setTimingInfo(timingInfo);
745             return criticalPutResult;
746         } else {
747             logger.info("unable to acquire lock, id " + lockId);
748             destroyLockRef(lockId);
749             return lockAcqResult;
750         }
751     }
752
753
754     /**
755      * This method performs DDL operation on cassasndra, when the lock for the resource is acquired.
756      * 
757      * @param keyspaceName name of the keyspace
758      * @param tableName name of the table
759      * @param primaryKey primary key value
760      * @param queryObject query object containing prepared query and values
761      * @return ResultSet
762      * @throws MusicServiceException
763      */
764     public static ResultSet atomicGet(String keyspaceName, String tableName, String primaryKey,
765                     PreparedQueryObject queryObject) throws MusicServiceException {
766         String key = keyspaceName + "." + tableName + "." + primaryKey;
767         String lockId = createLockReference(key);
768         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
769         ReturnType lockAcqResult = acquireLockWithLease(key, lockId, leasePeriod);
770         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
771             logger.info("acquired lock with id " + lockId);
772             ResultSet result =
773                             criticalGet(keyspaceName, tableName, primaryKey, queryObject, lockId);
774             boolean voluntaryRelease = true;
775             releaseLock(lockId, voluntaryRelease);
776             return result;
777         } else {
778             logger.info("unable to acquire lock, id " + lockId);
779             return null;
780         }
781     }
782
783     /**
784      * authenticate user logic
785      * 
786      * @param nameSpace
787      * @param userId
788      * @param password
789      * @param keyspace
790      * @param aid
791      * @param operation
792      * @return
793      * @throws Exception
794      */
795     public static Map<String, Object> autheticateUser(String nameSpace, String userId,
796                     String password, String keyspace, String aid, String operation)
797                     throws Exception {
798         Map<String, Object> resultMap = new HashMap<>();
799         String uuid = null;
800         resultMap = CachingUtil.validateRequest(nameSpace, userId, password, keyspace, aid,
801                         operation);
802         if (!resultMap.isEmpty())
803             return resultMap;
804         if (aid == null && (userId == null || password == null)) {
805             logger.error("One or more required headers is missing. userId: " + userId
806                             + " :: password: " + password);
807             resultMap.put("Exception",
808                             "UserId and Password are mandatory for the operation " + operation);
809             return resultMap;
810         }
811         boolean isAAF = CachingUtil.isAAFApplication(nameSpace);
812         if (!isAAF && aid != null && aid.length() > 0) { // Non AAF app
813             resultMap = CachingUtil.authenticateAIDUser(aid, keyspace);
814             if (!resultMap.isEmpty())
815                 return resultMap;
816         }
817         if (isAAF && nameSpace != null && userId != null && password != null) {
818             boolean isValid = true;
819             try {
820                 isValid = CachingUtil.authenticateAAFUser(nameSpace, userId, password, keyspace);
821             } catch (Exception e) {
822                 logger.error("Got exception while AAF authentication for namespace " + nameSpace);
823                 resultMap.put("Exception", e.getMessage());
824                 // return resultMap;
825             }
826             if (!isValid) {
827                 logger.error("User not authenticated with AAF.");
828                 resultMap.put("Exception", "User not authenticated...");
829                 // return resultMap;
830             }
831             if (!resultMap.isEmpty())
832                 return resultMap;
833
834         }
835
836         if (operation.equals("createKeySpace")) {
837             logger.info("AID is not provided. Creating new UUID for keyspace.");
838             PreparedQueryObject pQuery = new PreparedQueryObject();
839             pQuery.appendQueryString(
840                             "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
841             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
842             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
843             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
844                             MusicUtil.DEFAULTKEYSPACENAME));
845
846             try {
847                 Row rs = MusicCore.get(pQuery).one();
848                 uuid = rs.getUUID("uuid").toString();
849                 resultMap.put("uuid", "existing");
850             } catch (Exception e) {
851                 logger.info("No UUID found in DB. So creating new UUID.");
852                 uuid = CachingUtil.generateUUID();
853                 resultMap.put("uuid", "new");
854             }
855
856             pQuery = new PreparedQueryObject();
857             pQuery.appendQueryString(
858                             "INSERT into admin.keyspace_master (uuid, keyspace_name, application_name, is_api, "
859                                             + "password, username, is_aaf) values (?,?,?,?,?,?,?)");
860             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.uuid(), uuid));
861             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
862             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), nameSpace));
863             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), "True"));
864             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), password));
865             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
866             pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), isAAF));
867             CachingUtil.updateMusicCache(uuid, keyspace);
868             MusicCore.eventualPut(pQuery);
869             resultMap.put("aid", uuid);
870         }
871
872         return resultMap;
873     }
874 }