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