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