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