blob: 5031dd075f4a387235d5d70f8d3e3a2570931547 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002-2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsi.internal.core.monitor;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Vector;
import org.eclipse.wst.wsi.internal.core.ToolInfo;
import org.eclipse.wst.wsi.internal.core.WSIConstants;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.WSIFileNotFoundException;
import org.eclipse.wst.wsi.internal.core.document.DocumentFactory;
import org.eclipse.wst.wsi.internal.core.log.Log;
import org.eclipse.wst.wsi.internal.core.log.LogWriter;
import org.eclipse.wst.wsi.internal.core.monitor.config.ManInTheMiddle;
import org.eclipse.wst.wsi.internal.core.monitor.config.MonitorConfig;
import org.eclipse.wst.wsi.internal.core.monitor.config.Redirect;
import org.eclipse.wst.wsi.internal.core.util.MessageList;
import org.eclipse.wst.wsi.internal.core.util.TestUtils;
/**
* Message Monitor.
*
* @author Peter Brittenham (peterbr.us.ibm.com)
*/
public class Monitor
{
/**
* Message list.
*/
protected MessageList messageList = null;
private final static String RESOURCE_BUNDLE_NAME =
"org.eclipse.wst.wsi.internal.core.monitor.Monitor";
public final static String USAGE_MESSAGE =
"Usage: Monitor -config <configFilename>";
/**
* Conversation ID.
*/
private int conversationId = 1;
private Log log = null;
private LogWriter logWriter = null;
private MonitorConfig monitorConfig = null;
/**
* Tool information.
*/
public static final String TOOL_NAME = "Monitor";
protected ToolInfo toolInfo = null;
protected Vector listenerList = new Vector();
protected MessageEntryQueue messageEntryQueue = null;
/**
* Message monitor.
* @param args command line arguments.
* @throws WSIException if there is a problem creating a Monitor object.
*/
public Monitor(String[] args) throws WSIException
{
// Create message list
this.messageList = new MessageList(RESOURCE_BUNDLE_NAME);
// Tool information
toolInfo = new ToolInfo(TOOL_NAME);
// Create document factory
DocumentFactory documentFactory = DocumentFactory.newInstance();
// Get new config object
monitorConfig = documentFactory.newMonitorConfig();
monitorConfig.init(this.messageList);
// Parse command line arguments
monitorConfig.parseArgs(args);
String logLocation = monitorConfig.getLogLocation();
if (logLocation.indexOf(WSIConstants.PATH_SEPARATOR) > -1)
{
throw new WSIException(
messageList.getMessage(
"config11",
monitorConfig.getLogLocation(),
"The log file location value cannot contain the pass separator character:"));
}
File file = null;
try
{
// Get file object for log file
file = new File(monitorConfig.getLogLocation());
}
catch (Exception e)
{
throw new WSIException(
messageList.getMessage("config07", "Could not get log file location."),
e);
}
// If replace flag is false and file exists, then throw exception
if (file.exists() && !monitorConfig.getReplaceLog())
{
throw new IllegalArgumentException(
messageList.getMessage(
"config08",
monitorConfig.getLogLocation(),
"Log file already exists:"));
}
try
{
// Create output file
log = documentFactory.newLog();
// Set style sheet string
log.setStyleSheetString(
monitorConfig.getAddStyleSheet().getStyleSheetString());
// Get log writer
logWriter = documentFactory.newLogWriter();
logWriter.setWriter(monitorConfig.getLogLocation());
// Write start of log file
logWriter.write(new StringReader(log.getStartXMLString("")));
// Write monitor tool information
logWriter.write(new StringReader(toXMLString("")));
// Create log entry queue
messageEntryQueue = new MessageEntryQueue(this, log, logWriter);
}
catch (Exception e)
{
throw new WSIException(
messageList.getMessage(
"error03",
"Could not create log or log writer."),
e);
}
// Get manInTheMiddle settings
ManInTheMiddle manInTheMiddle = monitorConfig.getManInTheMiddle();
// Get list of redirects
Iterator iterator = manInTheMiddle.getRedirectList().iterator();
// Process each redirect
Redirect redirect;
while (iterator.hasNext())
{
// Get next redirect
redirect = (Redirect) iterator.next();
// Create server socket socket listener
listenerList.add(new ServerSocketListener(this, redirect));
}
// Add shutdown hook
Runtime.getRuntime().addShutdownHook(new ShutdownHook());
// Create and start console
Console console = new Console();
console.start();
}
/**
* Get the monitor config file.
* @return the monitor config file.
*/
public MonitorConfig getMonitorConfig()
{
return monitorConfig;
}
/**
* Get the log object.
* @return the log object.
*/
public Log getLog()
{
return this.log;
}
/**
* Get the log entry queue object.
* @return the log entry queue object.
*/
public MessageEntryQueue getMessageEntryQueue()
{
return this.messageEntryQueue;
}
/**
* Terminate the monitor.
*/
void exitMonitor()
{
printMessage("stopping01", "Stopping the monitor...");
System.exit(0);
}
/**
* Stop the monitor because an exception occurred.
*/
void exitMonitor(Exception e)
{
// Display error message
printMessage(
"stopping02",
"Stopping monitor because an exception occurred.");
System.err.println("EXCEPTION: " + e.toString());
if (this.monitorConfig.getVerboseOption())
e.printStackTrace();
// Exit monitor
exitMonitor();
}
/**
* Stop the monitor.
*/
void stopMonitor()
{
try
{
// Get list of listeners to stop
Iterator iterator = listenerList.iterator();
while (iterator.hasNext())
{
((ServerSocketListener) iterator.next()).shutdown();
}
// Wait for the cleanup timeout seconds
Thread.sleep(monitorConfig.getTimeout() * 1000);
// Write end of log file
if (logWriter != null)
{
logWriter.write(new StringReader(log.getEndXMLString("")));
logWriter.close();
}
}
catch (Exception e)
{
// ADD: How should this execption be handled?
}
printMessage("stopped01", "Monitor stopped.");
}
/**
* Command line interface.
* @param args command line arguments.
*/
public static void main(String[] args)
{
Monitor monitor = null;
try
{
if (args.length < 2)
{
staticPrintMessage("usage01", USAGE_MESSAGE);
System.exit(1);
}
if (!args[0].equalsIgnoreCase("-config"))
{
staticPrintMessage("usage01", USAGE_MESSAGE);
System.exit(1);
}
// Run the monitor
monitor = new Monitor(args);
}
catch (Exception e)
{
boolean printStackTrace = true;
String messageID;
String defaultMessage;
String messageData;
if ((e instanceof WSIFileNotFoundException)
|| (e instanceof IllegalArgumentException))
{
printStackTrace = false;
messageID = "error01";
defaultMessage = "Monitor Error:";
messageData = e.getMessage();
}
else
{
printStackTrace = true;
messageID = "error02";
defaultMessage = "Monitor Stopped By Exception:";
messageData = e.toString();
}
if (monitor != null)
monitor.printMessage(messageID, messageData, defaultMessage);
else
Monitor.staticPrintMessage(messageID, messageData, defaultMessage);
if (printStackTrace)
e.printStackTrace();
// Exit
if (monitor != null)
monitor.exitMonitor();
else
System.exit(2);
}
}
/**
* Print a message from the resource bundle.
* @param key a key.
* @param defaultMessage a default message.
*/
public void printMessage(String key, String defaultMessage)
{
printMessage(key, null, defaultMessage);
}
/**
* Print a message from the resource bundle.
* @param key a key.
* @param messageData message data.
* @param defaultMessage a default message.
*/
public void printMessage(
String key,
String messageData,
String defaultMessage)
{
messageList.printMessage(key, messageData, defaultMessage);
}
/**
* Print message.
* @param key a key.
* @param defaultMessage a default message.
*/
public static void staticPrintMessage(String key, String defaultMessage)
{
staticPrintMessage(key, null, defaultMessage);
}
/**
* Print message.
* @param key a key.
* @param messageData message data.
* @param defaultMessage a default message.
*/
public static void staticPrintMessage(
String key,
String messageData,
String defaultMessage)
{
MessageList.printMessage(
RESOURCE_BUNDLE_NAME,
key,
messageData,
defaultMessage);
}
/**
* Get the next conversation identifier.
* @return the next conversation identifier.
*/
synchronized int getNextConversationId()
{
return conversationId++;
}
/**
* Return XML string representation of this object.
* @param namespaceName namespace prefix.
* @return XML string representation of this object.
*/
public String toXMLString(String namespaceName)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
// Start
pw.print(toolInfo.getStartXMLString(namespaceName));
// Config
pw.print(
monitorConfig.toXMLString(WSIConstants.NS_NAME_WSI_MONITOR_CONFIG));
// End
pw.println(toolInfo.getEndXMLString(namespaceName));
return sw.toString();
}
/**
* Shutdown hook.
*/
class ShutdownHook extends Thread
{
/**
* Run shutdown procedure.
*/
public void run()
{
stopMonitor();
}
}
/**
* Run command from console.
*/
class Console extends Thread
{
/**
* Prompt user and wait for input.
*/
public void run()
{
// Get the exit string
String exitString = messageList.getMessage("exit01", "exit");
// Display options and how to stop application
TestUtils.printToolInfo(toolInfo);
System.out.print(monitorConfig.toString());
System.out.println(" ");
printMessage(
"start01",
"The "
+ toolInfo.getName()
+ " tool is ready to intercept and log web service messages.");
printMessage(
"start02",
"Type \"exit\" to stop the " + toolInfo.getName() + ".");
System.out.println(" ");
// Get the time to stop accepting connections
long stopTime =
System.currentTimeMillis() + (monitorConfig.getLogDuration() * 1000);
// SS
try
{
// Get stdin as a buffered reader
BufferedReader reader =
new BufferedReader(new InputStreamReader(System.in));
// Process input from console
boolean exit = false;
while ((!exit) && (System.currentTimeMillis() < stopTime))
{ // SS
// Sleep
Thread.sleep(500);
// Check for user input
if (reader.ready())
{
if (reader.readLine().equalsIgnoreCase(exitString))
exit = true;
}
}
}
catch (Exception e)
{
// ADD: How should this be handled?
System.err.println(e.toString());
}
// Exit
exitMonitor();
}
}
}