com.skysql.manager.api.Monitors.java Source code

Java tutorial

Introduction

Here is the source code for com.skysql.manager.api.Monitors.java

Source

/*
 * This file is distributed as part of the MariaDB Manager.  It is free
 * software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * version 2.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Copyright 2012-2014 SkySQL Corporation Ab
 */

package com.skysql.manager.api;

import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.skysql.manager.MonitorRecord;
import com.skysql.manager.api.Monitors.PermittedMonitorType;
import com.skysql.manager.ui.ErrorDialog;

/**
 * The Class Monitors.
 */
public class Monitors {

    /**
     * The Enum MonitorNames only includes some of the historic monitor names and is used in info panel and popups.
     */
    public enum MonitorNames {
        connections, traffic, availability, nodestate, capacity, hoststate;
    }

    /**
     * The Enum PermittedMonitorType determines which types of monitors are going to be visible to the user.
     */
    public enum PermittedMonitorType {
        SQL, GLOBAL, JS;
    }

    /**
     * The Enum EditableMonitorType determines which types of monitors are going to be editable by the user.
     */
    public enum EditableMonitorType {
        SQL;
    }

    private static LinkedHashMap<String, LinkedHashMap<String, MonitorRecord>> monitorsMap;
    private static LinkedHashMap<String, MonitorRecord> currentList;

    /**
     * Gets the monitors list.
     *
     * @return the monitors list
     */
    public static LinkedHashMap<String, MonitorRecord> getMonitorsList() {
        return currentList;
    }

    /**
     * Gets the monitors list.
     *
     * @param systemType the system type
     * @return the monitors list
     */
    public static LinkedHashMap<String, MonitorRecord> getMonitorsList(String systemType) {
        if (monitorsMap == null) {
            reloadMonitors();
        }
        currentList = monitorsMap.get(systemType);
        return currentList;
    }

    /**
     * Gets the monitor.
     *
     * @param ID the id
     * @return the monitor
     */
    public static MonitorRecord getMonitor(String ID) {
        return (currentList != null ? currentList.get(ID) : null);
    }

    /**
     * Sets the monitors map.
     *
     * @param monitorsMap the monitors map
     */
    protected void setMonitorsMap(LinkedHashMap<String, LinkedHashMap<String, MonitorRecord>> monitorsMap) {
        Monitors.monitorsMap = monitorsMap;
    }

    /**
     * Instantiates a new monitors.
     */
    public Monitors() {

    }

    /**
     * Reload list of monitors from API.
     */
    public synchronized static void reloadMonitors() {

        APIrestful api = new APIrestful();
        if (api.get("monitorclass")) {
            try {
                Monitors monitors = APIrestful.getGson().fromJson(api.getResult(), Monitors.class);
                Monitors.monitorsMap = monitors.monitorsMap;
            } catch (NullPointerException e) {
                new ErrorDialog(e, "API did not return expected result for:" + api.errorString());
                throw new RuntimeException("API response");
            } catch (JsonParseException e) {
                new ErrorDialog(e, "JSON parse error in API results for:" + api.errorString());
                throw new RuntimeException("API response");
            }
        }

    }

    /**
     * Writes the monitor to the API.
     *
     * @param monitor the monitor
     * @return true, if successful
     */
    public synchronized static boolean setMonitor(MonitorRecord monitor) {

        APIrestful api = new APIrestful();

        try {
            boolean success;

            JSONObject jsonParam = new JSONObject();
            jsonParam.put("name", monitor.getName());
            jsonParam.put("description", monitor.getDescription());
            jsonParam.put("sql", monitor.getSql());
            jsonParam.put("unit", monitor.getUnit());
            jsonParam.put("delta", monitor.isDelta() ? "1" : "0");
            jsonParam.put("systemaverage", monitor.isAverage() ? "1" : "0");
            jsonParam.put("monitortype", "SQL");

            // type needs to indicate int/float/string etc. instead of LineChart/AreaChart
            jsonParam.put("type", monitor.getChartType());
            int interval = monitor.getInterval();
            jsonParam.put("interval", String.valueOf(interval));

            if (monitor.getID() == null) {
                monitor.setID(createUniqueID(monitor.getName()));
            }

            success = api.put("monitorclass/" + monitor.getSystemType() + "/key/" + monitor.getID(),
                    jsonParam.toString());

        } catch (JSONException e) {
            new ErrorDialog(e, "Error encoding API request");
            throw new RuntimeException("Error encoding API request");
        }

        WriteResponse writeResponse = APIrestful.getGson().fromJson(api.getResult(), WriteResponse.class);
        if (writeResponse != null
                && (!writeResponse.getInsertKey().isEmpty() || writeResponse.getUpdateCount() > 0)) {
            currentList.put(monitor.getID(), monitor);
            return true;
        } else {
            return false;
        }

    }

    /**
     * Checks if the proposed monitor key is unique.
     *
     * @param proposedName the proposed name
     * @return true, if is name unique
     */
    public static boolean isNameUnique(String proposedName) {
        for (Map.Entry<String, MonitorRecord> entry : currentList.entrySet()) {
            MonitorRecord monitor = entry.getValue();
            if (monitor.getName().equals(proposedName)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Creates the unique monitor ID (API: monitor key).
     *
     * @param name the name
     * @return the string
     */
    private synchronized static String createUniqueID(String name) {
        String ID = name.replaceAll("[^a-zA-Z0-9.-]", "");
        int i = 0;
        String uniqueID = ID;
        while (Monitors.getMonitor(uniqueID) != null) {
            uniqueID = ID + i++;
        }
        return uniqueID;
    }

    /**
     * Deletes monitor from API.
     *
     * @param monitor the monitor
     * @return true, if successful
     */
    public synchronized static boolean deleteMonitor(MonitorRecord monitor) {

        APIrestful api = new APIrestful();
        if (api.delete("monitorclass/" + monitor.getSystemType() + "/key/" + monitor.getID())) {
            WriteResponse writeResponse = APIrestful.getGson().fromJson(api.getResult(), WriteResponse.class);
            if (writeResponse != null && writeResponse.getDeleteCount() > 0) {
                currentList.remove(monitor.getID());
                return true;
            }
        }
        return false;
    }

}

/***
// {"monitorclasses":[
{"systemtype":"aws","monitor":"connections","name":"Connections","sql":"select variable_value from global_status where variable_name = \"THREADS_CONNECTED\";","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"1"},
{"systemtype":"aws","monitor":"traffic","name":"Network Traffic","sql":"select round(sum(variable_value) \/ 1024) from global_status where variable_name in (\"BYTES_RECEIVED\", \"BYTES_SENT\");","description":"","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":"kB\/min","monitorid":"2"},
{"systemtype":"aws","monitor":"availability","name":"Availability","sql":"select 100;","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"3"},
{"systemtype":"aws","monitor":"nodestate","name":"Node State","sql":"crm status bynode","description":"","charttype":null,"delta":"0","monitortype":"CRM","systemaverage":"0","interval":"30","unit":null,"monitorid":"4"},
{"systemtype":"aws","monitor":"capacity","name":"Capacity","sql":"select round(((select variable_value from global_status where variable_name = \"THREADS_CONNECTED\") * 100) \/ variable_value) from global_variables where variable_name = \"MAX_CONNECTIONS\";","description":"","charttype":null,"delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"5"},
{"systemtype":"aws","monitor":"hoststate","name":"Host State","sql":"","description":"","charttype":null,"delta":"0","monitortype":"PING","systemaverage":"0","interval":"30","unit":null,"monitorid":"6"},
{"systemtype":"galera","monitor":"connections","name":"Connections","sql":"select variable_value from global_status where variable_name = \"THREADS_CONNECTED\";","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"7"},
{"systemtype":"galera","monitor":"traffic","name":"Network Traffic","sql":"select round(sum(variable_value) \/ 1024) from global_status where variable_name in (\"BYTES_RECEIVED\", \"BYTES_SENT\");","description":"","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":"kB\/min","monitorid":"8"},
{"systemtype":"galera","monitor":"availability","name":"Availability","sql":"select 100;","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"9"},
{"systemtype":"galera","monitor":"capacity","name":"Capacity","sql":"select round(((select variable_value from global_status where variable_name = \"THREADS_CONNECTED\") * 100) \/ variable_value) from global_variables where variable_name = \"MAX_CONNECTIONS\";","description":"","charttype":null,"delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"10"},
{"systemtype":"galera","monitor":"hoststate","name":"Host State","sql":"","description":"","charttype":null,"delta":"0","monitortype":"PING","systemaverage":"0","interval":"30","unit":null,"monitorid":"11"},
{"systemtype":"galera","monitor":"nodestate","name":"NodeState","sql":"select 100 + variable_value from global_status where variable_name = \"WSREP_LOCAL_STATE\" union select 107 limit 1;","description":"","charttype":null,"delta":"0","monitortype":"SQL_NODE_STATE","systemaverage":"1","interval":"30","unit":null,"monitorid":"12"},
{"systemtype":"galera","monitor":"clustersize","name":"Cluster Size","sql":"select variable_value from global_status where variable_name = \"WSREP_CLUSTER_SIZE\";","description":"Number of nodes in the cluster","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"13"},
{"systemtype":"galera","monitor":"reppaused","name":"Replication Paused","sql":"select variable_value * 100 from global_status where variable_name = \"WSREP_FLOW_CONTROL_PAUSED\";","description":"Percentage of time for which replication was paused","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"14"},
{"systemtype":"galera","monitor":"parallelism","name":"Parallelism","sql":"select variable_value from global_status where variable_name = \"WSREP_CERT_DEPS_DISTANCE\";","description":"Average No. of parallel transactions","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"15"},
{"systemtype":"galera","monitor":"recvqueue","name":"Avg Receive Queue","sql":"select variable_value from global_status where variable_name = \"WSREP_LOCAL_RECV_QUEUE_AVG\";","description":"Average receive queue length","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"16"},
{"systemtype":"galera","monitor":"flowcontrol","name":"Flow Controlled","sql":"select variable_value from global_status where variable_name = \"WSREP_FLOW_CONTROL_SENT\";","description":"Flow control messages sent","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"17"},
{"systemtype":"galera","monitor":"sendqueue","name":"Avg Send Queue","sql":"select variable_value from global_status where variable_name = \"WSREP_LOCAL_SEND_QUEUE_AVG\";","description":"Average length of send queue","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"18"}],
    
// {"monitorclass":[
{"systemtype":"aws","monitor":"connections","name":"Connections","sql":"select variable_value from global_status where variable_name = \"THREADS_CONNECTED\";","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"1"},
{"systemtype":"aws","monitor":"traffic","name":"Network Traffic","sql":"select round(sum(variable_value) \/ 1024) from global_status where variable_name in (\"BYTES_RECEIVED\", \"BYTES_SENT\");","description":"","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":"kB\/min","monitorid":"2"},
{"systemtype":"aws","monitor":"availability","name":"Availability","sql":"select 100;","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"3"},
{"systemtype":"aws","monitor":"nodestate","name":"Node State","sql":"crm status bynode","description":"","charttype":null,"delta":"0","monitortype":"CRM","systemaverage":"0","interval":"30","unit":null,"monitorid":"4"},
{"systemtype":"aws","monitor":"capacity","name":"Capacity","sql":"select round(((select variable_value from global_status where variable_name = \"THREADS_CONNECTED\") * 100) \/ variable_value) from global_variables where variable_name = \"MAX_CONNECTIONS\";","description":"","charttype":null,"delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"5"},
{"systemtype":"aws","monitor":"hoststate","name":"Host State","sql":"","description":"","charttype":null,"delta":"0","monitortype":"PING","systemaverage":"0","interval":"30","unit":null,"monitorid":"6"}]
***/

/***
{"monitorclasses":
{"aws":[
   {"systemtype":"aws","monitor":"connections","name":"Connections","sql":"select variable_value from global_status where variable_name = \"THREADS_CONNECTED\";","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"1"},
   {"systemtype":"aws","monitor":"traffic","name":"Network Traffic","sql":"select round(sum(variable_value) \/ 1024) from global_status where variable_name in (\"BYTES_RECEIVED\", \"BYTES_SENT\");","description":"","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":"kB\/min","monitorid":"2"},
   {"systemtype":"aws","monitor":"availability","name":"Availability","sql":"select 100;","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"3"},{"systemtype":"aws","monitor":"nodestate","name":"Node State","sql":"crm status bynode","description":"","charttype":null,"delta":"0","monitortype":"CRM","systemaverage":"0","interval":"30","unit":null,"monitorid":"4"},
   {"systemtype":"aws","monitor":"capacity","name":"Capacity","sql":"select round(((select variable_value from global_status where variable_name = \"THREADS_CONNECTED\") * 100) \/ variable_value) from global_variables where variable_name = \"MAX_CONNECTIONS\";","description":"","charttype":null,"delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"5"},
   {"systemtype":"aws","monitor":"hoststate","name":"Host State","sql":"","description":"","charttype":null,"delta":"0","monitortype":"PING","systemaverage":"0","interval":"30","unit":null,"monitorid":"6"}],
"galera":[
   {"systemtype":"galera","monitor":"connections","name":"Connections","sql":"select variable_value from global_status where variable_name = \"THREADS_CONNECTED\";","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"7"},
   {"systemtype":"galera","monitor":"traffic","name":"Network Traffic","sql":"select round(sum(variable_value) \/ 1024) from global_status where variable_name in (\"BYTES_RECEIVED\", \"BYTES_SENT\");","description":"","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":"kB\/min","monitorid":"8"},
   {"systemtype":"galera","monitor":"availability","name":"Availability","sql":"select 100;","description":"","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"9"},{"systemtype":"galera","monitor":"capacity","name":"Capacity","sql":"select round(((select variable_value from global_status where variable_name = \"THREADS_CONNECTED\") * 100) \/ variable_value) from global_variables where variable_name = \"MAX_CONNECTIONS\";","description":"","charttype":null,"delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"10"},
   {"systemtype":"galera","monitor":"hoststate","name":"Host State","sql":"","description":"","charttype":null,"delta":"0","monitortype":"PING","systemaverage":"0","interval":"30","unit":null,"monitorid":"11"},
   {"systemtype":"galera","monitor":"nodestate","name":"NodeState","sql":"select 100 + variable_value from global_status where variable_name = \"WSREP_LOCAL_STATE\" union select 107 limit 1;","description":"","charttype":null,"delta":"0","monitortype":"SQL_NODE_STATE","systemaverage":"1","interval":"30","unit":null,"monitorid":"12"},
   {"systemtype":"galera","monitor":"clustersize","name":"Cluster Size","sql":"select variable_value from global_status where variable_name = \"WSREP_CLUSTER_SIZE\";","description":"Number of nodes in the cluster","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"13"},
   {"systemtype":"galera","monitor":"reppaused","name":"Replication Paused","sql":"select variable_value * 100 from global_status where variable_name = \"WSREP_FLOW_CONTROL_PAUSED\";","description":"Percentage of time for which replication was paused","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":"%","monitorid":"14"},
   {"systemtype":"galera","monitor":"parallelism","name":"Parallelism","sql":"select variable_value from global_status where variable_name = \"WSREP_CERT_DEPS_DISTANCE\";","description":"Average No. of parallel transactions","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"15"},
   {"systemtype":"galera","monitor":"recvqueue","name":"Avg Receive Queue","sql":"select variable_value from global_status where variable_name = \"WSREP_LOCAL_RECV_QUEUE_AVG\";","description":"Average receive queue length","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"16"},
   {"systemtype":"galera","monitor":"flowcontrol","name":"Flow Controlled","sql":"select variable_value from global_status where variable_name = \"WSREP_FLOW_CONTROL_SENT\";","description":"Flow control messages sent","charttype":"LineChart","delta":"1","monitortype":"SQL","systemaverage":"0","interval":"30","unit":null,"monitorid":"17"},
   {"systemtype":"galera","monitor":"sendqueue","name":"Avg Send Queue","sql":"select variable_value from global_status where variable_name = \"WSREP_LOCAL_SEND_QUEUE_AVG\";","description":"Average length of send queue","charttype":"LineChart","delta":"0","monitortype":"SQL","systemaverage":"1","interval":"30","unit":null,"monitorid":"18"}]}
***/

class MonitorsDeserializer implements JsonDeserializer<Monitors> {
    public Monitors deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException, NullPointerException {
        Monitors monitors = new Monitors();

        JsonArray array = null;
        JsonObject object = null;

        if (json.getAsJsonObject().has("monitorclasses")) {
            JsonElement monitorsElement = json.getAsJsonObject().get("monitorclasses");
            if (monitorsElement.isJsonArray()) {
                array = monitorsElement.getAsJsonArray();
            } else {
                object = monitorsElement.getAsJsonObject();
            }
        } else if (json.getAsJsonObject().has("monitorclass")) {
            array = json.getAsJsonObject().get("monitorclass").getAsJsonArray();
        } else {
            monitors.setMonitorsMap(null);
            return monitors;
        }

        LinkedHashMap<String, LinkedHashMap<String, MonitorRecord>> monitorsMap = new LinkedHashMap<String, LinkedHashMap<String, MonitorRecord>>();
        monitors.setMonitorsMap(monitorsMap);
        for (String type : SystemTypes.getList().keySet()) {
            monitorsMap.put(type, new LinkedHashMap<String, MonitorRecord>());
        }

        if (array != null) {
            parseMonitors(array, monitorsMap);
        } else {
            for (String type : SystemTypes.getList().keySet()) {
                array = object.get(type).getAsJsonArray();
                parseMonitors(array, monitorsMap);
            }
        }

        return monitors;
    }

    private void parseMonitors(JsonArray array,
            LinkedHashMap<String, LinkedHashMap<String, MonitorRecord>> monitorsMap) {

        for (int i = 0; i < array.size(); i++) {
            JsonObject jsonObject = array.get(i).getAsJsonObject();
            JsonElement element;
            String systemType = (element = jsonObject.get("systemtype")).isJsonNull() ? null
                    : element.getAsString();
            String id = (element = jsonObject.get("monitor")).isJsonNull() ? null : element.getAsString();
            String name = (element = jsonObject.get("name")).isJsonNull() ? null : element.getAsString();
            String description = (element = jsonObject.get("description")).isJsonNull() ? null
                    : element.getAsString();
            String unit = (element = jsonObject.get("unit")).isJsonNull() ? null : element.getAsString();
            String monitorType = (element = jsonObject.get("monitortype")).isJsonNull() ? null
                    : element.getAsString();
            boolean delta = (element = jsonObject.get("delta")).isJsonNull() ? false : element.getAsBoolean();
            boolean average = (element = jsonObject.get("systemaverage")).isJsonNull() ? false
                    : element.getAsBoolean();
            String chartType = (element = jsonObject.get("charttype")).isJsonNull() ? null : element.getAsString();
            String intervalString = (element = jsonObject.get("interval")).isJsonNull() ? null
                    : element.getAsString();
            int interval = (intervalString != null && !intervalString.isEmpty()) ? Integer.valueOf(intervalString)
                    : 0;
            String sql = (element = jsonObject.get("sql")).isJsonNull() ? null : element.getAsString();
            for (PermittedMonitorType permitted : PermittedMonitorType.values()) {
                if (permitted.name().equals(monitorType)) {
                    MonitorRecord monitorRecord = new MonitorRecord(systemType, id, name, description, unit,
                            monitorType, delta, average, chartType, interval, sql);
                    monitorsMap.get(systemType).put(id, monitorRecord);
                    break;
                }
            }

        }

    }
}