diff options
Diffstat (limited to 'java/src/IceGridGUI/LiveDeployment')
-rwxr-xr-x | java/src/IceGridGUI/LiveDeployment/Node.java | 32 | ||||
-rwxr-xr-x | java/src/IceGridGUI/LiveDeployment/Root.java | 102 | ||||
-rwxr-xr-x | java/src/IceGridGUI/LiveDeployment/Server.java | 30 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java | 592 | ||||
-rwxr-xr-x | java/src/IceGridGUI/LiveDeployment/TreeNode.java | 17 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/WriteMessageDialog.java | 4 |
6 files changed, 771 insertions, 6 deletions
diff --git a/java/src/IceGridGUI/LiveDeployment/Node.java b/java/src/IceGridGUI/LiveDeployment/Node.java index 3ba6ecb9122..bb70bbd6415 100755 --- a/java/src/IceGridGUI/LiveDeployment/Node.java +++ b/java/src/IceGridGUI/LiveDeployment/Node.java @@ -36,9 +36,38 @@ class Node extends ListTreeNode { boolean[] actions = new boolean[ACTION_COUNT]; actions[SHUTDOWN_NODE] = _up; + actions[RETRIEVE_STDOUT] = _up; + actions[RETRIEVE_STDERR] = _up; return actions; } + public void retrieveOutput(final boolean stdout) + { + getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + { + public FileIteratorPrx open(int count) + throws FileNotAvailableException, NodeNotExistException, NodeUnreachableException + { + AdminSessionPrx adminSession = getRoot().getCoordinator().getSession(); + + if(stdout) + { + return adminSession.openNodeStdOut(_id, count); + } + else + { + return adminSession.openNodeStdErr(_id, count); + } + } + + public String getTitle() + { + return "Node " + _id + " " + (stdout ? "Stdout" : "Stderr"); + } + }); + } + + public void shutdownNode() { final String prefix = "Shutting down node '" + _id + "'..."; @@ -91,6 +120,9 @@ class Node extends ListTreeNode if(_popup == null) { _popup = new JPopupMenu(); + _popup.add(la.get(RETRIEVE_STDOUT)); + _popup.add(la.get(RETRIEVE_STDERR)); + _popup.addSeparator(); _popup.add(la.get(SHUTDOWN_NODE)); } diff --git a/java/src/IceGridGUI/LiveDeployment/Root.java b/java/src/IceGridGUI/LiveDeployment/Root.java index 1278fde61bf..cafe9e8d64d 100755 --- a/java/src/IceGridGUI/LiveDeployment/Root.java +++ b/java/src/IceGridGUI/LiveDeployment/Root.java @@ -21,6 +21,7 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import java.util.Enumeration; +import java.util.prefs.Preferences; import IceGrid.*; import IceGridGUI.*; @@ -40,6 +41,8 @@ public class Root extends ListArrayTreeNode _tree = new JTree(this, true); _treeModel = (DefaultTreeModel)_tree.getModel(); _objectDialog = new ObjectDialog(this); + + loadLogPrefs(); } public boolean[] getAvailableActions() @@ -47,6 +50,8 @@ public class Root extends ListArrayTreeNode boolean[] actions = new boolean[ACTION_COUNT]; actions[ADD_OBJECT] = _coordinator.connectedToMaster(); actions[SHUTDOWN_REGISTRY] = true; + actions[RETRIEVE_STDOUT] = true; + actions[RETRIEVE_STDERR] = true; return actions; } @@ -163,6 +168,8 @@ public class Root extends ListArrayTreeNode public void applicationInit(String instanceName, String replicaName, java.util.List applications) { + closeAllShowLogDialogs(); + _replicaName = replicaName; _label = instanceName + " (" + _replicaName + ")"; _tree.setRootVisible(true); @@ -576,6 +583,9 @@ public class Root extends ListArrayTreeNode _popup = new JPopupMenu(); _popup.add(la.get(ADD_OBJECT)); _popup.addSeparator(); + _popup.add(la.get(RETRIEVE_STDOUT)); + _popup.add(la.get(RETRIEVE_STDERR)); + _popup.addSeparator(); _popup.add(la.get(SHUTDOWN_REGISTRY)); } @@ -832,6 +842,32 @@ public class Root extends ListArrayTreeNode Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } + + public void retrieveOutput(final boolean stdout) + { + getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + { + public FileIteratorPrx open(int count) + throws FileNotAvailableException, RegistryNotExistException, RegistryUnreachableException + { + AdminSessionPrx session = _coordinator.getSession(); + + if(stdout) + { + return session.openRegistryStdOut(_replicaName, count); + } + else + { + return session.openRegistryStdErr(_replicaName, count); + } + } + + public String getTitle() + { + return "Registry " + _label + " " + (stdout ? "Stdout" : "Stderr"); + } + }); + } PropertySetDescriptor findNamedPropertySet(String name, String applicationName) @@ -841,6 +877,62 @@ public class Root extends ListArrayTreeNode return (PropertySetDescriptor)descriptor.propertySets.get(name); } + + void openShowLogDialog(ShowLogDialog.FileIteratorFactory factory) + { + ShowLogDialog d = (ShowLogDialog)_showLogDialogMap.get(factory.getTitle()); + if(d == null) + { + d = new ShowLogDialog(this, factory, + _logPeriod, _logInitialLines, + _logMaxLines, _logMaxSize, _logMaxReadLines); + + _showLogDialogMap.put(factory.getTitle(), d); + } + else + { + d.toFront(); + } + } + + void removeShowLogDialog(String title) + { + _showLogDialogMap.remove(title); + } + + public void closeAllShowLogDialogs() + { + java.util.Iterator p = _showLogDialogMap.values().iterator(); + while(p.hasNext()) + { + ShowLogDialog d = (ShowLogDialog)p.next(); + d.close(false); + } + _showLogDialogMap.clear(); + } + + + private void loadLogPrefs() + { + Preferences logPrefs = _coordinator.getPrefs().node("Log"); + _logPeriod = logPrefs.getInt("period", 300); + _logInitialLines = logPrefs.getInt("initialLines", 10); + _logMaxLines = logPrefs.getInt("maxLines", 500); + _logMaxSize = logPrefs.getInt("maxSize", 20000); + _logMaxReadLines = logPrefs.getInt("maxReadLines", 50); + } + + private void storeLogPrefs() + { + Preferences logPrefs = _coordinator.getPrefs().node("Log"); + logPrefs.putInt("period", _logPeriod); + logPrefs.putInt("initialLines", _logInitialLines); + logPrefs.putInt("maxLines", _logMaxLines); + logPrefs.putInt("maxSize", _logMaxSize); + logPrefs.putInt("maxReadLines", _logMaxReadLines); + } + + private Node findNode(String nodeName) { return (Node)find(nodeName, _nodes); @@ -905,6 +997,16 @@ public class Root extends ListArrayTreeNode private ObjectDialog _objectDialog; + // + // ShowLogDialog + // + java.util.Map _showLogDialogMap = new java.util.HashMap(); + int _logPeriod; + int _logInitialLines; + int _logMaxLines; + int _logMaxSize; + int _logMaxReadLines; + static private RegistryEditor _editor; static private JPopupMenu _popup; static private DefaultTreeCellRenderer _cellRenderer; diff --git a/java/src/IceGridGUI/LiveDeployment/Server.java b/java/src/IceGridGUI/LiveDeployment/Server.java index 864e124bf9c..d774e004ae9 100755 --- a/java/src/IceGridGUI/LiveDeployment/Server.java +++ b/java/src/IceGridGUI/LiveDeployment/Server.java @@ -42,6 +42,8 @@ class Server extends ListArrayTreeNode actions[ENABLE] = !_enabled; actions[DISABLE] = _enabled; actions[WRITE_MESSAGE] = _state != ServerState.Inactive; + actions[RETRIEVE_STDOUT] = true; + actions[RETRIEVE_STDERR] = true; actions[PATCH_SERVER] = !_serverDescriptor.distrib.icepatch.equals(""); @@ -167,6 +169,32 @@ class Server extends ListArrayTreeNode _writeMessageDialog.showDialog(_id); } + public void retrieveOutput(final boolean stdout) + { + getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + { + public FileIteratorPrx open(int count) + throws FileNotAvailableException, ServerNotExistException, NodeUnreachableException, DeploymentException + { + AdminSessionPrx adminSession = getRoot().getCoordinator().getSession(); + + if(stdout) + { + return adminSession.openServerStdOut(_id, count); + } + else + { + return adminSession.openServerStdErr(_id, count); + } + } + + public String getTitle() + { + return "Server " + _id + " " + (stdout ? "Stdout" : "Stderr"); + } + }); + } + public void signal(final String s) { final String prefix = "Sending '" + s + "' to server '" + _id + "'..."; @@ -332,6 +360,8 @@ class Server extends ListArrayTreeNode _popup.add(la.get(PATCH_SERVER)); _popup.addSeparator(); _popup.add(la.get(WRITE_MESSAGE)); + _popup.add(la.get(RETRIEVE_STDOUT)); + _popup.add(la.get(RETRIEVE_STDERR)); _popup.addSeparator(); JMenu signalMenu = new JMenu("Send signal"); diff --git a/java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java b/java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java new file mode 100644 index 00000000000..98d9b485b10 --- /dev/null +++ b/java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java @@ -0,0 +1,592 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 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.awt.Cursor; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Frame; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; + +import com.jgoodies.looks.BorderStyle; +import com.jgoodies.looks.HeaderStyle; +import com.jgoodies.looks.Options; +import com.jgoodies.looks.plastic.PlasticLookAndFeel; + +import IceGrid.*; +import IceGridGUI.*; + +class ShowLogDialog extends JDialog +{ + static interface FileIteratorFactory + { + FileIteratorPrx open(int count) + throws Ice.UserException; + + String getTitle(); + } + + private class FIFOTextArea extends JTextArea + { + FIFOTextArea(int rows, int colums) + { + super(rows, colums); + setEditable(false); + setLineWrap(true); + } + + public void appendLines(final String[] lines, final int maxLines, final int maxSize) + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + for(int i = 0; i < lines.length; ++i) + { + // + // The last line is always incomplete + // + if(i + 1 != lines.length) + { + append(lines[i] + "\n"); + } + else + { + append(lines[i]); + } + removeLines(maxLines, maxSize); + } + } + }); + } + + public void removeLines(int maxLines, int maxSize) + { + javax.swing.text.Document doc = getDocument(); + javax.swing.text.Element rootElt = doc.getDefaultRootElement(); + + // + // We keep at least one line, no matter its length + // + int lineCount = getLineCount(); + while(lineCount > 1 && (doc.getLength() > maxSize || (lineCount > maxLines))) + { + javax.swing.text.Element firstLine = rootElt.getElement(0); + try + { + doc.remove(0, firstLine.getEndOffset()); + } + catch(javax.swing.text.BadLocationException ble) + { + assert false; + } + lineCount--; + } + setCaretPosition(doc.getLength()); + } + + } + + private class ReaderThread extends Thread + { + ReaderThread() + { + _threadInitialLines = _initialLines; + _threadMaxLines = _maxLines; + _threadMaxSize = _maxSize; + _threadMaxReadLines = _maxReadLines; + + _play.setEnabled(false); + _pause.setEnabled(true); + _stop.setEnabled(true); + } + + private void openError(final String message) + { + SwingUtilities.invokeLater( + new Runnable() + { + public void run() + { + if(_textArea.getText() == null || _textArea.getText().length() == 0) + { + close(true); + } + else + { + stopReading(); + } + + JOptionPane.showMessageDialog( + ShowLogDialog.this, + message, + _factory.getTitle() + ": cannot open file", + JOptionPane.ERROR_MESSAGE); + } + }); + } + + + public void run() + { + // + // Open file + // + int initialLines; + + synchronized(this) + { + initialLines = _threadInitialLines; + } + + try + { + _p = _factory.open(initialLines); + } + catch(Ice.UserException e) + { + openError(e.toString()); + return; + } + catch(Ice.LocalException e) + { + openError(e.toString()); + return; + } + + SwingUtilities.invokeLater( + new Runnable() + { + public void run() + { + if(isVisible()) + { + _textArea.setText(null); + } + else + { + setVisible(true); + } + } + }); + + boolean firstRun = true; + for(;;) + { + synchronized(this) + { + if(!_done) + { + if(_paused) + { + while(_paused && !_done) + { + try + { + wait(); + } + catch(InterruptedException e) + { + } + } + } + else if(!firstRun) + { + try + { + wait(_period); + } + catch(InterruptedException e) + { + } + } + else + { + firstRun = false; + } + } + + if(_done) + { + cleanupIterator(); + return; + } + } + + boolean eofEncountered = false; + + while(!eofEncountered) + { + int maxLines; + int maxSize; + int maxReadLines; + + synchronized(this) + { + if(_done || _paused) + { + break; // while(!eofEncountered) + } + + maxLines = _threadMaxLines; + maxSize = _threadMaxSize; + maxReadLines = _threadMaxReadLines; + } + + Ice.StringSeqHolder linesHolder = new Ice.StringSeqHolder(); + + try + { + eofEncountered = _p.read(maxReadLines, _maxReadSize, linesHolder); + } + catch(IceGrid.FileNotAvailableException e) + { + _textArea.appendLines(new String[] + { + "---------------------------", + "IceGridAdmin caught: " + e.toString(), + "---------------------------" + }, maxLines, maxSize); + SwingUtilities.invokeLater( + new Runnable() + { + public void run() + { + stopReading(); + } + }); + cleanupIterator(); + return; + } + catch(Ice.LocalException e) + { + _textArea.appendLines(new String[] + { + "---------------------------", + "IceGridAdmin caught: " + e.toString(), + "---------------------------" + }, maxLines, maxSize); + SwingUtilities.invokeLater( + new Runnable() + { + public void run() + { + stopReading(); + } + }); + return; + } + + _textArea.appendLines(linesHolder.value, maxLines, maxSize); + } + } + } + + private void cleanupIterator() + { + try + { + _p.destroy(); + } + catch(Ice.LocalException e) + { + // Ignored, maybe should log warning + } + } + + synchronized void pause() + { + assert !_paused; + _paused = true; + notify(); + } + + synchronized void terminate() + { + _done = true; + notify(); + } + + synchronized void play() + { + assert _paused; + _paused = false; + notify(); + } + + synchronized void setPrefs(int initialLines, int maxLines, int maxSize, int maxReadLines) + { + _threadInitialLines = initialLines; + _threadMaxLines = maxLines; + _threadMaxSize = maxSize; + _threadMaxReadLines = maxReadLines; + } + + private FileIteratorPrx _p; + private boolean _done = false; + private boolean _paused = false; + + private int _threadInitialLines; + private int _threadMaxLines; + private int _threadMaxSize; + private int _threadMaxReadLines; + + } + + private class MenuBar extends JMenuBar + { + private MenuBar() + { + putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH); + putClientProperty(PlasticLookAndFeel.BORDER_STYLE_KEY, BorderStyle.SEPARATOR); + + // + // File menu + // + JMenu fileMenu = new JMenu("File"); + fileMenu.setMnemonic(java.awt.event.KeyEvent.VK_F); + add(fileMenu); + fileMenu.add(_pause); + fileMenu.add(_play); + fileMenu.add(_stop); + fileMenu.addSeparator(); + fileMenu.add(new AbstractAction("Save as...") + { + public void actionPerformed(ActionEvent e) + { + // todo + } + + }); + fileMenu.addSeparator(); + + fileMenu.add(new AbstractAction("Close") + { + public void actionPerformed(ActionEvent e) + { + close(true); + } + }); + JMenu editMenu = new JMenu("Edit"); + editMenu.setMnemonic(java.awt.event.KeyEvent.VK_E); + add(editMenu); + editMenu.add(new AbstractAction("Copy") + { + public void actionPerformed(ActionEvent e) + { + _textArea.copy(); + } + + }); + editMenu.addSeparator(); + editMenu.add(new AbstractAction("Select all") + { + public void actionPerformed(ActionEvent e) + { + _textArea.grabFocus(); + _textArea.selectAll(); + } + + }); + editMenu.addSeparator(); + editMenu.add(new AbstractAction("Preferences") + { + public void actionPerformed(ActionEvent e) + { + // todo + } + }); + } + } + + private class ToolBar extends JToolBar + { + private ToolBar() + { + putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH); + putClientProperty(PlasticLookAndFeel.BORDER_STYLE_KEY, BorderStyle.SEPARATOR); + setFloatable(false); + putClientProperty("JToolBar.isRollover", Boolean.TRUE); + + JButton button = new JButton(_pause); + button.setText(null); + button.setIcon(Utils.getIcon("/icons/16x16/pause.png")); + add(button); + button = new JButton(_play); + button.setText(null); + button.setIcon(Utils.getIcon("/icons/16x16/start.png")); + add(button); + button = new JButton(_stop); + button.setText(null); + button.setIcon(Utils.getIcon("/icons/16x16/stop.png")); + add(button); + + } + } + + + ShowLogDialog(Root root, FileIteratorFactory factory, + int period, int initialLines, int maxLines, int maxSize, int maxReadLines) + { + super(root.getCoordinator().getMainFrame(), factory.getTitle() + " - IceGrid Admin", false); + + _period = period; + _initialLines = initialLines; + _maxLines = maxLines; + _maxSize = maxSize; + _maxReadLines = maxReadLines; + _factory = factory; + _root = root; + + setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() + { + public void windowClosing(java.awt.event.WindowEvent e) + { + close(true); + } + }); + + _pause = new AbstractAction("Pause") + { + public void actionPerformed(ActionEvent e) + { + pause(); + } + }; + _pause.setEnabled(false); + + + _play = new AbstractAction("Play") + { + public void actionPerformed(ActionEvent e) + { + play(); + } + }; + _play.setEnabled(false); + + + _stop = new AbstractAction("Stop") + { + public void actionPerformed(ActionEvent e) + { + stopReading(); + } + }; + _stop.setEnabled(false); + + setJMenuBar(new MenuBar()); + getContentPane().add(new ToolBar(), + BorderLayout.PAGE_START); + + JScrollPane scrollPane = new JScrollPane(_textArea, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + + getContentPane().add(scrollPane); + + pack(); + setResizable(true); + + setLocationRelativeTo(root.getCoordinator().getMainFrame()); + play(); + } + + void pause() + { + _thread.pause(); + _pause.setEnabled(false); + _play.setEnabled(true); + } + + void stopReading() + { + if(_thread != null) + { + _thread.terminate(); + + try + { + _thread.join(); + } + catch(InterruptedException e) + { + } + + _thread = null; + _stop.setEnabled(false); + _play.setEnabled(true); + _pause.setEnabled(false); + } + } + + void play() + { + if(_thread != null) + { + _thread.play(); + _play.setEnabled(false); + _pause.setEnabled(true); + _stop.setEnabled(true); + } + else + { + _thread = new ReaderThread(); + _thread.start(); + } + } + + void close(boolean notifyRoot) + { + stopReading(); + + if(notifyRoot) + { + _root.removeShowLogDialog(_factory.getTitle()); + } + dispose(); + } + + private final Root _root; + private final FileIteratorFactory _factory; + private final int _maxReadSize = 800000; // TODO, compute from MessageSizeMax or remove + + private int _period; + private int _initialLines; + private int _maxLines; + private int _maxSize; + private int _maxReadLines; + + private Action _play; + private Action _pause; + private Action _stop; + + private FIFOTextArea _textArea = new FIFOTextArea(20, 45); + private ReaderThread _thread; +} diff --git a/java/src/IceGridGUI/LiveDeployment/TreeNode.java b/java/src/IceGridGUI/LiveDeployment/TreeNode.java index bf1a865eb59..50abcf00ddd 100755 --- a/java/src/IceGridGUI/LiveDeployment/TreeNode.java +++ b/java/src/IceGridGUI/LiveDeployment/TreeNode.java @@ -47,14 +47,17 @@ public abstract class TreeNode extends TreeNodeBase public static final int WRITE_MESSAGE = 11; - public static final int SHUTDOWN_NODE = 12; - public static final int SHUTDOWN_REGISTRY = 13; + public static final int RETRIEVE_STDOUT = 12; + public static final int RETRIEVE_STDERR = 13; + + public static final int SHUTDOWN_NODE = 14; + public static final int SHUTDOWN_REGISTRY = 15; - public static final int PATCH_SERVER = 14; + public static final int PATCH_SERVER = 16; - public static final int ADD_OBJECT = 15; + public static final int ADD_OBJECT = 17; - static public final int ACTION_COUNT = 16; + static public final int ACTION_COUNT = 18; public boolean[] getAvailableActions() { @@ -81,6 +84,10 @@ public abstract class TreeNode extends TreeNodeBase { assert false; } + public void retrieveOutput(boolean stdout) + { + assert false; + } public void signal(String s) { assert false; diff --git a/java/src/IceGridGUI/LiveDeployment/WriteMessageDialog.java b/java/src/IceGridGUI/LiveDeployment/WriteMessageDialog.java index fab14442a9d..b2e8dc9df7c 100644 --- a/java/src/IceGridGUI/LiveDeployment/WriteMessageDialog.java +++ b/java/src/IceGridGUI/LiveDeployment/WriteMessageDialog.java @@ -48,6 +48,7 @@ class WriteMessageDialog extends JDialog super(root.getCoordinator().getMainFrame(), "Write Message - IceGrid Admin", true); setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); + _mainFrame = root.getCoordinator().getMainFrame(); _stdOut = new JRadioButton("Write to stdout"); @@ -160,7 +161,8 @@ class WriteMessageDialog extends JDialog builder.setDefaultDialogBorder(); builder.setRowGroupingEnabled(true); builder.setLineGapSize(LayoutStyle.getCurrent().getLinePad()); - + + _message.setLineWrap(true); JScrollPane scrollPane = new JScrollPane(_message, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); |