diff --git a/src/main/java/com/scylladb/jmx/api/APIClient.java b/src/main/java/com/scylladb/jmx/api/APIClient.java index 6d7b49a..24cfcac 100644 --- a/src/main/java/com/scylladb/jmx/api/APIClient.java +++ b/src/main/java/com/scylladb/jmx/api/APIClient.java @@ -14,6 +14,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.function.BiFunction; +import java.util.logging.Logger; import javax.json.Json; import javax.json.JsonArray; @@ -35,13 +37,12 @@ import javax.ws.rs.core.Response; import org.glassfish.jersey.client.ClientConfig; -import com.scylladb.jmx.utils.EstimatedHistogram; import com.scylladb.jmx.utils.SnapshotDetailsTabularData; -import com.yammer.metrics.core.HistogramValues; public class APIClient { - Map cache = new HashMap(); - String getCacheKey(String key, MultivaluedMap param, long duration) { + private Map cache = new HashMap(); + + private String getCacheKey(String key, MultivaluedMap param, long duration) { if (duration <= 0) { return null; } @@ -56,43 +57,40 @@ public class APIClient { return key; } - String getStringFromCache(String key, long duration) { + private String getStringFromCache(String key, long duration) { if (key == null) { return null; } CacheEntry value = cache.get(key); - return (value!= null && value.valid(duration))? value.stringValue() : null; + return (value != null && value.valid(duration)) ? value.stringValue() : null; } - JsonObject getJsonObjectFromCache(String key, long duration) { + private JsonObject getJsonObjectFromCache(String key, long duration) { if (key == null) { return null; } CacheEntry value = cache.get(key); - return (value!= null && value.valid(duration))? value.jsonObject() : null; + return (value != null && value.valid(duration)) ? value.jsonObject() : null; } - EstimatedHistogram getEstimatedHistogramFromCache(String key, long duration) { - if (key == null) { - return null; - } - CacheEntry value = cache.get(key); - return (value!= null && value.valid(duration))? value.getEstimatedHistogram() : null; + private JsonReaderFactory factory = Json.createReaderFactory(null); + private static final Logger logger = Logger.getLogger(APIClient.class.getName()); + + private final APIConfig config; + + public APIClient(APIConfig config) { + this.config = config; } - JsonReaderFactory factory = Json.createReaderFactory(null); - private static final java.util.logging.Logger logger = java.util.logging.Logger - .getLogger(APIClient.class.getName()); - - public static String getBaseUrl() { - return APIConfig.getBaseUrl(); + private String getBaseUrl() { + return config.getBaseUrl(); } public Invocation.Builder get(String path, MultivaluedMap queryParams) { - Client client = ClientBuilder.newClient( new ClientConfig()); + Client client = ClientBuilder.newClient(new ClientConfig()); WebTarget webTarget = client.target(getBaseUrl()).path(path); if (queryParams != null) { - for (Entry> qp : queryParams.entrySet()) { + for (Entry> qp : queryParams.entrySet()) { for (String e : qp.getValue()) { webTarget = webTarget.queryParam(qp.getKey(), e); } @@ -112,8 +110,9 @@ public class APIClient { public Response post(String path, MultivaluedMap queryParams, Object object, String type) { try { Response response = get(path, queryParams).post(Entity.entity(object, type)); - if (response.getStatus() != Response.Status.OK.getStatusCode() ) { - throw getException("Scylla API server HTTP POST to URL '" + path + "' failed", response.readEntity(String.class)); + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + throw getException("Scylla API server HTTP POST to URL '" + path + "' failed", + response.readEntity(String.class)); } return response; } catch (ProcessingException e) { @@ -124,7 +123,7 @@ public class APIClient { public Response post(String path, MultivaluedMap queryParams, Object object) { return post(path, queryParams, object, MediaType.TEXT_PLAIN); } - + public void post(String path) { post(path, null); } @@ -159,8 +158,7 @@ public class APIClient { delete(path, null); } - public String getRawValue(String string, - MultivaluedMap queryParams, long duration) { + public String getRawValue(String string, MultivaluedMap queryParams, long duration) { try { if (string.equals("")) { return ""; @@ -176,7 +174,8 @@ public class APIClient { // TBD // We are currently not caching errors, // it should be reconsider. - throw getException("Scylla API server HTTP GET to URL '" + string + "' failed", response.readEntity(String.class)); + throw getException("Scylla API server HTTP GET to URL '" + string + "' failed", + response.readEntity(String.class)); } res = response.readEntity(String.class); if (duration > 0) { @@ -188,8 +187,7 @@ public class APIClient { } } - public String getRawValue(String string, - MultivaluedMap queryParams) { + public String getRawValue(String string, MultivaluedMap queryParams) { return getRawValue(string, queryParams, 0); } @@ -202,23 +200,19 @@ public class APIClient { } public String getStringValue(String string, MultivaluedMap queryParams) { - return getRawValue(string, - queryParams).replaceAll("^\"|\"$", ""); + return getRawValue(string, queryParams).replaceAll("^\"|\"$", ""); } public String getStringValue(String string, MultivaluedMap queryParams, long duration) { - return getRawValue(string, - queryParams, duration).replaceAll("^\"|\"$", ""); + return getRawValue(string, queryParams, duration).replaceAll("^\"|\"$", ""); } public String getStringValue(String string) { return getStringValue(string, null); } - public JsonReader getReader(String string, - MultivaluedMap queryParams) { - return factory.createReader(new StringReader(getRawValue(string, - queryParams))); + public JsonReader getReader(String string, MultivaluedMap queryParams) { + return factory.createReader(new StringReader(getRawValue(string, queryParams))); } public JsonReader getReader(String string) { @@ -230,8 +224,7 @@ public class APIClient { return val.toArray(new String[val.size()]); } - public int getIntValue(String string, - MultivaluedMap queryParams) { + public int getIntValue(String string, MultivaluedMap queryParams) { return Integer.parseInt(getRawValue(string, queryParams)); } @@ -239,6 +232,19 @@ public class APIClient { return getIntValue(string, null); } + public static BiFunction getReader(Class type) { + if (type == String.class) { + return (c, s) -> type.cast(c.getRawValue(s)); + } else if (type == Integer.class) { + return (c, s) -> type.cast(c.getIntValue(s)); + } else if (type == Double.class) { + return (c, s) -> type.cast(c.getDoubleValue(s)); + } else if (type == Long.class) { + return (c, s) -> type.cast(c.getLongValue(s)); + } + throw new IllegalArgumentException(type.getName()); + } + public boolean getBooleanValue(String string) { return Boolean.parseBoolean(getRawValue(string)); } @@ -247,8 +253,7 @@ public class APIClient { return Double.parseDouble(getRawValue(string)); } - public List getListStrValue(String string, - MultivaluedMap queryParams) { + public List getListStrValue(String string, MultivaluedMap queryParams) { JsonReader reader = getReader(string, queryParams); JsonArray arr = reader.readArray(); List res = new ArrayList(arr.size()); @@ -303,8 +308,7 @@ public class APIClient { return join(arr, ","); } - public static String mapToString(Map mp, String pairJoin, - String joiner) { + public static String mapToString(Map mp, String pairJoin, String joiner) { String res = ""; if (mp != null) { for (String name : mp.keySet()) { @@ -321,19 +325,15 @@ public class APIClient { return mapToString(mp, "=", ","); } - public static boolean set_query_param( - MultivaluedMap queryParams, String key, String value) { - if (queryParams != null && key != null && value != null - && !value.equals("")) { + public static boolean set_query_param(MultivaluedMap queryParams, String key, String value) { + if (queryParams != null && key != null && value != null && !value.equals("")) { queryParams.add(key, value); return true; } return false; } - public static boolean set_bool_query_param( - MultivaluedMap queryParams, String key, - boolean value) { + public static boolean set_bool_query_param(MultivaluedMap queryParams, String key, boolean value) { if (queryParams != null && key != null && value) { queryParams.add(key, "true"); return true; @@ -352,8 +352,7 @@ public class APIClient { for (int i = 0; i < arr.size(); i++) { JsonObject obj = arr.getJsonObject(i); if (obj.containsKey("key") && obj.containsKey("value")) { - map.put(obj.getString("key"), - listStrFromJArr(obj.getJsonArray("value"))); + map.put(obj.getString("key"), listStrFromJArr(obj.getJsonArray("value"))); } } reader.close(); @@ -375,8 +374,7 @@ public class APIClient { for (int i = 0; i < arr.size(); i++) { JsonObject obj = arr.getJsonObject(i); if (obj.containsKey("key") && obj.containsKey("value")) { - map.put(listStrFromJArr(obj.getJsonArray("key")), - listStrFromJArr(obj.getJsonArray("value"))); + map.put(listStrFromJArr(obj.getJsonArray("key")), listStrFromJArr(obj.getJsonArray("value"))); } } reader.close(); @@ -387,8 +385,7 @@ public class APIClient { return getMapListStrValue(string, null); } - public Set getSetStringValue(String string, - MultivaluedMap queryParams) { + public Set getSetStringValue(String string, MultivaluedMap queryParams) { JsonReader reader = getReader(string, queryParams); JsonArray arr = reader.readArray(); Set res = new HashSet(); @@ -403,8 +400,7 @@ public class APIClient { return getSetStringValue(string, null); } - public Map getMapStrValue(String string, - MultivaluedMap queryParams) { + public Map getMapStrValue(String string, MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -425,8 +421,7 @@ public class APIClient { return getMapStrValue(string, null); } - public Map getReverseMapStrValue(String string, - MultivaluedMap queryParams) { + public Map getReverseMapStrValue(String string, MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -443,12 +438,11 @@ public class APIClient { return map; } - public Map getReverseMapStrValue(String string) { + public Map getReverseMapStrValue(String string) { return getReverseMapStrValue(string, null); } - public List getListInetAddressValue(String string, - MultivaluedMap queryParams) { + public List getListInetAddressValue(String string, MultivaluedMap queryParams) { List vals = getListStrValue(string, queryParams); List res = new ArrayList(); for (String val : vals) { @@ -472,22 +466,20 @@ public class APIClient { } private TabularDataSupport getSnapshotData(String key, JsonArray arr) { - TabularDataSupport data = new TabularDataSupport( - SnapshotDetailsTabularData.TABULAR_TYPE); + TabularDataSupport data = new TabularDataSupport(SnapshotDetailsTabularData.TABULAR_TYPE); for (int i = 0; i < arr.size(); i++) { JsonObject obj = arr.getJsonObject(i); if (obj.containsKey("ks") && obj.containsKey("cf")) { - SnapshotDetailsTabularData.from(key, obj.getString("ks"), - obj.getString("cf"), obj.getInt("total"), + SnapshotDetailsTabularData.from(key, obj.getString("ks"), obj.getString("cf"), obj.getInt("total"), obj.getInt("live"), data); } } return data; } - public Map getMapStringSnapshotTabularDataValue( - String string, MultivaluedMap queryParams) { + public Map getMapStringSnapshotTabularDataValue(String string, + MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -521,8 +513,7 @@ public class APIClient { for (int i = 0; i < arr.size(); i++) { try { obj = arr.getJsonObject(i); - res.put(InetAddress.getByName(obj.getString("key")), - Float.parseFloat(obj.getString("value"))); + res.put(InetAddress.getByName(obj.getString("key")), Float.parseFloat(obj.getString("value"))); } catch (UnknownHostException e) { logger.warning("Bad formatted address " + obj.getString("key")); } @@ -534,8 +525,7 @@ public class APIClient { return getMapInetAddressFloatValue(string, null); } - public Map getMapStringLongValue(String string, - MultivaluedMap queryParams) { + public Map getMapStringLongValue(String string, MultivaluedMap queryParams) { Map res = new HashMap(); JsonReader reader = getReader(string, queryParams); @@ -553,8 +543,7 @@ public class APIClient { return getMapStringLongValue(string, null); } - public long[] getLongArrValue(String string, - MultivaluedMap queryParams) { + public long[] getLongArrValue(String string, MultivaluedMap queryParams) { JsonReader reader = getReader(string, queryParams); JsonArray arr = reader.readArray(); long[] res = new long[arr.size()]; @@ -569,8 +558,7 @@ public class APIClient { return getLongArrValue(string, null); } - public Map getMapStringIntegerValue(String string, - MultivaluedMap queryParams) { + public Map getMapStringIntegerValue(String string, MultivaluedMap queryParams) { Map res = new HashMap(); JsonReader reader = getReader(string, queryParams); @@ -588,8 +576,7 @@ public class APIClient { return getMapStringIntegerValue(string, null); } - public int[] getIntArrValue(String string, - MultivaluedMap queryParams) { + public int[] getIntArrValue(String string, MultivaluedMap queryParams) { JsonReader reader = getReader(string, queryParams); JsonArray arr = reader.readArray(); int[] res = new int[arr.size()]; @@ -604,8 +591,7 @@ public class APIClient { return getIntArrValue(string, null); } - public Map getListMapStringLongValue(String string, - MultivaluedMap queryParams) { + public Map getListMapStringLongValue(String string, MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -638,8 +624,7 @@ public class APIClient { return getListMapStringLongValue(string, null); } - public JsonArray getJsonArray(String string, - MultivaluedMap queryParams) { + public JsonArray getJsonArray(String string, MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -653,8 +638,7 @@ public class APIClient { return getJsonArray(string, null); } - public List> getListMapStrValue(String string, - MultivaluedMap queryParams) { + public List> getListMapStrValue(String string, MultivaluedMap queryParams) { JsonArray arr = getJsonArray(string, queryParams); List> res = new ArrayList>(); for (int i = 0; i < arr.size(); i++) { @@ -672,8 +656,7 @@ public class APIClient { return null; } - public JsonObject getJsonObj(String string, - MultivaluedMap queryParams, long duration) { + public JsonObject getJsonObj(String string, MultivaluedMap queryParams, long duration) { if (string.equals("")) { return null; } @@ -690,61 +673,19 @@ public class APIClient { } return res; } - public JsonObject getJsonObj(String string, - MultivaluedMap queryParams) { + + public JsonObject getJsonObj(String string, MultivaluedMap queryParams) { return getJsonObj(string, queryParams, 0); } - public static HistogramValues json2histogram(JsonObject obj) { - HistogramValues res = new HistogramValues(); - res.count = obj.getJsonNumber("count").longValue(); - res.max = obj.getJsonNumber("max").longValue(); - res.min = obj.getJsonNumber("min").longValue(); - res.sum = obj.getJsonNumber("sum").longValue(); - res.variance = obj.getJsonNumber("variance").doubleValue(); - res.mean = obj.getJsonNumber("mean").doubleValue(); - JsonArray arr = obj.getJsonArray("sample"); - if (arr != null) { - res.sample = new long[arr.size()]; - for (int i = 0; i < arr.size(); i++) { - res.sample[i] = arr.getJsonNumber(i).longValue(); - } - } - return res; - } - - public HistogramValues getHistogramValue(String url, - MultivaluedMap queryParams) { - return json2histogram(getJsonObj(url, queryParams)); - } - - public HistogramValues getHistogramValue(String url) { - return getHistogramValue(url, null); - } - - public EstimatedHistogram getEstimatedHistogram(String string, - MultivaluedMap queryParams, long duration) { - String key = getCacheKey(string, queryParams, duration); - EstimatedHistogram res = getEstimatedHistogramFromCache(key, duration); - if (res != null) { - return res; - } - res = new EstimatedHistogram(getEstimatedHistogramAsLongArrValue(string, queryParams)); - if (duration > 0) { - cache.put(key, new CacheEntry(res)); - } - return res; - - } - public long[] getEstimatedHistogramAsLongArrValue(String string, - MultivaluedMap queryParams) { + public long[] getEstimatedHistogramAsLongArrValue(String string, MultivaluedMap queryParams) { JsonObject obj = getJsonObj(string, queryParams); JsonArray arr = obj.getJsonArray("buckets"); if (arr == null) { return new long[0]; } long res[] = new long[arr.size()]; - for (int i = 0; i< arr.size(); i++) { + for (int i = 0; i < arr.size(); i++) { res[i] = arr.getJsonNumber(i).longValue(); } return res; @@ -754,8 +695,7 @@ public class APIClient { return getEstimatedHistogramAsLongArrValue(string, null); } - public Map getMapStringDouble(String string, - MultivaluedMap queryParams) { + public Map getMapStringDouble(String string, MultivaluedMap queryParams) { if (string.equals("")) { return null; } @@ -783,6 +723,7 @@ public class APIClient { reader.close(); return map; } + public Map getMapStringDouble(String string) { return getMapStringDouble(string, null); } diff --git a/src/main/java/com/scylladb/jmx/api/APIConfig.java b/src/main/java/com/scylladb/jmx/api/APIConfig.java index 522a12d..cd66844 100644 --- a/src/main/java/com/scylladb/jmx/api/APIConfig.java +++ b/src/main/java/com/scylladb/jmx/api/APIConfig.java @@ -30,23 +30,22 @@ import org.yaml.snakeyaml.Yaml; */ public class APIConfig { - static String address = "localhost"; - static String port = "10000"; + private String address = "localhost"; + private String port = "10000"; - public static String getAddress() { + public String getAddress() { return address; } - public static String getPort() { + public String getPort() { return port; } - public static String getBaseUrl() { - return "http://" + address + ":" - + port; + public String getBaseUrl() { + return "http://" + address + ":" + port; } - public static void readFile(String name) { + private void readFile(String name) { System.out.println("Using config file: " + name); InputStream input; try { @@ -61,7 +60,7 @@ public class APIConfig { address = (String) map.get("api_address"); } if (map.containsKey("api_port")) { - port = (String) map.get("api_port").toString(); + port = map.get("api_port").toString(); } } catch (FileNotFoundException e) { System.err.println("fail reading from config file: " + name); @@ -74,7 +73,7 @@ public class APIConfig { return varTmpDir.exists(); } - public static boolean loadIfExists(String path, String name) { + private boolean loadIfExists(String path, String name) { if (path == null) { return false; } @@ -84,24 +83,21 @@ public class APIConfig { readFile(path + name); return true; } + /** - * setConfig load the JMX proxy configuration - * The configuration hierarchy is as follow: - * Command line argument takes precedence over everything - * Then configuration file in the command line (command line - * argument can replace specific values in it. - * Then SCYLLA_CONF/scylla.yaml - * Then SCYLLA_HOME/conf/scylla.yaml - * Then conf/scylla.yaml - * Then the default values - * With file configuration, to make it clearer what is been used, only - * one file will be chosen with the highest precedence + * setConfig load the JMX proxy configuration The configuration hierarchy is + * as follow: Command line argument takes precedence over everything Then + * configuration file in the command line (command line argument can replace + * specific values in it. Then SCYLLA_CONF/scylla.yaml Then + * SCYLLA_HOME/conf/scylla.yaml Then conf/scylla.yaml Then the default + * values With file configuration, to make it clearer what is been used, + * only one file will be chosen with the highest precedence */ - public static void setConfig() { - if (!System.getProperty("apiconfig","").equals("")) { + public APIConfig() { + if (!System.getProperty("apiconfig", "").equals("")) { readFile(System.getProperty("apiconfig")); - } else if (!loadIfExists(System.getenv("SCYLLA_CONF"), "/scylla.yaml") && - !loadIfExists(System.getenv("SCYLLA_HOME"), "/conf/scylla.yaml")) { + } else if (!loadIfExists(System.getenv("SCYLLA_CONF"), "/scylla.yaml") + && !loadIfExists(System.getenv("SCYLLA_HOME"), "/conf/scylla.yaml")) { loadIfExists("", "conf/scylla.yaml"); } diff --git a/src/main/java/com/scylladb/jmx/api/CacheEntry.java b/src/main/java/com/scylladb/jmx/api/CacheEntry.java index c71756f..2451180 100644 --- a/src/main/java/com/scylladb/jmx/api/CacheEntry.java +++ b/src/main/java/com/scylladb/jmx/api/CacheEntry.java @@ -23,13 +23,11 @@ package com.scylladb.jmx.api; import javax.json.JsonObject; -import com.scylladb.jmx.utils.EstimatedHistogram; +class CacheEntry { + private long time; + private Object value; -public class CacheEntry { - long time; - Object value; - - CacheEntry(Object res) { + public CacheEntry(Object res) { time = System.currentTimeMillis(); this.value = res; } @@ -42,10 +40,6 @@ public class CacheEntry { return (String) value; } - public EstimatedHistogram getEstimatedHistogram() { - return (EstimatedHistogram)value; - } - public JsonObject jsonObject() { return (JsonObject) value; }