summaryrefslogtreecommitdiff
path: root/java/src/IceGridGUI/LiveDeployment/GraphView.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/IceGridGUI/LiveDeployment/GraphView.java')
-rw-r--r--java/src/IceGridGUI/LiveDeployment/GraphView.java1252
1 files changed, 1252 insertions, 0 deletions
diff --git a/java/src/IceGridGUI/LiveDeployment/GraphView.java b/java/src/IceGridGUI/LiveDeployment/GraphView.java
new file mode 100644
index 00000000000..c8f89c909ad
--- /dev/null
+++ b/java/src/IceGridGUI/LiveDeployment/GraphView.java
@@ -0,0 +1,1252 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2012 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceGridGUI.LiveDeployment;
+
+import java.util.Map;
+import java.util.List;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+import java.util.Date;
+import java.util.TimeZone;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSpinner;
+import javax.swing.JTable;
+import javax.swing.JOptionPane;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.SwingConstants;
+
+import javax.swing.table.DefaultTableModel;
+
+import javafx.application.Platform;
+
+import javafx.embed.swing.JFXPanel;
+
+import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.chart.XYChart;
+
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
+
+import javafx.scene.Scene;
+
+import javafx.util.StringConverter;
+
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.factories.Borders;
+import com.jgoodies.forms.builder.ButtonBarBuilder;
+
+import IceGrid.*;
+import IceGridGUI.*;
+
+public class GraphView extends JFrame
+{
+
+ public enum GraphCategory
+ {
+ DispatchGraphCategory,
+ InvocationsGraphCategory,
+ ConnectionsGraphCategory,
+ ThreadsGraphCategory,
+ BandwidthGraphCategory
+ }
+
+ public enum GraphType
+ {
+ TotalAverageGraphType,
+ CurrentCountGraphType,
+ BandwidhGraphType
+ }
+
+ class TimeFormatter extends StringConverter<java.lang.Number>
+ {
+ TimeFormatter()
+ {
+ _dateFormat.setTimeZone(TimeZone.getDefault());
+ }
+
+ @Override
+ public synchronized String toString(Number timestamp)
+ {
+ Date date = new Date(timestamp.longValue());
+ if(date.getTime() < 1000)
+ {
+ //
+ // When the x axis is first draw we don't have times to display.
+ //
+ return "";
+ }
+ else
+ {
+ return _dateFormat.format(date);
+ }
+ }
+
+ @Override
+ public synchronized Number fromString(String time)
+ {
+ try
+ {
+ long t = _dateFormat.parse(time).getTime();
+ return t;
+ }
+ catch(java.text.ParseException e)
+ {
+ return 0;
+ }
+ }
+
+ public synchronized void setDateFormat(String format)
+ {
+ _dateFormat = new SimpleDateFormat(format);
+ }
+
+ private DateFormat _dateFormat = new SimpleDateFormat(getDateFormat());
+ }
+
+ class TransferHandler extends javax.swing.TransferHandler
+ {
+ @Override
+ public boolean
+ canImport(TransferHandler.TransferSupport support)
+ {
+ boolean supported = false;
+ for(DataFlavor f : support.getDataFlavors())
+ {
+ if(f.getMimeType().equals(NodeMimeType) || f.getMimeType().equals(ServerMimeType) ||
+ f.getMimeType().equals(MetricsViewMimeType))
+ {
+ supported = true;
+ break;
+ }
+ }
+ return supported;
+ }
+
+ @Override
+ public boolean
+ importData(TransferHandler.TransferSupport support)
+ {
+ if(!canImport(support))
+ {
+ return false;
+ }
+
+ Transferable t = support.getTransferable();
+
+ for(DataFlavor flavor : support.getDataFlavors())
+ {
+ try
+ {
+ if(flavor.getMimeType().equals(NodeMimeType))
+ {
+ Node node = (Node)t.getTransferData(flavor);
+ importNode(node);
+ break;
+ }
+ else if(flavor.getMimeType().equals(ServerMimeType))
+ {
+ Server server = (Server)t.getTransferData(flavor);
+ importServer(server);
+ break;
+ }
+ else if(flavor.getMimeType().equals(MetricsViewMimeType))
+ {
+ MetricsView metricsView = (MetricsView)t.getTransferData(flavor);
+ importMetricsView(metricsView);
+ break;
+ }
+ }
+ catch(UnsupportedFlavorException ex)
+ {
+ }
+ catch(java.io.IOException ex)
+ {
+ }
+ }
+
+ return true;
+ }
+ }
+
+ private void importNode(Node node)
+ {
+ List<Server> servers = node.getServers();
+ for(Server s : servers)
+ {
+ importServer(s);
+ }
+ }
+
+ private void importServer(Server server)
+ {
+ List<MetricsView> metrics = server.getMetrics();
+ for(MetricsView m : metrics)
+ {
+ importMetricsView(m);
+ }
+ }
+
+ private void importMetricsView(MetricsView metricsView)
+ {
+ Server server = (Server)metricsView.getParent();
+ Node node = (Node)server.getParent();
+ MetricsViewInfo s = new MetricsViewInfo(node.getId(), server.getId(), metricsView.getId());
+ if(!_metrics.contains(s))
+ {
+ if(_metrics.size() == 0)
+ {
+ startRefreshThread();
+ }
+ _metrics.add(s);
+ addSeries(s, metricsView.data().get(_key));
+ }
+ }
+
+ class MetricsViewTargetInfo
+ {
+ MetricsViewTargetInfo(MetricsViewInfo parent, String id)
+ {
+ this.parent = parent;
+ this.id = id;
+ this.total = 0;
+ this.totalLifetime = 0;
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if(other == null)
+ {
+ return false;
+ }
+ else if(other == this)
+ {
+ return true;
+ }
+ else if(!(other instanceof MetricsViewTargetInfo))
+ {
+ return false;
+ }
+ MetricsViewTargetInfo that = (MetricsViewTargetInfo)other;
+ return this.parent.equals(that.parent) && this.id.equals(that.id);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return IceInternal.HashUtil.hashAdd(parent.hashCode(), id);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(parent.toString());
+ sb.append(" - ");
+ sb.append(id);
+ return sb.toString();
+ }
+
+ public String id;
+ public MetricsViewInfo parent;
+ //
+ // Totals from last delta.
+ //
+ public long total;
+ public long totalLifetime;
+ };
+
+ class BandwidhMetricsInfo extends MetricsViewTargetInfo
+ {
+ BandwidhMetricsInfo(MetricsViewInfo parent, String id, boolean in)
+ {
+ super(parent, id);
+ this.in = in;
+ }
+
+ @Override public boolean
+ equals(Object other)
+ {
+ if(other == null)
+ {
+ return false;
+ }
+ else if(other == this)
+ {
+ return true;
+ }
+ else if(!(other instanceof BandwidhMetricsInfo))
+ {
+ return false;
+ }
+ BandwidhMetricsInfo that = (BandwidhMetricsInfo)other;
+ return super.equals(that) && this.in == that.in;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return IceInternal.HashUtil.hashAdd(super.hashCode(), in);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString());
+ sb.append(" - ");
+ sb.append((in ? "bytes received" : "bytes sent"));
+ return sb.toString();
+ }
+
+ public boolean in;
+ };
+
+ public class MetricsViewInfo
+ {
+ MetricsViewInfo(String node, String server, String view)
+ {
+ this.node = node;
+ this.server = server;
+ this.view = view;
+ }
+
+ @Override
+ public boolean equals(Object other)
+ {
+ if(other == null)
+ {
+ return false;
+ }
+ else if(other == this)
+ {
+ return true;
+ }
+ else if(!(other instanceof MetricsViewInfo))
+ {
+ return false;
+ }
+ MetricsViewInfo that = (MetricsViewInfo)other;
+ return this.node.equals(that.node) && this.server.equals(that.server) && this.view.equals(that.view);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int h = IceInternal.HashUtil.hashAdd(5381, node);
+ h = IceInternal.HashUtil.hashAdd(h, server);
+ return IceInternal.HashUtil.hashAdd(h, view);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(node);
+ sb.append(" - ");
+ sb.append(server);
+ sb.append(" - ");
+ sb.append(view);
+ return sb.toString();
+ }
+
+ public String node;
+ public String server;
+ public String view;
+ }
+
+ public class DeltaInfo
+ {
+ public DeltaInfo(long total, long totalLifetime)
+ {
+ this.total = total;
+ this.totalLifetime = totalLifetime;
+ }
+
+ public long total;
+ public long totalLifetime;
+ }
+
+ private class RefreshThread extends Thread
+ {
+ RefreshThread(long period)
+ {
+ _period = period;
+ _done = false;
+ }
+
+ synchronized void setRefreshPeriod(long period)
+ {
+ _period = period;
+ }
+
+ synchronized long getRefreshPeriod()
+ {
+ return _period;
+ }
+
+ synchronized public void
+ run()
+ {
+ while(true)
+ {
+ ArrayList<MetricsViewInfo> metrics = null;
+ synchronized(GraphView.this)
+ {
+ metrics = new ArrayList<MetricsViewInfo>(_metrics);
+ }
+ for(final MetricsViewInfo m : metrics)
+ {
+ Ice.Identity adminId = new Ice.Identity(m.server, _coordinator.getServerAdminCategory());
+ Ice.ObjectPrx admin = _coordinator.getAdmin().ice_identity(adminId);
+ IceMX.Callback_MetricsAdmin_getMetricsView cb = new IceMX.Callback_MetricsAdmin_getMetricsView()
+ {
+ public void response(final java.util.Map<java.lang.String, IceMX.Metrics[]> data)
+ {
+ addDelta(m, data, System.currentTimeMillis());
+ }
+
+ public void exception(final Ice.LocalException e)
+ {
+ // XXX
+ }
+
+ public void exception(final Ice.UserException e)
+ {
+ // XXX
+ }
+ };
+ try
+ {
+ IceMX.MetricsAdminPrx metricsAdmin =
+ IceMX.MetricsAdminPrxHelper.uncheckedCast(admin.ice_facet("MetricsAdmin"));
+ metricsAdmin.begin_getMetricsView(m.view, cb);
+ }
+ catch(Ice.LocalException e)
+ {
+ // XXX
+ }
+ }
+ if(!_done)
+ {
+ try
+ {
+ wait(getRefreshPeriod());
+ }
+ catch(InterruptedException ex)
+ {
+ }
+ }
+
+ if(_done)
+ {
+ break;
+ }
+ }
+ }
+
+ synchronized public void
+ done()
+ {
+ if(!_done)
+ {
+ _done = true;
+ notify();
+ }
+ }
+
+ private long _period;
+ private boolean _done = false;
+ }
+
+ public GraphView(Coordinator coordinator, GraphType type, GraphCategory category, final String title, String key)
+ {
+ _coordinator = coordinator;
+ _type = type;
+ _category = category;
+ setTitle(title);
+ _key = key;
+
+ //
+ // Don't destroy JavaFX when the frame is disposed.
+ //
+ Platform.setImplicitExit(false);
+
+ setIconImage(Utils.getIcon("/icons/16x16/grid.png").getImage());
+
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ addWindowListener(new WindowAdapter()
+ {
+ public void windowClosing(WindowEvent e)
+ {
+ close();
+ }
+ });
+
+ //
+ // Create actions
+ //
+ Action removeMetrics = new AbstractAction("Remove Metrics")
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ final DefaultTableModel model = new DefaultTableModel()
+ {
+ public Class getColumnClass(int column)
+ {
+ if(column == 3)
+ {
+ return Boolean.class;
+ }
+ else
+ {
+ return String.class;
+ }
+ }
+
+ public boolean isCellEditable(int row, int column)
+ {
+ return column == 3;
+ }
+ };
+ model.addColumn("Node");
+ model.addColumn("Server");
+ model.addColumn("View");
+ model.addColumn("Show");
+
+ for(MetricsViewInfo m : _metrics)
+ {
+ model.addRow(new Object[]{m.node, m.server, m.view, true});
+ }
+
+ JTable table = new JTable(model);
+ table.setPreferredSize(new Dimension(450, 300));
+ table.setPreferredScrollableViewportSize(table.getPreferredSize());
+ table.setCellSelectionEnabled(false);
+ table.setOpaque(false);
+ JScrollPane scrollPane = new JScrollPane(table);
+
+ JOptionPane.showMessageDialog(GraphView.this, scrollPane, "Select Servers",
+ JOptionPane.PLAIN_MESSAGE);
+
+ for(int i = 0; i < model.getRowCount(); ++i)
+ {
+ //
+ // Remove unselected metrics from the graph.
+ //
+ boolean selected = ((Boolean)model.getValueAt(i, 3)).booleanValue();
+ if(!selected)
+ {
+ MetricsViewInfo serverData = new MetricsViewInfo((String)model.getValueAt(i, 0),
+ (String)model.getValueAt(i, 1),
+ (String)model.getValueAt(i, 2));
+ _metrics.remove(serverData);
+ if(_metrics.size() == 0)
+ {
+ stopRefreshThread();
+ }
+ removeSeries(serverData);
+ }
+ }
+ }
+ };
+ removeMetrics.setEnabled(true);
+
+ //
+ // Graph preferences.
+ //
+ Action preferences = new AbstractAction("Preferences")
+ {
+ public void actionPerformed(ActionEvent event)
+ {
+ //
+ // SpinnerNumberModel to set a refresh period.
+ //
+ // min value is 500 ms == 0.5 seconds
+ // max value is 60 * 1000 ms == 60 seconds == 1 minute
+ //
+ SpinnerNumberModel refreshPeriod = new SpinnerNumberModel(getRefreshPeriod(), 500, 60 * 1000, 1);
+ JPanel refreshPanel;
+ {
+ DefaultFormBuilder builder =
+ new DefaultFormBuilder(new FormLayout("pref,2dlu,pref:grow", "pref"));
+ builder.append("Refresh period (ms):", new JSpinner(refreshPeriod));
+ refreshPanel = builder.getPanel();
+ }
+
+ //
+ // SpinnerNumberModel to set the number of symbols to keep in X axis.
+ //
+ // min value is 10
+ // max value is 100
+ //
+ SpinnerNumberModel horizontalAxisSymbolCount =
+ new SpinnerNumberModel(_horizontaSymbolsCount, 5, 100, 1);
+
+ //
+ // JComboBox to select time format used in X Axis
+ //
+ JComboBox<String> dateFormats = new JComboBox<String>(_dateFormats);
+ dateFormats.setSelectedItem(getDateFormat());
+ JPanel xAxisPanel;
+ {
+ DefaultFormBuilder builder =
+ new DefaultFormBuilder(new FormLayout("pref,2dlu,pref:grow", "pref"));
+ builder.append("Number of horizontal symbols:", new JSpinner(horizontalAxisSymbolCount));
+ builder.append("Time format:", dateFormats);
+
+ xAxisPanel = builder.getPanel();
+ }
+
+ //
+ // JComboBox to select Y Axis units.
+ //
+ JComboBox<String> units = null;
+ JPanel yAxisPanel = null;
+ if(_type == GraphType.BandwidhGraphType || _type == GraphType.TotalAverageGraphType)
+ {
+ if(_type == GraphType.BandwidhGraphType)
+ {
+ units = new JComboBox<String>(_bandwidthUnits);
+ units.setSelectedIndex(getBandwidthUnitIndex());
+ }
+ else
+ {
+ units = new JComboBox<String>(_timeUnits);
+ units.setSelectedIndex(getTimeUnitIndex());
+ }
+
+
+ {
+ DefaultFormBuilder builder =
+ new DefaultFormBuilder(new FormLayout("pref,2dlu,pref:grow", "pref"));
+ builder.append("Units:", units);
+ yAxisPanel = builder.getPanel();
+ }
+ }
+
+ FormLayout layout = new FormLayout("fill:pref:grow", "pref");
+ final DefaultFormBuilder builder = new DefaultFormBuilder(layout);
+ builder.border(Borders.DIALOG);
+ builder.appendSeparator("Refresh Thread");
+ builder.append(refreshPanel);
+ builder.nextLine();
+ builder.appendSeparator("Horizontal Axis");
+ builder.append(xAxisPanel);
+ if(yAxisPanel != null)
+ {
+ builder.appendSeparator("Vertical Axis");
+ builder.append(yAxisPanel);
+ }
+
+ class PreferencesDialog extends JDialog
+ {
+ PreferencesDialog(JFrame owner)
+ {
+ super(owner, true);
+ setTitle("Graph Preferences");
+ setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+ JButton okButton = new JButton("OK");
+ ActionListener okListener = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ _option = JOptionPane.OK_OPTION;
+ setVisible(false);
+ dispose();
+ }
+ };
+
+ ActionListener cancelListener = new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ setVisible(false);
+ dispose();
+ }
+ };
+
+ okButton.addActionListener(okListener);
+ getRootPane().setDefaultButton(okButton);
+ KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+ getRootPane().registerKeyboardAction(cancelListener, stroke,
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
+
+ final JComponent buttonBar = new ButtonBarBuilder().addGlue()
+ .addButton(okButton)
+ .addGlue().build();
+ buttonBar.setBorder(Borders.DIALOG);
+
+ Container contentPane = getContentPane();
+ contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
+ contentPane.add(builder.getPanel());
+ contentPane.add(buttonBar);
+ pack();
+ setResizable(false);
+ setLocationRelativeTo(owner);
+ }
+
+ int showDialog()
+ {
+ setVisible(true);
+ return _option;
+ }
+
+ private int _option = JOptionPane.CLOSED_OPTION;
+ };
+ //
+ // Disabled the default dialog action, so we can use Enter for commit table cells edit.
+ //
+ PreferencesDialog dialog = new PreferencesDialog(GraphView.this);
+
+ if(dialog.showDialog() != JOptionPane.OK_OPTION)
+ {
+ return;
+ }
+ setRefreshPeriod(refreshPeriod.getNumber().longValue());
+ setHorizontalSymbolsCount(horizontalAxisSymbolCount.getNumber().intValue());
+ setDateFormat((String)dateFormats.getSelectedItem());
+ if((_type == GraphType.BandwidhGraphType && getBandwidthUnitIndex() != units.getSelectedIndex()) ||
+ _type == GraphType.TotalAverageGraphType && getTimeUnitIndex() != units.getSelectedIndex())
+ {
+ final int index = units.getSelectedIndex();
+ final float cf = conversionFactor(index);
+ final String label = yAxisLabel(index);
+
+ if(_type == GraphType.BandwidhGraphType)
+ {
+ setBandwidthUnitIndex(index);
+ }
+ else
+ {
+ setTimeUnitIndex(index);
+ }
+
+ //
+ // Update the graph in JavaFX thread.
+ //
+ Platform.runLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ _yAxis.setLabel(label);
+ for(XYChart.Series<Number, Number> series : _chart.getData())
+ {
+ for(XYChart.Data<Number, Number> item : series.getData())
+ {
+ item.setYValue(item.getYValue().floatValue() * cf);
+ }
+ }
+ }
+ });
+ }
+ }
+ };
+
+ //
+ // Create menus
+ //
+ JMenuBar menuBar = new JMenuBar();
+
+ // Create a menu
+ JMenu fileMenu = new JMenu("File");
+ fileMenu.setMnemonic(java.awt.event.KeyEvent.VK_F);
+ fileMenu.add(removeMetrics);
+ fileMenu.add(preferences);
+ menuBar.add(fileMenu);
+
+ setJMenuBar(menuBar);
+
+ JLabel dropTarget = new JLabel("Drop runtime components here to add it to the graph.");
+ dropTarget.setBorder(new CompoundBorder(BorderFactory.createLineBorder(java.awt.Color.gray, 5, true),
+ new EmptyBorder(20, 20, 20, 20)));
+ dropTarget.setHorizontalAlignment(SwingConstants.CENTER);
+ Font f = dropTarget.getFont();
+ dropTarget.setFont(f.deriveFont(f.getStyle(), f.getSize() + 8));
+ dropTarget.setTransferHandler(new TransferHandler());
+
+
+ final JFXPanel fxPanel = new JFXPanel();
+ DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout("fill:pref:grow", "fill:pref:grow, pref"));
+ builder.append(fxPanel);
+ builder.nextLine();
+ builder.append(dropTarget);
+ builder.nextLine();
+
+ JPanel panel = builder.getPanel();
+ panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+ setContentPane(panel);
+ setPreferredSize(new Dimension(800, 600));
+ pack();
+ //
+ // initialize the scene in JavaFX thread.
+ //
+ Platform.runLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ _xAxis = new NumberAxis();
+ _yAxis = new NumberAxis();
+ _chart = new LineChart<Number, Number>(_xAxis, _yAxis);
+
+ _xAxis.setLabel("Time (HH:mm:ss)");
+ _xAxis.setTickLabelFormatter(_timeFormater);
+ _xAxis.setForceZeroInRange(false);
+ _yAxis.setLabel(yAxisLabel(getUnitsSelectedIndex()));
+ _chart.setTitle(title);
+ _chart.setAnimated(true);
+ fxPanel.setScene(new Scene(_chart));
+ }
+ });
+ setLocationRelativeTo(_coordinator.getMainFrame());
+ setVisible(true);
+ }
+
+ public void close()
+ {
+ stopRefreshThread();
+ setVisible(false);
+ _coordinator.removeGraphView(GraphView.this);
+ dispose();
+ }
+
+ synchronized private void startRefreshThread()
+ {
+ if(_refreshThread == null)
+ {
+ _refreshThread = new RefreshThread(getRefreshPeriod());
+ _refreshThread.start();
+ }
+ }
+
+ synchronized private void stopRefreshThread()
+ {
+ if(_refreshThread != null)
+ {
+ _refreshThread.done();
+ _refreshThread = null;
+ }
+ }
+
+ synchronized private void setHorizontalSymbolsCount(int count)
+ {
+ _horizontaSymbolsCount = count;
+ }
+
+ synchronized private int getHorizontalSymbolsCount()
+ {
+ return _horizontaSymbolsCount;
+ }
+
+ void addDelta(MetricsViewInfo info, java.util.Map<java.lang.String, IceMX.Metrics[]> data,
+ final long timestamp)
+ {
+ IceMX.Metrics[] metrics = data.get(_key);
+ Map<MetricsViewTargetInfo, XYChart.Series<Number, Number>> seriesSeq = _series.get(info);
+ if(seriesSeq == null)
+ {
+ return;
+ }
+
+ if(metrics != null)
+ {
+ if(_type == GraphType.TotalAverageGraphType)
+ {
+ for(IceMX.Metrics m : metrics)
+ {
+ MetricsViewTargetInfo targetInfo = new MetricsViewTargetInfo(info, m.id);
+ XYChart.Series<Number, Number> series = seriesSeq.get(targetInfo);
+ if(series == null)
+ {
+ continue;
+ }
+
+ float value = 0;
+ DeltaInfo delta = _deltas.get(targetInfo);
+ if(delta == null)
+ {
+ delta = new DeltaInfo(m.total, m.totalLifetime);
+ _deltas.put(targetInfo, delta);
+ continue; // We need two meassurements to calculate delta AVG.
+ }
+ long deltaTotal = (m.total - delta.total);
+ value = deltaTotal == 0 ? 0.0f :
+ (m.totalLifetime - delta.totalLifetime) / deltaTotal;
+ delta.total = m.total;
+ delta.totalLifetime = m.totalLifetime;
+ addDelta(series, timestamp, value * _timeUnitsFactors[getTimeUnitIndex()]);
+ }
+ }
+ else if(_type == GraphType.CurrentCountGraphType)
+ {
+ for(IceMX.Metrics m : metrics)
+ {
+ MetricsViewTargetInfo targetInfo = new MetricsViewTargetInfo(info, m.id);
+ XYChart.Series<Number, Number> series = seriesSeq.get(targetInfo);
+ if(series == null)
+ {
+ continue;
+ }
+ float value = 0;
+ value = m.current;
+ addDelta(series, timestamp, value);
+ }
+ }
+ else if(_type == GraphType.BandwidhGraphType)
+ {
+ for(IceMX.Metrics m : metrics)
+ {
+ IceMX.ConnectionMetrics cm = (IceMX.ConnectionMetrics)m;
+ for(boolean in : new boolean[]{true, false})
+ {
+ MetricsViewTargetInfo targetInfo = new BandwidhMetricsInfo(info, m.id, in);
+ XYChart.Series<Number, Number> series = seriesSeq.get(targetInfo);
+ if(series == null)
+ {
+ continue;
+ }
+
+ float value = 0;
+ DeltaInfo delta = _deltas.get(targetInfo);
+ if(delta == null)
+ {
+ if(in)
+ {
+ delta = new DeltaInfo(cm.receivedBytes, timestamp);
+ }
+ else
+ {
+ delta = new DeltaInfo(cm.sentBytes, timestamp);
+ }
+ _deltas.put(targetInfo, delta);
+ continue; // We need two meassurements to calculate delta AVG.
+ }
+
+ if(in)
+ {
+ boolean zero = (cm.receivedBytes - delta.total) == 0 ||
+ (timestamp - delta.totalLifetime) == 0;
+ value = zero ? 0.0f : (cm.receivedBytes - delta.total) /
+ (float)(timestamp - delta.totalLifetime);
+ delta.total = cm.receivedBytes;
+ delta.totalLifetime = timestamp;
+ }
+ else
+ {
+ boolean zero = (cm.sentBytes - delta.total) == 0 ||
+ (timestamp - delta.totalLifetime) == 0;
+ value = zero ? 0.0f : (cm.sentBytes - delta.total) /
+ (float)(timestamp - delta.totalLifetime);
+ delta.total = cm.sentBytes;
+ delta.totalLifetime = timestamp;
+ }
+ addDelta(series, timestamp, value * _bandwidthUnitsFactors[getBandwidthUnitIndex()]);
+ }
+ }
+ }
+ }
+ }
+
+ private void addDelta(final XYChart.Series<Number, Number> series, final long timestamp, final float value)
+ {
+ //
+ // Update the graph series in JavaFX thread.
+ //
+ Platform.runLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ series.getData().add(new XYChart.Data<Number, Number>(timestamp, value));
+ while(series.getData().size() > getHorizontalSymbolsCount())
+ {
+ series.getData().remove(0);
+ }
+ }
+ });
+ }
+
+ public void addSeries(final MetricsViewInfo info, final IceMX.Metrics[] data)
+ {
+ //
+ // Need to run in JavaFX thread.
+ //
+ Platform.runLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if(data != null)
+ {
+ Map<MetricsViewTargetInfo, XYChart.Series<Number, Number>> seriesSeq = _series.get(info);
+ if(seriesSeq == null)
+ {
+ seriesSeq = new HashMap<MetricsViewTargetInfo, XYChart.Series<Number, Number>>();
+ _series.put(info, seriesSeq);
+ }
+
+ if(_category != GraphCategory.BandwidthGraphCategory)
+ {
+ for(IceMX.Metrics m : data)
+ {
+ MetricsViewTargetInfo targetInfo = new MetricsViewTargetInfo(info, m.id);
+ XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
+ series.setName(targetInfo.toString());
+ seriesSeq.put(targetInfo, series);
+ _chart.getData().add(series);
+ }
+ }
+ else
+ {
+ for(IceMX.Metrics m : data)
+ {
+ for(boolean in : new boolean[]{true, false})
+ {
+ MetricsViewTargetInfo targetInfo = new BandwidhMetricsInfo(info, m.id, in);
+ XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
+ series.setName(targetInfo.toString());
+ seriesSeq.put(targetInfo, series);
+ _chart.getData().add(series);
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+ //
+ // Remove all series associated to a Metrics View
+ //
+ public void removeSeries(final MetricsViewInfo info)
+ {
+ //
+ // Need to run in JavaFX thread.
+ //
+ Platform.runLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Map<MetricsViewTargetInfo, XYChart.Series<Number, Number>> seriesSeq = _series.get(info);
+ if(seriesSeq != null)
+ {
+ for(Map.Entry<MetricsViewTargetInfo, XYChart.Series<Number, Number>> entry :
+ seriesSeq.entrySet())
+ {
+ _chart.getData().remove(entry.getValue());
+ }
+ _series.remove(info);
+ }
+ }
+ });
+ }
+
+ synchronized long getRefreshPeriod()
+ {
+ return _refreshPeriod;
+ }
+
+ synchronized void setRefreshPeriod(long refreshPeriod)
+ {
+ _refreshPeriod = refreshPeriod;
+ if(_refreshThread != null)
+ {
+ _refreshThread.setRefreshPeriod(_refreshPeriod);
+ }
+ }
+
+ synchronized String getDateFormat()
+ {
+ return _dateFormat;
+ }
+
+ synchronized void setDateFormat(String dateFormat)
+ {
+ _dateFormat = dateFormat;
+ _timeFormater.setDateFormat(dateFormat);
+ }
+
+ synchronized String getBandwithUnit()
+ {
+ return _bandwidthUnits[_bandwidthUnitIndex];
+ }
+
+ synchronized int getBandwidthUnitIndex()
+ {
+ return _bandwidthUnitIndex;
+ }
+
+ synchronized void setBandwidthUnitIndex(int index)
+ {
+ _bandwidthUnitIndex = index;
+ }
+
+ synchronized String getTimeUnit()
+ {
+ return _timeUnits[_timeUnitIndex];
+ }
+
+ synchronized int getTimeUnitIndex()
+ {
+ return _timeUnitIndex;
+ }
+
+ synchronized void setTimeUnitIndex(int index)
+ {
+ _timeUnitIndex = index;
+ }
+
+ synchronized float conversionFactor(int index)
+ {
+ return _type == GraphType.BandwidhGraphType ?
+ _bandwidthUnitsFactors[index] / _bandwidthUnitsFactors[_bandwidthUnitIndex] :
+ _timeUnitsFactors[index] / _timeUnitsFactors[_timeUnitIndex];
+ }
+
+ synchronized String yAxisLabel(int index)
+ {
+ if(_type == GraphType.BandwidhGraphType)
+ {
+ return _bandwidthUnits[index];
+ }
+ else if(_type == GraphType.TotalAverageGraphType)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Average ");
+ if(_category == GraphCategory.DispatchGraphCategory)
+ {
+ sb.append("dispatch ");
+ }
+ else
+ {
+ sb.append("invocation ");
+ }
+ sb.append("time (");
+ sb.append(_timeUnits[index]);
+ sb.append(")");
+ return sb.toString();
+ }
+ else if(_category == GraphCategory.ThreadsGraphCategory)
+ {
+ return "Threads";
+ }
+ else if(_category == GraphCategory.ConnectionsGraphCategory)
+ {
+ return "Connections";
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ synchronized int getUnitsSelectedIndex()
+ {
+ if(_type == GraphType.BandwidhGraphType)
+ {
+ return _bandwidthUnitIndex;
+ }
+ else if(_type == GraphType.TotalAverageGraphType)
+ {
+ return _timeUnitIndex;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private final Coordinator _coordinator;
+ private RefreshThread _refreshThread;
+ private final List<MetricsViewInfo> _metrics = new ArrayList<MetricsViewInfo>();
+ private Map<MetricsViewInfo, Map<MetricsViewTargetInfo, XYChart.Series<Number, Number>>> _series =
+ new HashMap<MetricsViewInfo, Map<MetricsViewTargetInfo, XYChart.Series<Number, Number>>>();
+
+ private Map<MetricsViewTargetInfo, DeltaInfo> _deltas = new HashMap<MetricsViewTargetInfo, DeltaInfo>();
+
+ private LineChart<Number, Number> _chart;
+ private final GraphCategory _category;
+ private final GraphType _type;
+ private final String _key;
+ private int _horizontaSymbolsCount = 10;
+
+ private long _refreshPeriod = 5000;
+
+ private String[] _dateFormats = new String[]{"HH:mm:ss", "mm:ss"};
+ private String _dateFormat = _dateFormats[0];
+
+ private String[] _bandwidthUnits = new String[]{"Bytes/s", "KBytes/s", "Bytes/min", "KBytes/min"};
+ private float[] _bandwidthUnitsFactors = new float[]{1000.0f, 1.0f, 60000.0f, 60.0f};
+ private int _bandwidthUnitIndex = 0;
+
+ private String[] _timeUnits = new String[]{"\u00B5s", "ms", "s"};
+ private float [] _timeUnitsFactors = new float[]{1.0f, 0.001f, 0.000001f};
+ private int _timeUnitIndex = 1;
+
+ final TimeFormatter _timeFormater = new TimeFormatter();
+ final Object _monitor = new Object();
+
+ NumberAxis _xAxis;
+ NumberAxis _yAxis;
+
+ private final static String NodeMimeType =
+ "application/x-java-jvm-local-objectref; class=IceGridGUI.LiveDeployment.Node";
+ private final static String ServerMimeType =
+ "application/x-java-jvm-local-objectref; class=IceGridGUI.LiveDeployment.Server";
+ private final static String MetricsViewMimeType =
+ "application/x-java-jvm-local-objectref; class=IceGridGUI.LiveDeployment.MetricsView";
+}