/* * Sun Public License * * The contents of this file are subject to the Sun Public License Version * 1.0 (the "License"). You may not use this file except in compliance with * the License. A copy of the License is available at http://www.sun.com/ * * The Original Code is the SLAMD Distributed Load Generation Engine. * The Initial Developer of the Original Code is Neil A. Wilson. * Portions created by Neil A. Wilson are Copyright (C) 2004-2010. * Some preexisting portions Copyright (C) 2002-2006 Sun Microsystems, Inc. * All Rights Reserved. * * Contributor(s): Neil A. Wilson */ package com.slamd.tools; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import java.util.Properties; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.slamd.client.Client; import com.slamd.client.ClientException; import com.slamd.client.ClientMessageWriter; import com.slamd.client.ClientShutdownListener; import com.slamd.common.Constants; import com.slamd.common.DynamicConstants; /** * This class provides a GUI front-end to the SLAMD client interface using the * Java Swing interface. * * * @author Neil A. Wilson */ public class SwingClient implements ActionListener, ChangeListener, ClientMessageWriter, ClientShutdownListener { /** * The name of the configuration property that specifies the address of the * SLAMD server. */ public static final String PROPERTY_SLAMD_ADDRESS = "SLAMD_ADDRESS"; /** * The name of the configuration property that specifies the client port for * the SLAMD server. */ public static final String PROPERTY_SLAMD_PORT = "SLAMD_PORT"; /** * The name of the configuration property that specifies the stat port for the * SLAMD server. */ public static final String PROPERTY_SLAMD_STAT_PORT = "SLAMD_STAT_PORT"; /** * The name of the configuration property that specifies whether to enable * real-time statistics tracking. */ public static final String PROPERTY_ENABLE_RT = "ENABLE_REAL_TIME_STATS"; /** * The name of the configuration property that specifies the interval for * reporting real-time statistics. */ public static final String PROPERTY_RT_INTERVAL = "REAL_TIME_REPORT_INTERVAL"; /** * The name of the configuration property that specifies whether to enable * stat persistence. */ public static final String PROPERTY_ENABLE_PERSISTENCE = "ENABLE_STAT_PERSISTENCE"; /** * The name of the configuration property that specifies the directory for * stat persistence data. */ public static final String PROPERTY_PERSISTENCE_DIR = "STAT_PERSISTENCE_DIRECTORY"; /** * The name of the configuration property that specifies the stat persistence * interval. */ public static final String PROPERTY_PERSISTENCE_INTERVAL = "STAT_PERSISTENCE_INTERVAL"; /** * The name of the configuration property that specifies the authentication * ID. */ public static final String PROPERTY_AUTH_ID = "AUTH_ID"; /** * The name of the configuration property that specifies the authentication * password. */ public static final String PROPERTY_AUTH_PW = "AUTH_PASS"; /** * The name of the configuration property that specifies whether to use SSL. */ public static final String PROPERTY_USE_SSL = "USE_SSL"; /** * The name of the configuration property that specifies whether to blindly * trust any certificate. */ public static final String PROPERTY_BLIND_TRUST = "BLIND_TRUST"; /** * The name of the configuration property that specifies the path to the SSL * keystore. */ public static final String PROPERTY_KEY_STORE = "SSL_KEY_STORE"; /** * The name of the configuration property that specifies the password for the * SSL keystore. */ public static final String PROPERTY_KEY_PASS = "SSL_KEY_PASS"; /** * The name of the configuration property that specifies the path to the SSL * trust store. */ public static final String PROPERTY_TRUST_STORE = "SSL_TRUST_PASS"; /** * The name of the configuration property that specifies the password for the * SSL trust store. */ public static final String PROPERTY_TRUST_PASS = "SSL_TRUST_PASS"; /** * The name of the configuration property that specifies whether to aggregate * client thread data. */ public static final String PROPERTY_AGGREGATE = "AGGREGATE_CLIENT_THREADS"; /** * The name of the configuration property that specifies whether to operate in * restricted mode. */ public static final String PROPERTY_RESTRICTED_MODE = "RESTRICTED_MODE"; /** * The name of the configuration property that specifies whether to disable * the custom class loader. */ public static final String PROPERTY_DISABLE_CL = "DISABLE_CUSTOM_CLASS_LOADER"; /** * The name of the configuration property that specifies whether to enable * verbose mode. */ public static final String PROPERTY_VERBOSE = "VERBOSE_MODE"; /** * The end-of-line marker that should be used on this platform. */ public static String EOL = System.getProperty("line.separator"); // The reference to the SLAMD client actually doing the work. private Client client; // Variables pertaining to the client configuration. private boolean aggregateThreadData = false; private boolean enableRealTimeStats = false; private boolean persistStats = false; private boolean restrictedMode = false; private boolean sslBlindTrust = true; private boolean useCustomClassLoader = true; private boolean useSSL = false; private boolean useTimeSync = true; private boolean verboseMode = false; private int persistenceInterval = 300; private int serverClientPort = 3000; private int serverStatPort = 3003; private int statReportInterval = 5; private String authID = null; private String authPW = null; private String classDirectory = "classes"; private String persistenceDirectory = "statpersistence"; private String serverAddress = "127.0.0.1"; private String sslKeyStore = null; private String sslKeyStorePassword = null; private String sslTrustStore = null; private String sslTrustStorePassword = null; // References to GUI components pertaining to the client configuration. private JButton copyAllButton; private JButton copySelectedButton; private JButton connectButton; private JButton dialogCancelButton; private JButton dialogConnectButton; private JCheckBox aggregateCheckbox; private JCheckBox blindTrustCheckbox; private JCheckBox enableRealTimeCheckbox; private JCheckBox persistStatsCheckbox; private JCheckBox restrictedModeCheckbox; private JCheckBox useSSLCheckbox; private JCheckBox verboseCheckbox; private JDialog connectDialog; private JFrame appWindow; private JLabel persistDirLabel; private JLabel persistIntervalLabel; private JLabel statIntervalLabel; private JLabel statPortLabel; private JLabel sslKeyStoreLabel; private JLabel sslKeyStorePasswordLabel; private JLabel sslTrustStoreLabel; private JLabel sslTrustStorePasswordLabel; private JPasswordField authPWField; private JPasswordField sslKeyStorePasswordField; private JPasswordField sslTrustStorePasswordField; private JTextArea messageArea; private JTextField authIDField; private JTextField hostField; private JTextField persistDirField; private JTextField persistIntervalField; private JTextField portField; private JTextField statPortField; private JTextField statIntervalField; private JTextField sslKeyStoreField; private JTextField sslTrustStoreField; /** * Launches the swing client with the provided set of command-line arguments. * * @param args The command-line arguments provided to this program. */ public static void main(String[] args) { new SwingClient(args); } /** * Creates a new instance of this swing client using the provided set of * command-line arguments. * * @param args The command-line arguments provided to this program. */ public SwingClient(String[] args) { // See if a configuration file was specified. If so, then use it to // initialize the client settings. for (int i=0; i < args.length; i++) { if (args[i].equals("-f")) { processConfigFile(args[++i]); break; } } // Parse the command-line arguments and assign their values to the // appropriate variables. for (int i=0; i < args.length; i++) { if (args[i].equals("-h")) { serverAddress = args[++i]; } else if (args[i].equals("-p")) { serverClientPort = Integer.parseInt(args[++i]); } else if (args[i].equals("-P")) { serverStatPort = Integer.parseInt(args[++i]); } else if (args[i].equals("-D")) { authID = args[++i]; } else if (args[i].equals("-w")) { authPW = args[++i]; } else if (args[i].equals("-c")) { classDirectory = args[++i]; } else if (args[i].equals("-a")) { aggregateThreadData = true; } else if (args[i].equals("-R")) { restrictedMode = true; } else if (args[i].equals("-S")) { useSSL = true; } else if (args[i].equals("-s")) { enableRealTimeStats = true; } else if (args[i].equals("-I")) { statReportInterval = Integer.parseInt(args[++i]); } else if (args[i].equals("-r")) { persistStats = true; } else if (args[i].equals("-i")) { persistenceInterval = Integer.parseInt(args[++i]); } else if (args[i].equals("-d")) { persistenceDirectory = args[++i]; } else if (args[i].equals("-B")) { sslBlindTrust = true; } else if (args[i].equals("-k")) { sslKeyStore = args[++i]; } else if (args[i].equals("-K")) { sslKeyStorePassword = args[++i]; } else if (args[i].equals("-t")) { sslTrustStore = args[++i]; } else if (args[i].equals("-T")) { sslTrustStorePassword = args[++i]; } else if (args[i].equals("-L")) { useCustomClassLoader = false; } else if (args[i].equals("-Y")) { useTimeSync = false; } else if (args[i].equals("-v")) { verboseMode = true; } else if (args[i].equals("-H")) { displayUsage(); return; } else if (args[i].equals("-f")) { // Already handled this. i++; } else { System.err.println("ERROR: Unrecognized argument \"" + args[i] + '"'); return; } } // Create the GUI layout for this client. appWindow = new JFrame("SLAMD Client - " + DynamicConstants.SLAMD_VERSION); appWindow.getContentPane().setLayout(new BorderLayout(5, 5)); JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); copySelectedButton = new JButton("Copy Selection to Clipboard"); copySelectedButton.addActionListener(this); northPanel.add(copySelectedButton); copyAllButton = new JButton("Copy All to Clipboard"); copyAllButton.addActionListener(this); northPanel.add(copyAllButton); connectButton = new JButton("Disconnect"); connectButton.addActionListener(this); northPanel.add(connectButton); messageArea = new JTextArea(30, 80); messageArea.setLineWrap(true); messageArea.setWrapStyleWord(true); messageArea.setEditable(false); messageArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); JScrollPane centerPane = new JScrollPane(messageArea); appWindow.getContentPane().add(northPanel, BorderLayout.NORTH); appWindow.getContentPane().add(centerPane, BorderLayout.CENTER); appWindow.pack(); appWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); appWindow.setVisible(true); connectButton.setText("Connect"); connectButton.requestFocus(); } /** * Detects an action event (i.e., button click) and performs the appropriate * task. * * @param event The action event that occurred. */ public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if (source == connectButton) { if (client == null) { if (connectDialog == null) { createConnectDialog(); } else { connectDialog.setVisible(true); } } else { client.disconnect(); client = null; connectButton.setText("Connect"); } } else if (source == dialogConnectButton) { try { serverAddress = hostField.getText(); serverClientPort = Integer.parseInt(portField.getText()); useSSL = useSSLCheckbox.isSelected(); sslBlindTrust = blindTrustCheckbox.isSelected(); sslKeyStore = sslKeyStoreField.getText(); sslKeyStorePassword = new String(sslKeyStorePasswordField.getPassword()); sslTrustStore = sslTrustStoreField.getText(); sslTrustStorePassword = new String(sslTrustStorePasswordField.getPassword()); authID = authIDField.getText(); authPW = new String(authPWField.getPassword()); enableRealTimeStats = enableRealTimeCheckbox.isSelected(); serverStatPort = Integer.parseInt(statPortField.getText()); statReportInterval = Integer.parseInt(statIntervalField.getText()); persistStats = persistStatsCheckbox.isSelected(); persistenceDirectory = persistDirField.getText(); persistenceInterval = Integer.parseInt(persistIntervalField.getText()); aggregateThreadData = aggregateCheckbox.isSelected(); restrictedMode = restrictedModeCheckbox.isSelected(); verboseMode = verboseCheckbox.isSelected(); int authType = Constants.AUTH_TYPE_NONE; if ((authID != null) && (authID.length() > 0) && (authPW != null) && (authPW.length() > 0)) { authType = Constants.AUTH_TYPE_SIMPLE; } client = new Client(null, null, serverAddress, serverClientPort, serverStatPort, useTimeSync, enableRealTimeStats, statReportInterval, persistStats, persistenceDirectory, persistenceInterval, authType, authID, authPW, restrictedMode, useCustomClassLoader, classDirectory, useSSL, sslBlindTrust, sslKeyStore, sslKeyStorePassword, sslTrustStore, sslTrustStorePassword, this); client.setShutdownListener(this); connectButton.setText("Disconnect"); client.start(); connectDialog.setVisible(false); } catch (ClientException ce) { messageArea.append("Unable to connect: " + ce); connectDialog.setVisible(false); } } else if (source == dialogCancelButton) { connectDialog.setVisible(false); } else if (source == copyAllButton) { int selectionStart = messageArea.getSelectionStart(); int selectionEnd = messageArea.getSelectionEnd(); messageArea.selectAll(); messageArea.copy(); messageArea.setSelectionStart(selectionStart); messageArea.setSelectionEnd(selectionEnd); } else if (source == copySelectedButton) { messageArea.copy(); } } /** * Detects a change event (i.e., checkbox selection/deselection) and performs * the appropriate task. * * @param event The change event that occurred. */ public void stateChanged(ChangeEvent event) { Object source = event.getSource(); if (source == useSSLCheckbox) { useSSL = useSSLCheckbox.isSelected(); blindTrustCheckbox.setEnabled(useSSL); sslKeyStoreLabel.setEnabled(useSSL); sslKeyStoreField.setEnabled(useSSL); sslKeyStorePasswordLabel.setEnabled(useSSL); sslKeyStorePasswordField.setEnabled(useSSL); sslTrustStoreLabel.setEnabled(useSSL); sslTrustStoreField.setEnabled(useSSL); sslTrustStorePasswordLabel.setEnabled(useSSL); sslTrustStorePasswordField.setEnabled(useSSL); } else if (source == enableRealTimeCheckbox) { enableRealTimeStats = enableRealTimeCheckbox.isSelected(); statPortLabel.setEnabled(enableRealTimeStats); statPortField.setEnabled(enableRealTimeStats); statIntervalLabel.setEnabled(enableRealTimeStats); statIntervalField.setEnabled(enableRealTimeStats); } else if (source == persistStatsCheckbox) { persistStats = persistStatsCheckbox.isSelected(); persistDirLabel.setEnabled(persistStats); persistDirField.setEnabled(persistStats); persistIntervalLabel.setEnabled(persistStats); persistIntervalField.setEnabled(persistStats); } } /** * Creates the dialog that collects the information necessary to connect to * the SLAMD server. */ public void createConnectDialog() { connectDialog = new JDialog(appWindow, "SLAMD Server Information", true); connectDialog.getContentPane().setLayout(new BorderLayout()); JPanel centerPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridheight = 1; gbc.gridwidth = 2; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.anchor = GridBagConstraints.WEST; centerPanel.add(new JLabel("Server Address"), gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; hostField = new JTextField(20); if (serverAddress != null) { hostField.setText(serverAddress); } centerPanel.add(hostField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; centerPanel.add(new JLabel("Server Port"), gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; portField = new JTextField(5); portField.setText(String.valueOf(serverClientPort)); centerPanel.add(portField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; centerPanel.add(new JPanel()); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; useSSLCheckbox = new JCheckBox("Connect Using SSL"); useSSLCheckbox.setSelected(useSSL); useSSLCheckbox.addChangeListener(this); centerPanel.add(useSSLCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; blindTrustCheckbox = new JCheckBox("Blindly Trust any Certificate"); blindTrustCheckbox.setSelected(sslBlindTrust); blindTrustCheckbox.setEnabled(useSSL); centerPanel.add(blindTrustCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; sslKeyStoreLabel = new JLabel("SSL Key Store Location"); sslKeyStoreLabel.setEnabled(useSSL); centerPanel.add(sslKeyStoreLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; sslKeyStoreField = new JTextField(20); if (sslKeyStore != null) { sslKeyStoreField.setText(sslKeyStore); } sslKeyStoreField.setEnabled(useSSL); centerPanel.add(sslKeyStoreField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; sslKeyStorePasswordLabel = new JLabel("SSL Key Store Password"); sslKeyStorePasswordLabel.setEnabled(useSSL); centerPanel.add(sslKeyStorePasswordLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; sslKeyStorePasswordField = new JPasswordField(20); if (sslKeyStorePassword != null) { sslKeyStorePasswordField.setText(sslKeyStorePassword); } sslKeyStorePasswordField.setEnabled(useSSL); centerPanel.add(sslKeyStorePasswordField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; sslTrustStoreLabel = new JLabel("SSL Trust Store Location"); sslTrustStoreLabel.setEnabled(useSSL); centerPanel.add(sslTrustStoreLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; sslTrustStoreField = new JTextField(20); if (sslTrustStore != null) { sslTrustStoreField.setText(sslTrustStore); } sslTrustStoreField.setEnabled(useSSL); centerPanel.add(sslTrustStoreField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; sslTrustStorePasswordLabel = new JLabel("SSL Trust Store Password"); sslTrustStorePasswordLabel.setEnabled(useSSL); centerPanel.add(sslTrustStorePasswordLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; sslTrustStorePasswordField = new JPasswordField(20); if (sslTrustStorePassword != null) { sslTrustStorePasswordField.setText(sslTrustStorePassword); } sslTrustStorePasswordField.setEnabled(useSSL); centerPanel.add(sslTrustStorePasswordField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; centerPanel.add(new JPanel()); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; centerPanel.add(new JLabel("Authentication ID"), gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; authIDField = new JTextField(20); if (authID != null) { authIDField.setText(authID); } centerPanel.add(authIDField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; centerPanel.add(new JLabel("Authentication Password"), gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; authPWField = new JPasswordField(20); if (authPW != null) { authPWField.setText(authID); } centerPanel.add(authPWField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; centerPanel.add(new JPanel()); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; enableRealTimeCheckbox = new JCheckBox("Enable Real-Time Statistics Reporting"); enableRealTimeCheckbox.setSelected(enableRealTimeStats); enableRealTimeCheckbox.addChangeListener(this); centerPanel.add(enableRealTimeCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; statPortLabel = new JLabel("SLAMD Server Stat Port"); statPortLabel.setEnabled(enableRealTimeStats); centerPanel.add(statPortLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; statPortField = new JTextField(5); statPortField.setText(String.valueOf(serverStatPort)); statPortField.setEnabled(enableRealTimeStats); centerPanel.add(statPortField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; statIntervalLabel = new JLabel("Stat Report Interval"); statIntervalLabel.setEnabled(enableRealTimeStats); centerPanel.add(statIntervalLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; statIntervalField = new JTextField(5); statIntervalField.setText(String.valueOf(statReportInterval)); statIntervalField.setEnabled(enableRealTimeStats); centerPanel.add(statIntervalField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; persistStatsCheckbox = new JCheckBox("Enable Client-Side Stat Persistence"); persistStatsCheckbox.setSelected(persistStats); persistStatsCheckbox.addChangeListener(this); centerPanel.add(persistStatsCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; persistDirLabel = new JLabel("Stat Persistence Directory"); persistDirLabel.setEnabled(persistStats); centerPanel.add(persistDirLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; persistDirField = new JTextField(20); persistDirField.setText(persistenceDirectory); persistDirField.setEnabled(persistStats); centerPanel.add(persistDirField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; persistIntervalLabel = new JLabel("Persistence Collection Interval"); persistIntervalLabel.setEnabled(persistStats); centerPanel.add(persistIntervalLabel, gbc); gbc.gridx = 2; gbc.gridwidth = GridBagConstraints.REMAINDER; persistIntervalField = new JTextField(5); persistIntervalField.setText(String.valueOf(persistenceInterval)); persistIntervalField.setEnabled(persistStats); centerPanel.add(persistIntervalField, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; centerPanel.add(new JPanel()); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; aggregateCheckbox = new JCheckBox("Aggregate Thread Data"); aggregateCheckbox.setSelected(aggregateThreadData); centerPanel.add(aggregateCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; restrictedModeCheckbox = new JCheckBox("Use Restricted Mode"); restrictedModeCheckbox.setSelected(restrictedMode); centerPanel.add(restrictedModeCheckbox, gbc); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = GridBagConstraints.REMAINDER; verboseCheckbox = new JCheckBox("Use Verbose Mode"); verboseCheckbox.setSelected(verboseMode); centerPanel.add(verboseCheckbox, gbc); JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); dialogConnectButton = new JButton("Connect"); dialogConnectButton.addActionListener(this); buttonPanel.add(dialogConnectButton); dialogCancelButton = new JButton("Cancel"); dialogCancelButton.addActionListener(this); buttonPanel.add(dialogCancelButton); connectDialog.getContentPane().add(centerPanel, BorderLayout.CENTER); connectDialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH); connectDialog.pack(); connectDialog.setVisible(true); } /** * Writes the provided message to the message text area. * * @param message The message to be written. */ public void writeMessage(String message) { messageArea.append(message + EOL); messageArea.setCaretPosition(messageArea.getText().length()); } /** * Writes the provided message to the message text area if verbose mode is * enabled. * * @param message The message to be written. */ public void writeVerbose(String message) { if (verboseCheckbox.isSelected()) { messageArea.append(message + EOL); messageArea.setCaretPosition(messageArea.getText().length()); } } /** * Indicates whether the message writer is using verbose mode and therefore * will display messages written with the <CODE>writeVerbose</CODE> method. * * @return <CODE>true</CODE> if the message writer is using verbose mode, or * <CODE>false</CODE> if not. */ public boolean usingVerboseMode() { return verboseCheckbox.isSelected(); } /** * Indicates that the client has disconnected from the server and that the * client may wish to take whatever action is appropriate. */ public void clientDisconnected() { writeMessage("Disconnected from the SLAMD server"); connectButton.setText("Connect"); client = null; } /** * Processes the contents of the specified config file. * * @param configFile The path to the configuration file to process. */ public void processConfigFile(String configFile) { Properties properties = new Properties(); try { properties.load(new FileInputStream(configFile)); } catch (IOException ioe) { System.err.println("ERROR: Unable to load properties file \"" + configFile + "\": " + ioe); System.exit(1); } Iterator keys = properties.keySet().iterator(); while (keys.hasNext()) { String name = (String) keys.next(); String value = properties.getProperty(name, null); if (value == null) { continue; } if (name.equals(PROPERTY_SLAMD_ADDRESS)) { serverAddress = value; } else if (name.equals(PROPERTY_SLAMD_PORT)) { serverClientPort = Integer.parseInt(value); } else if (name.equals(PROPERTY_SLAMD_STAT_PORT)) { serverStatPort = Integer.parseInt(value); } else if (name.equals(PROPERTY_ENABLE_RT)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { enableRealTimeStats = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { enableRealTimeStats = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_ENABLE_RT + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_RT_INTERVAL)) { statReportInterval = Integer.parseInt(value); } else if (name.equals(PROPERTY_ENABLE_PERSISTENCE)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { persistStats = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { persistStats = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_ENABLE_PERSISTENCE + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_PERSISTENCE_DIR)) { persistenceDirectory = value; } else if (name.equals(PROPERTY_PERSISTENCE_INTERVAL)) { persistenceInterval = Integer.parseInt(value); } else if (name.equals(PROPERTY_AUTH_ID)) { authID = value; } else if (name.equals(PROPERTY_AUTH_PW)) { authPW = value; } else if (name.equals(PROPERTY_USE_SSL)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { useSSL = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { useSSL = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_USE_SSL + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_BLIND_TRUST)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { sslBlindTrust = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { sslBlindTrust = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_BLIND_TRUST + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_KEY_STORE)) { sslKeyStore = value; } else if (name.equals(PROPERTY_KEY_PASS)) { sslKeyStorePassword = value; } else if (name.equals(PROPERTY_TRUST_STORE)) { sslTrustStore = value; } else if (name.equals(PROPERTY_TRUST_PASS)) { sslTrustStorePassword = value; } else if (name.equals(PROPERTY_AGGREGATE)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { aggregateThreadData = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { aggregateThreadData = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_AGGREGATE + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_RESTRICTED_MODE)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { restrictedMode = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { restrictedMode = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_RESTRICTED_MODE + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_DISABLE_CL)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { useCustomClassLoader = false; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { useCustomClassLoader = true; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_DISABLE_CL + " property as a Boolean."); System.exit(1); } } else if (name.equals(PROPERTY_VERBOSE)) { if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("1")) { verboseMode = true; } else if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off") || value.equalsIgnoreCase("0")) { verboseMode = false; } else { System.err.println("ERROR: Cannot interpret the value of the " + PROPERTY_VERBOSE + " property as a Boolean."); System.exit(1); } } } } /** * Displays usage information for this program. */ public void displayUsage() { String eol = Constants.EOL; System.err.println( "USAGE: java " + getClass().getName() + " [options]" + eol + " where [options] include:" + eol + "-h {host} -- The address of the SLAMD server." + eol + "-p {port} -- The port number of the SLAMD server." + eol + "-P {port} -- The port number that the SLAMD server uses for " + eol + " collecting real-time statistics. " + eol + "-D {authid} -- The ID to use to authenticate to the SLAMD server." + eol + "-w {authpw} -- The password for the authentication ID." + eol + "-c {dir} -- The name of the directory in which Java class files" + eol + " may be written." + eol + "-a -- Indicates that the data from each thread should be" + eol + " aggregated before sending results to the server." + eol + "-R -- Indicates that the client should operate in " + eol + " restricted mode." + eol + "-S -- Indicates that the client should communicate with the" + eol + " SLAMD server over SSL." + eol + "-s -- Indicates that the client should enable real-time " + eol + " statistics reporting to the SLAMD server." + eol + "-I {value} -- Specifies the interval (in seconds) to use when " + eol + " reporting real-time stats to the SLAMD server." + eol + "-r -- Indicates that the client should retain persistent" + eol + " data on disk for recovery in case of a failure" + eol + "-i {value} -- Specifies the interval in seconds that should be used" + eol + " when periodically persisting statistics to disk" + eol + "-d {dir} -- Specifies the directory into which statistical data" + eol + " should be written if persistence is enabled" + eol + "-B -- Indicates that the client blindly trust any SSL" + eol + " certificate presented by the SLAMD server." + eol + "-k {file} -- The location of the JSSE key store." + eol + "-K {pw} -- The password needed to access the JSSE key store." + eol + "-t {file} -- The location of the JSSE trust store." + eol + "-T {pw} -- The password needed to access the JSSE trust store." + eol + "-L -- Disable the custom class loader." + eol + "-Y -- Disable time synchronization with the SLAMD server." + eol + "-v -- Operate in verbose mode." + eol + "-H -- Show this usage information." + eol ); } }