package openjms.examples.nuix;
import java.util.HashMap;
import java.util.Map;
import java.util.Date;
import java.util.Properties;
import java.lang.reflect.Constructor;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.ObjectMessage;
import javax.jms.JMSException;
import javax.jms.QueueReceiver;
import javax.jms.Queue;
import javax.naming.NamingException;
import org.exolab.jms.util.CommandLine;
/**
*
*/
public class Worker extends BaseJmsSenderReceiver {
//////////////////////////////////////////////////////////////////////////////////////
// Constants
/**
* Constant for worker id settingin the configuration.
*/
public static final String WORKER_ID = "worker.id";
public static final String SPECIAL_WORKER = "special.worker";
public static final String SPECIAL_JNDI_HOST = "special.jndi.jms.host";
public static final String SPECIAL_JNDI_PORT = "special.jndi.jms.port";
public static final String SPECIAL_JNDI_NAME = "special.jndi.jms.name";
public static final String SPECIAL_JNDI_CONTEXT_FACTORY =
"special.jndi.jms.initialcontextfactory";
public static final String SPECIAL_QUEUE_NAME = "special.jms.queue.listen";
public static final String SPECIAL_WORKER_TIMEOUT = "special.jms.queue.timeout";
//////////////////////////////////////////////////////////////////////////////////////
// Fields
private int workerId = 0;
private boolean specialWorker = false;
private QueueReceiver specialReceiver;
private long specialReceiverTimeout = 0;
//////////////////////////////////////////////////////////////////////////////////////
// Mainline
public static void main(String[] args)
throws Exception {
CommandLine line = new CommandLine(args);
if (line.exists("props")) {
Properties props = new Properties(System.getProperties());
props.load(new BufferedInputStream(new FileInputStream(line.value("props"))));
System.setProperties(props);
Worker worker = new Worker();
//worker.waitForMessage();
} else {
System.err.println("No property file specified");
System.exit(0);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// Constructor
/**
* Construct the worker.
* @param configuration configuration of the worker.
*/
public Worker()
{
super();
try {
System.out.println("Initialising the Worker");
// Call super.init()! This is important step that cannot be overlooked.
super.init();
setupSpecialWorker(configuration);
}
// If failed while init then we need to shut down system, the server *must*
// run OK before anything else.
catch (Throwable e) {
System.err.println("Serious problem with worker, die");
e.printStackTrace();
System.exit(-1);
}
String sWorkerId = (String) configuration.getProperty(WORKER_ID);
workerId = Math.abs((new java.util.Random(System.currentTimeMillis())).nextInt());
}
//////////////////////////////////////////////////////////////////////////////////////
// Methods
/**
*
*/
public void waitForMessage()
{
while (true) {
if (specialWorker) {
specialWorkerWaitLogic();
} else {
normalWorkerWaitLogic();
}
}
}
private void normalWorkerWaitLogic()
{
Message message = null;
try {
message = receiver.receive();
onMessage(message);
} catch (JMSException e) {
System.err.println("Error while waiting for messages");
e.printStackTrace();
System.exit(-1);
}
}
private void specialWorkerWaitLogic()
{
Message message = null;
try {
// First wait in the special queue until it receives a message
// or times out
message = specialReceiver.receive(specialReceiverTimeout);
if (message != null) {
onMessage(message);
} else {
// Wait in the normal queue, but still use the timeout, because
// we don't want to wait forever in this normal queue in case
// there is a SME in the special queue.
message = receiver.receive(specialReceiverTimeout);
if (message != null) {
onMessage(message);
}
// if message null then just loop back.
}
} catch (JMSException e) {
System.err.println("Error while waiting for messages");
e.printStackTrace();
System.exit(-1);
}
}
/**
*
* @param configuration
* @throws NamingException
* @throws JMSException
*/
private void setupSpecialWorker(Properties configuration)
throws NamingException, JMSException
{
// Special worker configuration
String sSpecialWorker = (String) configuration.getProperty(SPECIAL_WORKER);
if (sSpecialWorker != null && sSpecialWorker.equalsIgnoreCase(TRUE)) {
// Set specialWorker flag to true
specialWorker = true;
// Set up the special receiver
String queueName = (String)
configuration.getProperty(SPECIAL_QUEUE_NAME);
Queue queue = (Queue) getContext().lookup(queueName);
specialReceiver = session.createReceiver(queue);
// Special worker will be run as receive()! so do NOT make this
// worker as listener to the specialReceiver.
String sTimeout = (String)
configuration.getProperty(SPECIAL_WORKER_TIMEOUT);
if (sTimeout != null) {
try {
specialReceiverTimeout = Long.parseLong(sTimeout);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Badly formed special receiver " +
"timeout: " + sTimeout);
}
}
} else {
specialWorker = false;
}
}
public void onMessage(Message message)
{
//SoundSystem.play(SoundSystem.START, 1);
System.out.println("Receive message");
// Only handle object messages. Warn if otherwise.
if (message instanceof ObjectMessage) {
handleObjectMessage((ObjectMessage) message);
}
try {
System.err.println("Committing the session");
session.commit();
} catch (Exception exception) {
exception.printStackTrace();
}
System.out.println("Finised processing message");
//SoundSystem.play(SoundSystem.END, 1);
}
/**
* Handle object message.
* If the worker itself throws an exception, then this worker is considered
* in serious problem and stop executing, thus the System.exit(-1) if it catches
* an exception.
* @param objectMessage the object message.
*/
private void handleObjectMessage(ObjectMessage objectMessage) {
try {
System.out.println("Received message " + objectMessage.getJMSMessageID());
}
// If we have problem here we are deep in trouble, stop the worker system, the
// message will be delivered to another worker.
catch (Throwable e) {
System.err.println("Got exception in worker: " + e.getMessage());
e.printStackTrace();
System.exit(-1);
} finally {
try {
sendMessage((java.io.Serializable)objectMessage.getObject());
if (ack == Session.CLIENT_ACKNOWLEDGE) {
System.err.println("Acking message using client_ack");
objectMessage.acknowledge();
}
}
// can't do clean up, something is really wrong here.
catch (Throwable e) {
System.err.println("Got exception in worker: " + e.getMessage());
e.printStackTrace();
System.exit(-1);
}
}
}
/**
* Exit this JMS sender and receiver gracefully.
*/
protected void exit()
{
super.exit();
System.exit(0);
}
}