Merge "fixed sonar issue in MusicUtil.java"
[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 package org.onap.music.main;
25
26 import java.io.File;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.math.BigInteger;
31 import java.nio.ByteBuffer;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Properties;
37 import java.util.Scanner;
38 import java.util.StringTokenizer;
39 import java.util.UUID;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.ConcurrentMap;
42
43 import javax.ws.rs.core.Response;
44 import javax.ws.rs.core.Response.ResponseBuilder;
45
46 import org.onap.music.datastore.PreparedQueryObject;
47 import org.onap.music.eelf.logging.EELFLoggerDelegate;
48
49 import com.datastax.driver.core.DataType;
50 import com.sun.jersey.core.util.Base64;
51
52 /**
53  * @author nelson24
54  * 
55  *         Properties This will take Properties and load them into MusicUtil.
56  *         This is a hack for now. Eventually it would bebest to do this in
57  *         another way.
58  * 
59  */
60 public class MusicUtil {
61     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicUtil.class);
62     
63     public static final String ATOMIC = "atomic";
64     public static final String EVENTUAL = "eventual";
65     public static final String CRITICAL = "critical";
66     public static final String ATOMICDELETELOCK = "atomic_delete_lock";
67     public static final String DEFAULTKEYSPACENAME = "TBD";
68     private static final String XLATESTVERSION = "X-latestVersion";
69     private static final String XMINORVERSION = "X-minorVersion";
70     private static final String XPATCHVERSION = "X-patchVersion";
71     public static final String SELECT = "select";
72     public static final String INSERT = "insert";
73     public static final String UPDATE = "update";
74     public static final String UPSERT = "upsert";
75     public static final String USERID = "userId";
76     public static final String PASSWORD = "password";
77
78         public static final String AUTHORIZATION = "Authorization";
79
80     private static final String LOCALHOST = "localhost";
81     private static final String PROPERTIES_FILE = "/opt/app/music/etc/music.properties";
82     
83     private static int myId = 0;
84     private static ArrayList<String> allIds = new ArrayList<>();
85     private static String publicIp = "";
86     private static ArrayList<String> allPublicIps = new ArrayList<>();
87     private static String myZkHost = LOCALHOST;
88     private static String myCassaHost = LOCALHOST;
89     private static String defaultMusicIp = LOCALHOST;
90     private static int cassandraPort = 9042;
91     private static int notifytimeout = 30000;
92     private static int notifyinterval = 5000;
93     
94     private static boolean debug = true;
95     private static String version = "2.3.0";
96     private static String musicRestIp = LOCALHOST;
97     private static String musicPropertiesFilePath = PROPERTIES_FILE;
98     private static long defaultLockLeasePeriod = 6000;
99     private static final String[] propKeys = new String[] { "zookeeper.host", "cassandra.host", "music.ip", "debug",
100             "version", "music.rest.ip", "music.properties", "lock.lease.period", "id", "all.ids", "public.ip",
101             "all.pubic.ips", "cassandra.user", "cassandra.password", "aaf.endpoint.url","cassandra.port", "notify.timeout", "notify.interval" };
102
103     private static String cassName = "cassandra";
104     private static String cassPwd;
105     private static String aafEndpointUrl = null;
106     public static final ConcurrentMap<String, Long> zkNodeMap = new ConcurrentHashMap<>();
107
108     private MusicUtil() {
109         throw new IllegalStateException("Utility Class");
110     }
111     /**
112      * 
113      * @return cassandra port
114      */
115     public static int getCassandraPort() {
116                 return cassandraPort;
117         }
118
119     /**
120      * set cassandra port
121      * @param cassandraPort
122      */
123         public static void setCassandraPort(int cassandraPort) {
124                 MusicUtil.cassandraPort = cassandraPort;
125         }
126     /**
127      * @return the cassName
128      */
129     public static String getCassName() {
130         return cassName;
131     }
132
133     /**
134      * @return the cassPwd
135      */
136     public static String getCassPwd() {
137         return cassPwd;
138     }
139
140     /**
141      * @return the aafEndpointUrl
142      */
143     public static String getAafEndpointUrl() {
144         return aafEndpointUrl;
145     }
146
147     /**
148      * 
149      * @param aafEndpointUrl
150      */
151     public static void setAafEndpointUrl(String aafEndpointUrl) {
152         MusicUtil.aafEndpointUrl = aafEndpointUrl;
153     }
154
155     /**
156      * 
157      * @return
158      */
159     public static int getMyId() {
160         return myId;
161     }
162
163     /**
164      * 
165      * @param myId
166      */
167     public static void setMyId(int myId) {
168         MusicUtil.myId = myId;
169     }
170
171     /**
172      * 
173      * @return
174      */
175     public static List<String> getAllIds() {
176         return allIds;
177     }
178
179     /**
180      * 
181      * @param allIds
182      */
183     public static void setAllIds(List<String> allIds) {
184         MusicUtil.allIds = (ArrayList<String>) allIds;
185     }
186
187     /**
188      * 
189      * @return
190      */
191     public static String getPublicIp() {
192         return publicIp;
193     }
194
195     /**
196      * 
197      * @param publicIp
198      */
199     public static void setPublicIp(String publicIp) {
200         MusicUtil.publicIp = publicIp;
201     }
202
203     /**
204      * 
205      * @return
206      */
207     public static List<String> getAllPublicIps() {
208         return allPublicIps;
209     }
210
211     /**
212      * 
213      * @param allPublicIps
214      */
215     public static void setAllPublicIps(List<String> allPublicIps) {
216         MusicUtil.allPublicIps = (ArrayList<String>) allPublicIps;
217     }
218
219     /**
220      * Returns An array of property names that should be in the Properties
221      * files.
222      * 
223      * @return
224      */
225     public static String[] getPropkeys() {
226         return propKeys;
227     }
228
229     /**
230      * Get MusicRestIp - default = localhost property file value - music.rest.ip
231      * 
232      * @return
233      */
234     public static String getMusicRestIp() {
235         return musicRestIp;
236     }
237
238     /**
239      * Set MusicRestIp
240      * 
241      * @param musicRestIp
242      */
243     public static void setMusicRestIp(String musicRestIp) {
244         MusicUtil.musicRestIp = musicRestIp;
245     }
246
247     /**
248      * Get MusicPropertiesFilePath - Default = /opt/music/music.properties
249      * property file value - music.properties
250      * 
251      * @return
252      */
253     public static String getMusicPropertiesFilePath() {
254         return musicPropertiesFilePath;
255     }
256
257     /**
258      * Set MusicPropertiesFilePath
259      * 
260      * @param musicPropertiesFilePath
261      */
262     public static void setMusicPropertiesFilePath(String musicPropertiesFilePath) {
263         MusicUtil.musicPropertiesFilePath = musicPropertiesFilePath;
264     }
265
266     /**
267      * Get DefaultLockLeasePeriod - Default = 6000 property file value -
268      * lock.lease.period
269      * 
270      * @return
271      */
272     public static long getDefaultLockLeasePeriod() {
273         return defaultLockLeasePeriod;
274     }
275
276     /**
277      * Set DefaultLockLeasePeriod
278      * 
279      * @param defaultLockLeasePeriod
280      */
281     public static void setDefaultLockLeasePeriod(long defaultLockLeasePeriod) {
282         MusicUtil.defaultLockLeasePeriod = defaultLockLeasePeriod;
283     }
284
285     /**
286      * Set Debug
287      * 
288      * @param debug
289      */
290     public static void setDebug(boolean debug) {
291         MusicUtil.debug = debug;
292     }
293
294     /**
295      * Is Debug - Default = true property file value - debug
296      * 
297      * @return
298      */
299     public static boolean isDebug() {
300         return debug;
301     }
302
303     /**
304      * Set Version
305      * 
306      * @param version
307      */
308     public static void setVersion(String version) {
309         MusicUtil.version = version;
310     }
311
312     /**
313      * Return the version property file value - version
314      * 
315      * @return
316      */
317     public static String getVersion() {
318         return version;
319     }
320
321     /**
322      * Get MyZkHost - Zookeeper Hostname - Default = localhost property file
323      * value - zookeeper.host
324      * 
325      * @return
326      */
327     public static String getMyZkHost() {
328         return myZkHost;
329     }
330
331     /**
332      * Set MyZkHost - Zookeeper Hostname
333      * 
334      * @param myZkHost
335      */
336     public static void setMyZkHost(String myZkHost) {
337         MusicUtil.myZkHost = myZkHost;
338     }
339
340     /**
341      * Get MyCassHost - Cassandra Hostname - Default = localhost property file
342      * value - cassandra.host
343      * 
344      * @return
345      */
346     public static String getMyCassaHost() {
347         return myCassaHost;
348     }
349
350     /**
351      * Set MyCassHost - Cassandra Hostname
352      * 
353      * @param myCassaHost
354      */
355     public static void setMyCassaHost(String myCassaHost) {
356         MusicUtil.myCassaHost = myCassaHost;
357     }
358
359     /**
360      * Get DefaultMusicIp - Default = localhost property file value - music.ip
361      * 
362      * @return
363      */
364     public static String getDefaultMusicIp() {
365         return defaultMusicIp;
366     }
367
368     /**
369      * Set DefaultMusicIp
370      * 
371      * @param defaultMusicIp
372      */
373     public static void setDefaultMusicIp(String defaultMusicIp) {
374         MusicUtil.defaultMusicIp = defaultMusicIp;
375     }
376
377     /**
378      * 
379      * @return
380      */
381     public static String getTestType() {
382         String testType = "";
383         try {
384             Scanner fileScanner = new Scanner(new File(""));
385             testType = fileScanner.next();// ignore the my id line
386             @SuppressWarnings("unused")
387                         String batchSize = fileScanner.next();// ignore the my public ip
388                                                     // line
389             fileScanner.close();
390         } catch (FileNotFoundException e) {
391             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
392         }
393         return testType;
394
395     }
396
397     /**
398      * 
399      * @param time
400      */
401     public static void sleep(long time) {
402         try {
403             Thread.sleep(time);
404         } catch (InterruptedException e) {
405             logger.error(EELFLoggerDelegate.errorLogger, e.getMessage());
406             Thread.currentThread().interrupt();
407         }
408     }
409
410     /**
411      * Utility function to check if the query object is valid.
412      * 
413      * @param withparams
414      * @param queryObject
415      * @return
416      */
417     public static boolean isValidQueryObject(boolean withparams, PreparedQueryObject queryObject) {
418         if (withparams) {
419             int noOfValues = queryObject.getValues().size();
420             int noOfParams = 0;
421             char[] temp = queryObject.getQuery().toCharArray();
422             for (int i = 0; i < temp.length; i++) {
423                 if (temp[i] == '?')
424                     noOfParams++;
425             }
426             return (noOfValues == noOfParams);
427         } else {
428             return !queryObject.getQuery().isEmpty();
429         }
430
431     }
432
433     public static void setCassName(String cassName) {
434         MusicUtil.cassName = cassName;
435     }
436
437     public static void setCassPwd(String cassPwd) {
438         MusicUtil.cassPwd = cassPwd;
439     }
440
441     @SuppressWarnings("unchecked")
442         public static String convertToCQLDataType(DataType type, Object valueObj) throws Exception {
443
444         String value = "";
445         switch (type.getName()) {
446         case UUID:
447             value = valueObj + "";
448             break;
449         case TEXT:
450         case VARCHAR:
451             String valueString = valueObj + "";
452             valueString = valueString.replace("'", "''");
453             value = "'" + valueString + "'";
454             break;
455         case MAP: {
456             Map<String, Object> otMap = (Map<String, Object>) valueObj;
457             value = "{" + jsonMaptoSqlString(otMap, ",") + "}";
458             break;
459         }
460         default:
461             value = valueObj + "";
462             break;
463         }
464         return value;
465     }
466
467     /**
468      * 
469      * @param colType
470      * @param valueObj
471      * @return
472      * @throws MusicTypeConversionException 
473      * @throws Exception
474      */
475     @SuppressWarnings("unchecked")
476         public static Object convertToActualDataType(DataType colType, Object valueObj) throws Exception {
477         String valueObjString = valueObj + "";
478         switch (colType.getName()) {
479             case UUID:
480                 return UUID.fromString(valueObjString);
481             case VARINT:
482                 return BigInteger.valueOf(Long.parseLong(valueObjString));
483             case BIGINT:
484                 return Long.parseLong(valueObjString);
485             case INT:
486                 return Integer.parseInt(valueObjString);
487             case FLOAT:
488                 return Float.parseFloat(valueObjString);
489             case DOUBLE:
490                 return Double.parseDouble(valueObjString);
491             case BOOLEAN:
492                 return Boolean.parseBoolean(valueObjString);
493             case MAP:
494                 return (Map<String, Object>) valueObj;
495             case BLOB:
496                 
497             default:
498                 return valueObjString;
499         }
500     }
501
502     public static ByteBuffer convertToActualDataType(DataType colType, byte[] valueObj) {
503          ByteBuffer buffer = ByteBuffer.wrap(valueObj);
504          return buffer;
505     }
506  
507     /**
508      *
509      * Utility function to parse json map into sql like string
510      * 
511      * @param jMap
512      * @param lineDelimiter
513      * @return
514      */
515
516     public static String jsonMaptoSqlString(Map<String, Object> jMap, String lineDelimiter) throws Exception{
517         StringBuilder sqlString = new StringBuilder();
518         int counter = 0;
519         for (Map.Entry<String, Object> entry : jMap.entrySet()) {
520             Object ot = entry.getValue();
521             String value = ot + "";
522             if (ot instanceof String) {
523                 value = "'" + value.replace("'", "''") + "'";
524             }
525             sqlString.append("'" + entry.getKey() + "':" + value);
526             if (counter != jMap.size() - 1)
527                 sqlString.append(lineDelimiter);
528             counter = counter + 1;
529         }
530         return sqlString.toString();
531     }
532
533     @SuppressWarnings("unused")
534     public static String buildVersion(String major, String minor, String patch) {
535         if (minor != null) {
536             major += "." + minor;
537             if (patch != null) {
538                 major += "." + patch;
539             }
540         }
541         return major;
542     }
543     
544     /**
545      * Currently this will build a header with X-latestVersion, X-minorVersion and X-pathcVersion
546      * X-latestVerstion will be equal to the latest full version.
547      * X-minorVersion - will be equal to the latest minor version.
548      * X-pathVersion - will be equal to the latest patch version.
549      * Future plans will change this. 
550      * @param response
551      * @param major
552      * @param minor
553      * @param patch
554      * @return
555      */
556     public static ResponseBuilder buildVersionResponse(String major, String minor, String patch) {
557         ResponseBuilder response = Response.noContent();
558         String versionIn = buildVersion(major,minor,patch);
559         String version = MusicUtil.getVersion();
560         String[] verArray = version.split("\\.",3);
561         if ( minor != null ) { 
562             response.header(XMINORVERSION,minor);
563         } else {
564             response.header(XMINORVERSION,verArray[1]);
565         } 
566         if ( patch != null ) {
567             response.header(XPATCHVERSION,patch);
568         } else {
569             response.header(XPATCHVERSION,verArray[2]);
570         } 
571         response.header(XLATESTVERSION,version);
572         logger.info(EELFLoggerDelegate.applicationLogger,"Version In:" + versionIn);
573         return response;
574     }
575     
576     
577     public static Map<String,String> extractBasicAuthentication(String authorization){
578                 
579         Map<String,String> authValues = new HashMap<>();
580         authorization = authorization.replaceFirst("Basic", "");
581         String decoded = Base64.base64Decode(authorization);
582         StringTokenizer token = new StringTokenizer(decoded, ":");
583         authValues.put(MusicUtil.USERID, token.nextToken());
584         authValues.put(MusicUtil.PASSWORD,token.nextToken());
585         return authValues;
586         
587     }
588     
589     public static void loadProperties() throws Exception {
590                 Properties prop = new Properties();
591             InputStream input = null;
592             try {
593                 // load the properties file
594                 input = MusicUtil.class.getClassLoader().getResourceAsStream("music.properties");
595                 prop.load(input);
596             } catch (Exception ex) {
597                 logger.error(EELFLoggerDelegate.errorLogger, "Unable to find properties file.");
598                 throw new Exception();
599             } finally {
600                 if (input != null) {
601                     try {
602                         input.close();
603                     } catch (IOException e) {
604                         logger.error(EELFLoggerDelegate.applicationLogger,"Load properties failed "+e.getMessage(),e);
605                     }
606                 }
607             }
608             // get the property value and return it
609                 MusicUtil.setMyCassaHost(prop.getProperty("cassandra.host"));
610                 String zkHosts = prop.getProperty("zookeeper.host");
611                 MusicUtil.setMyZkHost(zkHosts);
612                 MusicUtil.setCassName(prop.getProperty("cassandra.user"));
613                 MusicUtil.setCassPwd(prop.getProperty("cassandra.password"));
614                 MusicUtil.setCassandraPort(Integer.parseInt(prop.getProperty("cassandra.port")));
615                 MusicUtil.setNotifyTimeOut(Integer.parseInt(prop.getProperty("notify.timeout")));
616                 MusicUtil.setNotifyInterval(Integer.parseInt(prop.getProperty("notify.interval")));
617                 
618         }
619     
620         public static void setNotifyInterval(int notifyinterval) {
621                 MusicUtil.notifyinterval = notifyinterval;
622         }
623         public static void setNotifyTimeOut(int notifytimeout) {
624                 MusicUtil.notifytimeout = notifytimeout;
625         }
626
627         public static int getNotifyInterval() {
628                 return MusicUtil.notifyinterval;
629         }
630         
631         public static int getNotifyTimeout() {
632                 return MusicUtil.notifytimeout;
633                 
634         }
635 }