package org.obe.util;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.obe.client.api.ClientConfig;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.io.*;
import java.util.*;
public class JMSClient implements MessageListener {
private static final String JMS_QUEUE_CON_FACTORY =
ClientConfig.getJMSQueueConnectionFactory();
private static final String JMS_TOPIC_CON_FACTORY =
ClientConfig.getJMSTopicConnectionFactory();
private static final String NEWLINE = System.getProperty("line.separator");
private static final int TEXT_TYPE = 0;
private static final int OBJECT_TYPE = 1;
private static final int BYTES_TYPE = 2;
private static final int MAP_TYPE = 3;
private static final int BUF_SIZE = 4096;
public static void main(String[] args) {
try {
CommandLine cl = parseArgs(args);
args = cl.getArgs();
String action = args[0];
String destination = args[1];
String hostURL = args.length == 3 ? args[2]
: ClientConfig.getServerHostURL();
JMSClient jmstest = new JMSClient();
if (action.equalsIgnoreCase("publish") ||
action.equalsIgnoreCase("send")) {
String s;
int msgType = TEXT_TYPE;
if ((s = cl.getOptionValue('t')) != null) {
if (s.equalsIgnoreCase("text")) {
msgType = TEXT_TYPE;
} else if (s.equalsIgnoreCase("object")) {
msgType = OBJECT_TYPE;
} else if (s.equalsIgnoreCase("bytes")) {
msgType = BYTES_TYPE;
} else if (s.equalsIgnoreCase("map")) {
msgType = MAP_TYPE;
} else {
throw new IllegalArgumentException(
"invalid message type");
}
}
Object content = null;
if ((s = cl.getOptionValue('f')) != null) {
FileInputStream in = new FileInputStream(s);
switch (msgType) {
case TEXT_TYPE:
content = readText(in);
break;
case OBJECT_TYPE:
content = readObject(in);
break;
case BYTES_TYPE:
content = readBytes(in);
break;
case MAP_TYPE:
content = readProperties(in);
break;
}
}
Properties props = null;
if ((s = cl.getOptionValue('p')) != null) {
FileInputStream in = new FileInputStream(s);
props = readProperties(in);
}
if (action.equalsIgnoreCase("send"))
jmstest.send(hostURL, destination, content, msgType, props);
else if (action.equalsIgnoreCase("publish"))
jmstest.publish(hostURL, destination, content, msgType,
props);
} else if (action.equalsIgnoreCase("subscribe")) {
jmstest.subscribe(hostURL, destination);
} else if (action.equalsIgnoreCase("receive")) {
jmstest.receive(hostURL, destination);
} else {
usage();
}
} catch (Exception e) {
e.printStackTrace();
System.exit(2);
}
}
private static String readText(InputStream in) throws IOException {
try {
// N.B. This technique assumes the default charset. It may not work
// correctly with, for example, XML files that declare (and actually
// use) a different encoding.
Reader rdr = new InputStreamReader(in);
StringWriter out = new StringWriter();
char[] buf = new char[BUF_SIZE];
int i;
while ((i = rdr.read(buf)) > 0)
out.write(buf, 0, i);
out.close();
return out.toString();
} finally {
in.close();
}
}
private static byte[] readBytes(InputStream in) throws IOException {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[BUF_SIZE];
int i;
while ((i = in.read(buf)) > 0)
out.write(buf, 0, i);
out.close();
return out.toByteArray();
} finally {
in.close();
}
}
private static Properties readProperties(InputStream in)
throws IOException {
try {
Properties props = new Properties();
props.load(in);
return props;
} finally {
in.close();
}
}
private static Object readObject(InputStream in)
throws IOException, ClassNotFoundException {
try {
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject();
ois.close();
return obj;
} finally {
in.close();
}
}
private static CommandLine parseArgs(String[] args) {
CommandLine cl = null;
try {
BasicParser parser = new BasicParser();
Options options = new Options();
options.addOption("f", true, "message file");
options.addOption("t", true, "message type: text|object|bytes|map");
options.addOption("p", true, "message properties file");
cl = parser.parse(options, args, true);
int argc = cl.getArgs().length;
if (argc < 2 || argc > 3)
usage();
} catch (ParseException e) {
usage();
}
return cl;
}
private static void usage() {
System.out.println(
"usage: org.obe.util.JMSClient [-f <msg-file>] [-t <msg-type>] [-p <props-file>] <action> <destination> [<host-url>]");
System.out.println(" send/publish only:");
System.out
.println(" msg-file ::= file from which to read the message");
System.out.println(" msg-type ::= text | object | bytes | map");
System.out.println(" props-file ::= message properties file");
System.out.println();
System.out.println(" action ::= send|receive | publish|subscribe");
System.out.println(" destination ::= queue-name | topic-name");
System.out.println(
" (Specify JMS connection factory JNDI names in obe.properties)");
System.exit(1);
}
private static Message createMessage(int msgType, Session session,
Object content,
Map properties) throws JMSException {
Message msg = null;
switch (msgType) {
case TEXT_TYPE:
msg = session.createTextMessage((String)content);
break;
case OBJECT_TYPE:
msg = session.createObjectMessage((Serializable)content);
break;
case BYTES_TYPE:
BytesMessage bytesMsg = session.createBytesMessage();
bytesMsg.writeBytes((byte[])content);
msg = bytesMsg;
break;
case MAP_TYPE:
MapMessage mapMsg = session.createMapMessage();
for (Iterator i = ((Map)content).entrySet().iterator();
i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
mapMsg.setObject((String)entry.getKey(),
entry.getValue());
}
msg = mapMsg;
break;
}
if (properties != null) {
for (Iterator iter = properties.entrySet().iterator();
iter.hasNext();) {
Map.Entry entry = (Map.Entry)iter.next();
msg.setObjectProperty((String)entry.getKey(), entry.getValue());
}
}
return msg;
}
private static void publish(String url, String destJndiName, Object content,
int msgType, Map properties) throws NamingException, JMSException,
IOException {
Context ctx = getInitialContext(url);
TopicConnectionFactory tcf = (TopicConnectionFactory)
ctx.lookup(JMS_TOPIC_CON_FACTORY);
Topic topic = (Topic)ctx.lookup(destJndiName);
ctx.close();
TopicConnection tcon = tcf.createTopicConnection();
TopicSession tsession = tcon.createTopicSession(false, 1);
TopicPublisher tpub = tsession.createPublisher(topic);
if (content != null) {
Message msg = createMessage(msgType, tsession, content, properties);
System.out.println("Publishing message");
tpub.publish(msg);
} else {
TextMessage msg = tsession.createTextMessage();
System.out.println("Publishing to JMS Topic: " + topic);
System.out.println(
"Enter text<\\n><\\n> to publish message, or ! to terminate");
System.out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
StringBuffer sb = new StringBuffer();
String line;
while (!"!".equals(line = in.readLine())) {
if (line != null && line.length() != 0) {
sb.append(line);
sb.append(NEWLINE);
} else {
if (sb.length() > 0) {
String msgText = sb.toString();
System.out.println("Publishing message:");
System.out.println(msgText);
msg.setText(msgText);
tpub.publish(msg);
sb.setLength(0);
}
// If we've reached the end of input, get out of the loop.
if (line == null)
break;
}
}
}
tpub.close();
tsession.close();
tcon.stop();
tcon.close();
}
private static void send(String url, String destJndiName, Object content,
int msgType, Map properties)
throws NamingException, JMSException, IOException {
Context ctx = getInitialContext(url);
QueueConnectionFactory tcf = (QueueConnectionFactory)
ctx.lookup(JMS_QUEUE_CON_FACTORY);
Queue queue = (Queue)ctx.lookup(destJndiName);
ctx.close();
QueueConnection qcon = tcf.createQueueConnection();
QueueSession qsession = qcon.createQueueSession(false, 1);
QueueSender qsend = qsession.createSender(queue);
if (content != null) {
Message msg = createMessage(msgType, qsession, content, properties);
System.out.println("Sending message");
qsend.send(msg);
} else {
TextMessage msg = qsession.createTextMessage();
System.out.println("Sending to JMS Queue: " + queue);
System.out.println(
"Enter text<\\n><\\n> to send message, or ! to terminate");
System.out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
StringBuffer sb = new StringBuffer();
String line;
while (!"!".equals(line = in.readLine())) {
if (line != null && line.length() != 0) {
sb.append(line);
sb.append(NEWLINE);
} else {
if (sb.length() > 0) {
String msgText = sb.toString();
System.out.println("Sending message:");
System.out.println(msgText);
msg.setText(msgText);
qsend.send(msg);
sb.setLength(0);
}
// If we've reached the end of input, get out of the loop.
if (line == null)
break;
}
}
}
qsend.close();
qsession.close();
qcon.stop();
qcon.close();
}
private static Context getInitialContext(String s) throws NamingException {
Hashtable hashtable = new Hashtable();
hashtable.put(Context.PROVIDER_URL, s);
return new InitialContext(hashtable);
}
private JMSClient() {
}
private void subscribe(String url, String destJndiName)
throws NamingException, JMSException, IOException {
Context ctx = getInitialContext(url);
TopicConnectionFactory tcf = (TopicConnectionFactory)
ctx.lookup(JMS_TOPIC_CON_FACTORY);
Topic topic = (Topic)ctx.lookup(destJndiName);
ctx.close();
TopicConnection tcon = tcf.createTopicConnection();
TopicSession tsession = tcon.createTopicSession(false, 1);
TopicSubscriber tsub = tsession.createSubscriber(topic);
tsub.setMessageListener(this);
tcon.start();
System.out.println("Subscribed to JMS Topic: " + topic);
System.out.println("Press any key to terminate");
System.in.read();
tsession.close();
tcon.stop();
tcon.close();
}
private void receive(String url, String destJndiName)
throws NamingException, JMSException, IOException {
Context ctx = getInitialContext(url);
QueueConnectionFactory qcf = (QueueConnectionFactory)
ctx.lookup(JMS_QUEUE_CON_FACTORY);
Queue queue = (Queue)ctx.lookup(destJndiName);
ctx.close();
QueueConnection qcon = qcf.createQueueConnection();
QueueSession qsession = qcon.createQueueSession(false, 1);
QueueReceiver qrcvr = qsession.createReceiver(queue);
qrcvr.setMessageListener(this);
qcon.start();
System.out.println("Receiving from JMS Queue: " + queue);
System.out.println("Press any key to terminate");
System.in.read();
qsession.close();
qcon.stop();
qcon.close();
}
public void onMessage(Message msg) {
try {
String s = msg instanceof TextMessage
? ((TextMessage)msg).getText() : msg.toString();
String s1 = msg.getClass().getName();
s1 = s1.substring(s1.lastIndexOf('.') + 1);
System.out.println("Received " + s1);
Enumeration enumeration = msg.getPropertyNames();
if (enumeration.hasMoreElements()) {
System.out.println("Message header: ");
while (enumeration.hasMoreElements()) {
String s2 = (String)enumeration.nextElement();
System.out.println('\t' + s2 + '=' +
msg.getObjectProperty(s2));
}
}
System.out.println("Message body: " + s);
System.out.println("----------------------------------------");
} catch (JMSException e) {
e.printStackTrace();
}
}
}
|