Merge "MusicPolicyVoilationException-Junit TestCase added"
[music.git] / src / main / java / org / onap / music / main / MusicUtil.java
1 /*
2  * ============LICENSE_START==========================================
3  * org.onap.music
4  * ===================================================================
5  *  Copyright (c) 2017 AT&T Intellectual Property
6  * ===================================================================
7  * Modifications Copyright (c) 2018 IBM.
8  * ===================================================================
9  *  Licensed under the Apache License, Version 2.0 (the "License");
10  *  you may not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS,
17  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  *
21  * ============LICENSE_END=============================================
22  * ====================================================================
23  */
24
25 package org.onap.music.main;
26
27 import java.io.File;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.math.BigInteger;
32 import java.nio.ByteBuffer;
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Properties;
38 import java.util.Scanner;
39 import java.util.StringTokenizer;
40 import java.util.UUID;
41 import java.util.concurrent.ConcurrentHashMap;
42 import java.util.concurrent.ConcurrentMap;
43
44 import javax.ws.rs.core.Response;
45 import javax.ws.rs.core.Response.ResponseBuilder;
46
47 import org.onap.music.datastore.PreparedQueryObject;
48 import org.onap.music.eelf.logging.EELFLoggerDelegate;
49 import org.onap.music.exceptions.MusicQueryException;
50 import org.onap.music.exceptions.MusicServiceException;
51 import org.onap.music.service.MusicCoreService;
52 import org.onap.music.service.impl.MusicCassaCore;
53 import org.onap.music.service.impl.MusicZKCore;
54
55 import com.datastax.driver.core.ConsistencyLevel;
56 import com.datastax.driver.core.DataType;
57 import com.sun.jersey.core.util.Base64;
58
59 /**
60  * @author nelson24
61  *
62  *         Properties This will take Properties and load them into MusicUtil.
63  *         This is a hack for now. Eventually it would bebest to do this in
64  *         another way.
65  *
66  */
67 public class MusicUtil {
68     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
69
70     public static final String ATOMIC = "atomic";
71     public static final String EVENTUAL = "eventual";
72     public static final String CRITICAL = "critical";
73     public static final String EVENTUAL_NB = "eventual_nb";
74     public static final String ALL = "all";
75     public static final String QUORUM = "quorum";
76     public static final String ONE = "one";
77     public static final String ATOMICDELETELOCK = "atomic_delete_lock";
78     public static final String DEFAULTKEYSPACENAME = "TBD";
79     private static final String XLATESTVERSION = "X-latestVersion";
80     private static final String XMINORVERSION = "X-minorVersion";
81     private static final String XPATCHVERSION = "X-patchVersion";
82     public static final String SELECT = "select";
83     public static final String INSERT = "insert";
84     public static final String UPDATE = "update";
85     public static final String UPSERT = "upsert";
86     public static final String USERID = "userId";
87     public static final String PASSWORD = "password";
88     public static final String CASSANDRA = "cassandra";
89     public static final String ZOOKEEPER = "zookeeper";
90
91     public static final String AUTHORIZATION = "Authorization";
92
93     private static final String LOCALHOST = "localhost";
94     private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties";
95
96     private static int myId = 0;
97     private static ArrayList<String> allIds = new ArrayList<>();
98     private static String publicIp = "";
99     private static ArrayList<String> allPublicIps = new ArrayList<>();
100     private static String myZkHost = LOCALHOST;
101     private static String myCassaHost = LOCALHOST;
102     private static String defaultMusicIp = LOCALHOST;
103     private static int cassandraPort = 9042;
104     private static int notifytimeout = 30000;
105     private static int notifyinterval = 5000;
106     private static int cacheObjectMaxLife = -1;
107     private static String lockUsing = MusicUtil.CASSANDRA;
108     private static boolean isCadi = false;
109     
110     private static boolean debug = true;
111     private static String version = "2.3.0";
112     private static String musicRestIp = LOCALHOST;
113     private static String musicPropertiesFilePath = PROPERTIES_FILE;
114     private static long defaultLockLeasePeriod = 6000;
115     private static final String[] propKeys = new String[] { "zookeeper.host", "cassandra.host", "music.ip", "debug",
116             "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", "public.ip",
117             "all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url","admin.username","admin.password","aaf.admin.url",
118             "music.namespace","admin.aaf.role","cassandra.port","lock.using"};
119     private static final String[] cosistencyLevel = new String[] {
120             "ALL","EACH_QUORUM","QUORUM","LOCAL_QUORUM","ONE","TWO","THREE","LOCAL_ONE","ANY","SERIAL","LOCAL_SERIAL"};
121     private static final Map<String,ConsistencyLevel> consistencyName = new HashMap<>();
122     static {
123         consistencyName.put("ONE",ConsistencyLevel.ONE);
124         consistencyName.put("TWO",ConsistencyLevel.TWO);
125         consistencyName.put("THREE",ConsistencyLevel.THREE);
126         consistencyName.put("SERIAL",ConsistencyLevel.SERIAL);
127         consistencyName.put("ALL",ConsistencyLevel.ALL);
128         consistencyName.put("EACH_QUORUM",ConsistencyLevel.EACH_QUORUM);
129         consistencyName.put("QUORUM",ConsistencyLevel.QUORUM);
130         consistencyName.put("LOCAL_QUORUM",ConsistencyLevel.LOCAL_QUORUM);
131         consistencyName.put("LOCAL_ONE",ConsistencyLevel.LOCAL_ONE);
132         consistencyName.put("LOCAL_SERIAL",ConsistencyLevel.LOCAL_SERIAL);
133     }
134
135     private static String cassName = "cassandra";
136     private static String cassPwd;
137     private static String aafEndpointUrl = null;
138     public static ConcurrentMap<String, Long> zkNodeMap = new ConcurrentHashMap<>();
139     private static String adminId = "username";
140     private static String adminPass= "password";
141     private static String aafAdminUrl= null;
142     private static String musicNamespace= "com.att.music.api";
143     private static String adminAafRole= "com.att.music.api.admin_api";
144     
145     public static final long MusicEternityEpochMillis = 1533081600000L; // Wednesday, August 1, 2018 12:00:00 AM
146
147     public static final long MaxLockReferenceTimePart = 1000000000000L; // millis after eternity (eq sometime in 2050)
148     
149     public static final long MaxCriticalSectionDurationMillis = 1L * 24 * 60 * 60 * 1000; // 1 day
150
151
152     public static String getLockUsing() {
153         return lockUsing;
154     }
155
156
157     public static void setLockUsing(String lockUsing) {
158         MusicUtil.lockUsing = lockUsing;
159     }
160     
161     public static String getAafAdminUrl() {
162         return aafAdminUrl;
163     }
164
165
166     public static void setAafAdminUrl(String aafAdminUrl) {
167         MusicUtil.aafAdminUrl = aafAdminUrl;
168     }
169
170
171     public static String getMusicNamespace() {
172         return musicNamespace;
173     }
174
175
176     public static void setMusicNamespace(String musicNamespace) {
177         MusicUtil.musicNamespace = musicNamespace;
178     }
179
180
181     public static String getAdminAafRole() {
182         return adminAafRole;
183     }
184
185
186     public static void setAdminAafRole(String adminAafRole) {
187         MusicUtil.adminAafRole = adminAafRole;
188     }
189
190
191
192     public static String getAdminId() {
193         return adminId;
194     }
195
196
197     public static void setAdminId(String adminId) {
198         MusicUtil.adminId = adminId;
199     }
200
201
202     public static String getAdminPass() {
203         return adminPass;
204     }
205
206     public static void setAdminPass(String adminPass) {
207         MusicUtil.adminPass = adminPass;
208     }
209
210
211     private MusicUtil() {
212         throw new IllegalStateException("Utility Class");
213     }
214     /**
215      *
216      * @return cassandra port
217      */
218     public static int getCassandraPort() {
219         return cassandraPort;
220     }
221
222     /**
223      * set cassandra port
224      * @param cassandraPort
225      */
226     public static void setCassandraPort(int cassandraPort) {
227         MusicUtil.cassandraPort = cassandraPort;
228     }
229     /**
230      * @return the cassName
231      */
232     public static String getCassName() {
233         return cassName;
234     }
235
236     /**
237      * @return the cassPwd
238      */
239     public static String getCassPwd() {
240         return cassPwd;
241     }
242
243     /**
244      * @return the aafEndpointUrl
245      */
246     public static String getAafEndpointUrl() {
247         return aafEndpointUrl;
248     }
249
250     /**
251      *
252      * @param aafEndpointUrl
253      */
254     public static void setAafEndpointUrl(String aafEndpointUrl) {
255         MusicUtil.aafEndpointUrl = aafEndpointUrl;
256     }
257
258     /**
259      *
260      * @return
261      */
262     public static int getMyId() {
263         return myId;
264     }
265
266     /**
267      *
268      * @param myId
269      */
270     public static void setMyId(int myId) {
271         MusicUtil.myId = myId;
272     }
273
274     /**
275      *
276      * @return
277      */
278     public static List<String> getAllIds() {
279         return allIds;
280     }
281
282     /**
283      *
284      * @param allIds
285      */
286     public static void setAllIds(List<String> allIds) {
287         MusicUtil.allIds = (ArrayList<String>) allIds;
288     }
289
290     /**
291      *
292      * @return
293      */
294     public static String getPublicIp() {
295         return publicIp;
296     }
297
298     /**
299      *
300      * @param publicIp
301      */
302     public static void setPublicIp(String publicIp) {
303         MusicUtil.publicIp = publicIp;
304     }
305
306     /**
307      *
308      * @return
309      */
310     public static List<String> getAllPublicIps() {
311         return allPublicIps;
312     }
313
314     /**
315      *
316      * @param allPublicIps
317      */
318     public static void setAllPublicIps(List<String> allPublicIps) {
319         MusicUtil.allPublicIps = (ArrayList<String>) allPublicIps;
320     }
321
322     /**
323      * Returns An array of property names that should be in the Properties
324      * files.
325      *
326      * @return
327      */
328     public static String[] getPropkeys() {
329         return propKeys;
330     }
331
332     /**
333      * Get MusicRestIp - default = localhost property file value - music.rest.ip
334      *
335      * @return
336      */
337     public static String getMusicRestIp() {
338         return musicRestIp;
339     }
340
341     /**
342      * Set MusicRestIp
343      *
344      * @param musicRestIp
345      */
346     public static void setMusicRestIp(String musicRestIp) {
347         MusicUtil.musicRestIp = musicRestIp;
348     }
349
350     /**
351      * Get MusicPropertiesFilePath - Default = /opt/music/music.properties
352      * property file value - music.properties
353      *
354      * @return
355      */
356     public static String getMusicPropertiesFilePath() {
357         return musicPropertiesFilePath;
358     }
359
360     /**
361      * Set MusicPropertiesFilePath
362      *
363      * @param musicPropertiesFilePath
364      */
365     public static void setMusicPropertiesFilePath(String musicPropertiesFilePath) {
366         MusicUtil.musicPropertiesFilePath = musicPropertiesFilePath;
367     }
368
369     /**
370      * Get DefaultLockLeasePeriod - Default = 6000 property file value -
371      * lock.lease.period
372      *
373      * @return
374      */
375     public static long getDefaultLockLeasePeriod() {
376         return defaultLockLeasePeriod;
377     }
378
379     /**
380      * Set DefaultLockLeasePeriod
381      *
382      * @param defaultLockLeasePeriod
383      */
384     public static void setDefaultLockLeasePeriod(long defaultLockLeasePeriod) {
385         MusicUtil.defaultLockLeasePeriod = defaultLockLeasePeriod;
386     }
387
388     /**
389      * Set Debug
390      *
391      * @param debug
392      */
393     public static void setDebug(boolean debug) {
394         MusicUtil.debug = debug;
395     }
396
397     /**
398      * Is Debug - Default = true property file value - debug
399      *
400      * @return
401      */
402     public static boolean isDebug() {
403         return debug;
404     }
405
406     /**
407      * Set Version
408      *
409      * @param version
410      */
411     public static void setVersion(String version) {
412         MusicUtil.version = version;
413     }
414
415     /**
416      * Return the version property file value - version
417      *
418      * @return
419      */
420     public static String getVersion() {
421         return version;
422     }
423
424     /**
425      * Get MyZkHost - Zookeeper Hostname - Default = localhost property file
426      * value - zookeeper.host
427      *
428      * @return
429      */
430     public static String getMyZkHost() {
431         return myZkHost;
432     }
433
434     /**
435      * Set MyZkHost - Zookeeper Hostname
436      *
437      * @param myZkHost
438      */
439     public static void setMyZkHost(String myZkHost) {
440         MusicUtil.myZkHost = myZkHost;
441     }
442
443     /**
444      * Get MyCassHost - Cassandra Hostname - Default = localhost property file
445      * value - cassandra.host
446      *
447      * @return
448      */
449     public static String getMyCassaHost() {
450         return myCassaHost;
451     }
452
453     /**
454      * Set MyCassHost - Cassandra Hostname
455      *
456      * @param myCassaHost
457      */
458     public static void setMyCassaHost(String myCassaHost) {
459         MusicUtil.myCassaHost = myCassaHost;
460     }
461
462     /**
463      * Get DefaultMusicIp - Default = localhost property file value - music.ip
464      *
465      * @return
466      */
467     public static String getDefaultMusicIp() {
468         return defaultMusicIp;
469     }
470
471     /**
472      * Set DefaultMusicIp
473      *
474      * @param defaultMusicIp
475      */
476     public static void setDefaultMusicIp(String defaultMusicIp) {
477         MusicUtil.defaultMusicIp = defaultMusicIp;
478     }
479
480     /**
481      *
482      * @return
483      */
484     public static String getTestType() {
485         String testType = "";
486         try {
487             Scanner fileScanner = new Scanner(new File(""));
488             testType = fileScanner.next();// ignore the my id line
489             @SuppressWarnings("unused")
490             String batchSize = fileScanner.next();// ignore the my public ip
491                                                     // line
492             fileScanner.close();
493         } catch (FileNotFoundException e) {
494             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
495         }
496         return testType;
497
498     }
499
500     /**
501      *
502      * @param time
503      */
504     public static void sleep(long time) {
505         try {
506             Thread.sleep(time);
507         } catch (InterruptedException e) {
508             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
509             Thread.currentThread().interrupt();
510         }
511     }
512
513     /**
514      * Utility function to check if the query object is valid.
515      *
516      * @param withparams
517      * @param queryObject
518      * @return
519      */
520     public static boolean isValidQueryObject(boolean withparams, PreparedQueryObject queryObject) {
521         if (withparams) {
522             int noOfValues = queryObject.getValues().size();
523             int noOfParams = 0;
524             char[] temp = queryObject.getQuery().toCharArray();
525             for (int i = 0; i < temp.length; i++) {
526                 if (temp[i] == '?')
527                     noOfParams++;
528             }
529             return (noOfValues == noOfParams);
530         } else {
531             return !queryObject.getQuery().isEmpty();
532         }
533
534     }
535
536     public static void setCassName(String cassName) {
537         MusicUtil.cassName = cassName;
538     }
539
540     public static void setCassPwd(String cassPwd) {
541         MusicUtil.cassPwd = cassPwd;
542     }
543
544     @SuppressWarnings("unchecked")
545     public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception {
546
547         String value = "";
548         switch (type.getName()) {
549         case UUID:
550             value = valueObj + "";
551             break;
552         case TEXT:
553         case VARCHAR:
554             String valueString = valueObj + "";
555             valueString = valueString.replace("'", "''");
556             value = "'" + valueString + "'";
557             break;
558         case MAP: {
559             Map<String, Object> otMap = (Map<String, Object>) valueObj;
560             value = "{" + jsonMaptoSqlString(otMap, ",") + "}";
561             break;
562         }
563         default:
564             value = valueObj + "";
565             break;
566         }
567         return value;
568     }
569
570     /**
571      *
572      * @param colType
573      * @param valueObj
574      * @return
575      * @throws MusicTypeConversionException
576      * @throws Exception
577      */
578     @SuppressWarnings("unchecked")
579     public static Object convertToActualDataType(DataType colType, Object valueObj) throws Exception {
580         String valueObjString = valueObj + "";
581         switch (colType.getName()) {
582             case UUID:
583                 return UUID.fromString(valueObjString);
584             case VARINT:
585                 return BigInteger.valueOf(Long.parseLong(valueObjString));
586             case BIGINT:
587                 return Long.parseLong(valueObjString);
588             case INT:
589                 return Integer.parseInt(valueObjString);
590             case FLOAT:
591                 return Float.parseFloat(valueObjString);
592             case DOUBLE:
593                 return Double.parseDouble(valueObjString);
594             case BOOLEAN:
595                 return Boolean.parseBoolean(valueObjString);
596             case MAP:
597                 return (Map<String, Object>) valueObj;
598             case LIST:
599                 return (List<Object>)valueObj;
600             case BLOB:
601
602             default:
603                 return valueObjString;
604         }
605     }
606
607     public static ByteBuffer convertToActualDataType(DataType colType, byte[] valueObj) {
608          ByteBuffer buffer = ByteBuffer.wrap(valueObj);
609          return buffer;
610     }
611
612     /**
613      *
614      * Utility function to parse json map into sql like string
615      *
616      * @param jMap
617      * @param lineDelimiter
618      * @return
619      */
620
621     public static String jsonMaptoSqlString(Map<String, Object> jMap, String lineDelimiter) throws Exception{
622         StringBuilder sqlString = new StringBuilder();
623         int counter = 0;
624         for (Map.Entry<String, Object> entry : jMap.entrySet()) {
625             Object ot = entry.getValue();
626             String value = ot + "";
627             if (ot instanceof String) {
628                 value = "'" + value.replace("'", "''") + "'";
629             }
630             sqlString.append("'" + entry.getKey() + "':" + value);
631             if (counter != jMap.size() - 1)
632                 sqlString.append(lineDelimiter);
633             counter = counter + 1;
634         }
635         return sqlString.toString();
636     }
637
638     @SuppressWarnings("unused")
639     public static String buildVersion(String major, String minor, String patch) {
640         if (minor != null) {
641             major += "." + minor;
642             if (patch != null) {
643                 major += "." + patch;
644             }
645         }
646         return major;
647     }
648
649     /**
650      * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion
651      * X-latestVerstion will be equal to the latest full version.
652      * X-minorVersion - will be equal to the latest minor version.
653      * X-pathVersion - will be equal to the latest patch version.
654      * Future plans will change this.
655      * @param response
656      * @param major
657      * @param minor
658      * @param patch
659      * @return
660      */
661     public static ResponseBuilder buildVersionResponse(String major, String minor, String patch) {
662         ResponseBuilder response = Response.noContent();
663         String versionIn = buildVersion(major,minor,patch);
664         String version = MusicUtil.getVersion();
665         String[] verArray = version.split("\\.",3);
666         if ( minor != null ) {
667             response.header(XMINORVERSION,minor);
668         } else {
669             response.header(XMINORVERSION,verArray[1]);
670         }
671         if ( patch != null ) {
672             response.header(XPATCHVERSION,patch);
673         } else {
674             response.header(XPATCHVERSION,verArray[2]);
675         }
676         response.header(XLATESTVERSION,version);
677         logger.info(EELFLoggerDelegate.applicationLogger,"Version In:" + versionIn);
678         return response;
679     }
680
681
682     public static Map<String,String> extractBasicAuthentication(String authorization){
683         Map<String,String> authValues = new HashMap<>();
684         if(authorization == null) {
685             authValues.put("ERROR", "Authorization cannot be null");
686             return authValues;
687         }
688         authorization = authorization.replaceFirst("Basic", "");
689         String decoded = Base64.base64Decode(authorization);
690         StringTokenizer token = new StringTokenizer(decoded, ":");
691         authValues.put(MusicUtil.USERID, token.nextToken());
692         authValues.put(MusicUtil.PASSWORD,token.nextToken());
693         return authValues;
694
695     }
696
697     public static boolean isValidConsistency(String consistency) {
698         for (String string : cosistencyLevel) {
699             if (string.equalsIgnoreCase(consistency))
700                 return true;
701         }
702         return false;
703
704     }
705
706     public static ConsistencyLevel getConsistencyLevel(String consistency) {
707         return consistencyName.get(consistency.toUpperCase());
708         }
709
710         public static void loadProperties() throws Exception {
711         Properties prop = new Properties();
712         InputStream input = null;
713         try {
714             // load the properties file
715             input = MusicUtil.class.getClassLoader().getResourceAsStream("music.properties");
716             prop.load(input);
717         } catch (Exception ex) {
718             logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file.");
719             throw new Exception();
720         } finally {
721             if (input != null) {
722                 try {
723                     input.close();
724                 } catch (IOException e) {
725                     e.printStackTrace();
726                 }
727             }
728         }
729         // get the property value and return it
730         MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host"));
731         String zkHosts = prop.getProperty("zookeeper.host");
732         MusicUtil.setMyZkHost(zkHosts);
733         MusicUtil.setCassName(prop.getProperty("cassandra.user"));
734         MusicUtil.setCassPwd(prop.getProperty("cassandra.password"));
735         MusicUtil.setCassandraPort(Integer.parseInt(prop.getProperty("cassandra.port")));
736         MusicUtil.setNotifyTimeOut(Integer.parseInt(prop.getProperty("notify.timeout")));
737         MusicUtil.setNotifyInterval(Integer.parseInt(prop.getProperty("notify.interval")));
738         MusicUtil.setCacheObjectMaxLife(Integer.parseInt(prop.getProperty("cacheobject.maxlife")));
739     }
740
741     public static void setNotifyInterval(int notifyinterval) {
742         MusicUtil.notifyinterval = notifyinterval;
743     }
744     public static void setNotifyTimeOut(int notifytimeout) {
745         MusicUtil.notifytimeout = notifytimeout;
746     }
747
748     public static int getNotifyInterval() {
749         return MusicUtil.notifyinterval;
750     }
751
752     public static int getNotifyTimeout() {
753         return MusicUtil.notifytimeout;
754     }
755
756     public static int getCacheObjectMaxLife() {
757         return MusicUtil.cacheObjectMaxLife;
758     }
759
760     public static void setCacheObjectMaxLife(int cacheObjectMaxLife) {
761         MusicUtil.cacheObjectMaxLife = cacheObjectMaxLife;
762     }
763     
764     /**
765      * Given the time of write for an update in a critical section, this method provides a transformed timestamp
766      * that ensures that a previous lock holder who is still alive can never corrupt a later critical section.
767      * The main idea is to us the lock reference to clearly demarcate the timestamps across critical sections.
768      * @param the UUID lock reference associated with the write.
769      * @param the long timeOfWrite which is the actual time at which the write took place
770      * @throws MusicServiceException
771      * @throws MusicQueryException
772      */
773     public static long v2sTimeStampInMicroseconds(long ordinal, long timeOfWrite) throws MusicServiceException, MusicQueryException {
774         // TODO: use acquire time instead of music eternity epoch
775         long ts = ordinal * MaxLockReferenceTimePart + (timeOfWrite - MusicEternityEpochMillis);
776
777         return ts;
778     }
779     
780     public static MusicCoreService  getMusicCoreService() {
781         if(getLockUsing().equals(MusicUtil.CASSANDRA))
782             return MusicCassaCore.getInstance();
783         else if (getLockUsing().equals(MusicUtil.ZOOKEEPER))
784             return MusicZKCore.getInstance();
785         else
786             return MusicCassaCore.getInstance();
787     }
788     
789     /**
790      * @param lockName
791      * @return
792      */
793     public static Map<String, Object> validateLock(String lockName) {
794         Map<String, Object> resultMap = new HashMap<>();
795         String[] locks = lockName.split("\\.");
796         if(locks.length < 3) {
797             resultMap.put("Error", "Invalid lock. Please make sure lock is of the type keyspaceName.tableName.primaryKey");
798             return resultMap;
799         }
800         String keyspace= locks[0];
801         if(keyspace.startsWith("$"))
802             keyspace = keyspace.substring(1);
803         resultMap.put("keyspace",keyspace);
804         return resultMap;
805     }
806
807
808     public static void setIsCadi(boolean isCadi) {
809         // TODO Auto-generated method stub
810         MusicUtil.isCadi = isCadi;
811     }
812     
813     public static boolean getIsCadi() {
814         return MusicUtil.isCadi;
815     }
816
817 }
818