001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2002 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "WSIF" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 2001, 2002, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.wsif.util.jms;
059:
060: import inout.wsiftypes.InoutImpl;
061: import inout.wsiftypes.Mutablestring;
062: import java.io.BufferedReader;
063: import java.io.FileReader;
064: import java.io.IOException;
065: import java.io.Serializable;
066: import java.util.Date;
067: import java.util.Enumeration;
068: import java.util.HashMap;
069:
070: import javax.jms.JMSException;
071: import javax.jms.Message;
072: import javax.jms.ObjectMessage;
073: import javax.jms.Queue;
074: import javax.jms.QueueReceiver;
075: import javax.jms.TextMessage;
076:
077: import org.apache.wsif.WSIFConstants;
078: import org.apache.wsif.WSIFException;
079: import org.apache.wsif.logging.Trc;
080: import stockquote.wsiftypes.StockQuote;
081: import util.TestUtilities;
082:
083: import addressbook.wsiftypes.Address;
084: import addressbook.wsiftypes.AddressBook;
085:
086: /**
087: * Used to simulate the remote service for native JMS requests.
088: */
089: public class NativeJMSRequestListener extends JMS2HTTPBridgeDestination {
090: int counter = 0;
091: static final String startType = JMS2HTTPBridgeDestination.COLDSTART;
092: static final boolean VERBOSE = TestUtilities.isJmsVerbose();
093:
094: private Thread listenerThread;
095:
096: static AddressBook ab = new AddressBook();
097: static StockQuote sq = new StockQuote();
098: static InoutImpl inout = new InoutImpl();
099:
100: static final Object LOCK = new Lock();
101:
102: static class Lock {
103: }
104:
105: private WSIFJMSListener list = new WSIFJMSListener() {
106: public void onException(JMSException arg1) {
107: Trc.entry(this , arg1);
108: arg1.printStackTrace();
109: Trc.exit();
110: }
111:
112: public void onMessage(Message message) {
113: try {
114: Trc.entry(this , message);
115: synchronized (getLock()) {
116: processResponse(message);
117: }
118: Trc.exit();
119: } catch (Exception ex) {
120: ex.printStackTrace();
121: }
122: }
123: };
124:
125: public NativeJMSRequestListener(String msgQ) throws WSIFException {
126: super (
127: new WSIFJMSFinderForJndi(
128: null,
129: TestUtilities
130: .getWsifProperty("wsif.jms2httpbridge.initialcontextfactory"),
131: TestUtilities
132: .getWsifProperty("wsif.jms2httpbridge.jndiproviderurl"),
133: WSIFJMSFinder.STYLE_QUEUE,
134: TestUtilities
135: .getWsifProperty("wsif.jms2httpbridge.jndiconnectionfactoryname"),
136: msgQ, null), null,
137: WSIFJMSConstants.WAIT_FOREVER, startType, VERBOSE);
138:
139: listenerThread = new Thread() {
140: public void run() {
141: try {
142: listen(list);
143: } catch (WSIFException ex) {
144: ex.printStackTrace();
145: }
146: }
147: };
148: listenerThread.start();
149: }
150:
151: /**
152: * Create a listener thread to listen for messages. This waits forever
153: * until it gets an InterruptedException.
154: * @param listener is the JMS message and exception callback interface implementation
155: * @param queue to listen on
156: */
157: public void listen(WSIFJMSListener listener, Queue queue)
158: throws WSIFException {
159: Trc.entry(this , listener, queue);
160: areWeClosed();
161:
162: try {
163: QueueReceiver qr = session.createReceiver(queue);
164: qr.setMessageListener(listener);
165: connection.setExceptionListener(listener);
166:
167: connection.start();
168:
169: for (int i = 1; !Thread.interrupted(); i++) {
170: Thread.yield();
171: Thread.sleep(5000);
172: if (VERBOSE)
173: System.out.println("JMSAsyncListener waiting... "
174: + i);
175: }
176: } catch (JMSException je) {
177: je.printStackTrace();
178: throw new WSIFException(je.getMessage());
179: } catch (InterruptedException ignored) {
180: if (VERBOSE)
181: System.out.println("JMSAsyncListener Exitting");
182: }
183: Trc.exit();
184: }
185:
186: public void stop() {
187: listenerThread.interrupt();
188: }
189:
190: private void processResponse(Message msg) {
191: if (VERBOSE)
192: System.out.println("NativeJMSRequestListener got msg:"
193: + msg);
194: try {
195: String operationName = null;
196: String input = null;
197: String output = null;
198: String fake = null;
199: try {
200: operationName = msg
201: .getStringProperty(WSIFConstants.JMS_PROP_OPERATION_NAME);
202: input = msg
203: .getStringProperty(WSIFConstants.JMS_PROP_INPUT_NAME);
204: output = msg
205: .getStringProperty(WSIFConstants.JMS_PROP_OUTPUT_NAME);
206: fake = msg.getStringProperty("WSIF_FAKE");
207: } catch (javax.jms.JMSException e) {
208: }
209:
210: Object reply = null;
211: Object dummyReply = "input only, so no reply";
212: if (fake != null) {
213: sendReply(msg, doFakeOp(fake));
214: } else if ("getQuote".equals(operationName)) {
215: reply = new Float(sqGetQuote((ObjectMessage) msg));
216: sendReply(msg, reply);
217: } else if ("AddEntryFirstAndLastNamesRequest".equals(input)) {
218: abAddEntryFL((ObjectMessage) msg);
219: sendReply(msg, dummyReply); //TODO jms test needs this???
220: } else if ("addEntry".equals(operationName)) {
221: abAddEntry((ObjectMessage) msg);
222: sendReply(msg, dummyReply); //TODO jms test needs this???
223: } else if ("addEntryWholeName".equals(operationName)) {
224: abAddEntry((ObjectMessage) msg);
225: sendReply(msg, dummyReply); //TODO jms test needs this???
226: } else if ("addEntryUserProp".equals(operationName)) {
227: abAddEntry((ObjectMessage) msg);
228: sendReply(msg, dummyReply); //TODO jms test needs this???
229: } else if ("addEntryJmsProp".equals(operationName)) {
230: abAddEntry((ObjectMessage) msg);
231: sendReply(msg, dummyReply); //TODO jms test needs this???
232: } else if ("addEntryFirstAndLastNames"
233: .equals(operationName)) {
234: abAddEntryFL((ObjectMessage) msg);
235: sendReply(msg, dummyReply); //TODO jms test needs this???
236: } else if ("GetAddressFromNameMSRequest".equals(input)) {
237: reply = inoutGetAddressFromName((ObjectMessage) msg);
238: sendReply(msg, reply);
239: } else if ("getAddressFromName".equals(operationName)) {
240: reply = abGetAddressFromName((ObjectMessage) msg);
241: sendReply(msg, reply);
242: } else if ("getAddressFromName".equals(operationName)) {
243: reply = abGetAddressFromName((ObjectMessage) msg);
244: sendReply(msg, reply);
245: } else if ("getAddressFromNameMS".equals(operationName)) {
246: reply = inoutGetAddressFromName((ObjectMessage) msg);
247: sendReply(msg, reply);
248: } else if ("addNumbers".equals(operationName)) {
249: reply = inoutAddNumbers((ObjectMessage) msg);
250: sendReply(msg, reply);
251: } else if ("getDate".equals(operationName)) {
252: reply = inoutGetDate((ObjectMessage) msg);
253: sendReply(msg, reply);
254: } else if ("whoamiString".equals(operationName)) {
255: reply = inoutWhoami((ObjectMessage) msg);
256: sendReply(msg, reply);
257: } else if ("whoamiFloat".equals(operationName)) {
258: reply = inoutWhoami((ObjectMessage) msg);
259: sendReply(msg, reply);
260: } else if ("whoamiInt".equals(operationName)) {
261: reply = inoutWhoami((ObjectMessage) msg);
262: sendReply(msg, reply);
263: } else if ("whoamiAddress".equals(operationName)) {
264: reply = inoutWhoami((ObjectMessage) msg);
265: sendReply(msg, reply);
266: } else if ("inoutArgs".equals(operationName)) {
267: reply = inoutArgs((ObjectMessage) msg);
268: sendReply(msg, reply);
269: } else if ("whoami".equals(operationName)) {
270: reply = inoutWhoami((ObjectMessage) msg);
271: sendReply(msg, reply);
272: } else if (operationName.startsWith("throw")) {
273: throwFault(operationName, (ObjectMessage) msg);
274: } else {
275: System.err.println("unknown operation: "
276: + operationName);
277: }
278: } catch (Exception ex) {
279: ex.printStackTrace();
280: }
281: }
282:
283: private void abAddEntry(ObjectMessage msg) throws JMSException {
284: HashMap hm = (HashMap) msg.getObject();
285: String name = (String) hm.get("name");
286: Address addr = (Address) hm.get("address");
287: ab.addEntry(name, addr);
288: inout.addEntry(name, addr);
289: }
290:
291: private void abAddEntryFL(ObjectMessage msg) throws JMSException {
292: HashMap hm = (HashMap) msg.getObject();
293: String first = (String) hm.get("firstName");
294: String last = (String) hm.get("lastName");
295: Address addr = (Address) hm.get("address");
296: ab.addEntry(first, last, addr);
297: inout.addEntry(first, last, addr);
298: }
299:
300: private Address abGetAddressFromName(ObjectMessage msg)
301: throws JMSException {
302: String name = (String) msg.getObject();
303: return ab.getAddressFromName(name);
304: }
305:
306: private float sqGetQuote(ObjectMessage msg) throws Exception {
307: String name = (String) msg.getObject();
308: return sq.getQuote(name);
309: }
310:
311: private Address inoutGetAddressFromName(ObjectMessage msg)
312: throws JMSException {
313: Mutablestring name = (Mutablestring) msg.getObject();
314: return inout.getAddressFromName(name);
315: }
316:
317: private Date inoutGetDate(ObjectMessage msg) throws JMSException {
318: return inout.getDate();
319: }
320:
321: private String inoutWhoami(ObjectMessage msg) throws JMSException {
322: Object o = null;
323: o = msg.getObject();
324: if (o instanceof String) {
325: return inout.whoami((String) o);
326: }
327: o = msg.getObject();
328: if (o instanceof Address) {
329: return inout.whoami((Address) o);
330: }
331: o = msg.getObject();
332: if (o instanceof Integer) {
333: return inout.whoami(((Integer) o).intValue());
334: }
335: o = msg.getObject();
336: if (o instanceof Float) {
337: return inout.whoami(((Float) o).floatValue());
338: }
339: return "errror - unknown obj";
340: }
341:
342: private Integer inoutAddNumbers(ObjectMessage msg)
343: throws JMSException {
344: int[] nums = (int[]) msg.getObject();
345: return new Integer(inout.addNumbers(nums));
346: }
347:
348: private HashMap inoutArgs(ObjectMessage msg) throws JMSException {
349: HashMap hm = (HashMap) msg.getObject();
350: Mutablestring ms1 = (Mutablestring) hm.get("ms1");
351: Mutablestring ms2 = (Mutablestring) hm.get("ms2");
352: // String s = inout.inoutArgs( ms1, ms2 ); TODO ???what happened?
353: HashMap hmr = new HashMap();
354: // hmr.put( "reply", s );
355: hmr.put("ms2", ms2);
356: return hmr;
357: }
358:
359: private void throwFault(String operationName, ObjectMessage msg)
360: throws Exception {
361:
362: Queue replyTo = (Queue) (msg.getJMSReplyTo());
363: if (replyTo == null)
364: return;
365:
366: ObjectMessage faultMsg = (ObjectMessage) session
367: .createObjectMessage();
368: int choice = ((Integer) msg.getObject()).intValue();
369: System.out
370: .println("NativeJMSRequestListener throwSimple choice="
371: + choice);
372: switch (choice) {
373: case 0:
374: break;
375: case 1:
376: faultMsg.setStringProperty("faultIndicator", "simple");
377: faultMsg.setObject((Serializable) "A Simple Fault");
378: break;
379: case 2:
380: case 3:
381: faultMsg.setStringProperty("faultIndicator",
382: choice == 2 ? "ints" : "twoints");
383: HashMap hm = new HashMap();
384: hm.put("faultInt1", new Integer(1));
385: hm.put("faultInt2", new Integer(2));
386: hm.put("faultInt3", new Integer(3));
387: faultMsg.setObject((Serializable) hm);
388: break;
389: case 4:
390: faultMsg.setIntProperty("faultIndicator", 43);
391: faultMsg.setObject((Serializable) "A Simple Fault");
392: break;
393: case 5:
394: faultMsg.setStringProperty("faultIndicator", "not a fault");
395: faultMsg.setObject((Serializable) "Not a Fault");
396: break;
397: case 6:
398: faultMsg.setByteProperty("faultIndicator", (byte) -1);
399: faultMsg.setObject((Serializable) "A Fault Indicator");
400: break;
401: case 7:
402: faultMsg.setByteProperty("faultIndicator", (byte) -2);
403: faultMsg.setObject((Serializable) "Another Property Fault");
404: faultMsg.setStringProperty("anotherProperty",
405: "Another JMS Property");
406: break;
407: case 8:
408: faultMsg.setByteProperty("faultIndicator", (byte) -3);
409: break;
410: case 9:
411: faultMsg.setByteProperty("faultIndicator", (byte) -4);
412: faultMsg.setStringProperty("anotherProperty",
413: "Another JMS Property");
414: break;
415: case 10:
416: faultMsg.setByteProperty("faultIndicator", (byte) -5);
417: break;
418: default:
419: throw new RuntimeException("throwSimple: Bad choice");
420: }
421:
422: setReplyToQueue(replyTo);
423: String o = msg.getJMSMessageID();
424: try {
425: send(faultMsg, o, false);
426: } catch (Exception ex) {
427: ex.printStackTrace();
428: }
429: }
430:
431: private String doFakeOp(String fake) {
432: fake = fake.substring(1); // remove leading quote
433: fake = fake.substring(0, fake.length() - 1); // remove trailing quote
434: return getFakeReply(fake);
435: }
436:
437: private String getFakeReply(String name) {
438: String s;
439: StringBuffer sb = new StringBuffer();
440: try {
441: BufferedReader in = new BufferedReader(new FileReader(name));
442: while ((s = in.readLine()) != null) {
443: sb.append(s);
444: }
445: in.close();
446: } catch (IOException ex) {
447: ex.printStackTrace();
448: }
449: return sb.toString();
450: }
451:
452: private void sendReply(Message msg, Object response)
453: throws Exception {
454: Queue replyTo = (Queue) (msg.getJMSReplyTo());
455: if (replyTo == null)
456: return;
457:
458: Message replyMsg = session.createObjectMessage();
459: ((ObjectMessage) replyMsg).setObject((Serializable) response);
460:
461: setEchoProperties(msg, replyMsg);
462:
463: setReplyToQueue(replyTo);
464: String o = msg.getJMSMessageID();
465: try {
466: send(replyMsg, o, false);
467: } catch (Exception ex) {
468: ex.printStackTrace();
469: }
470: }
471:
472: private void sendReply(Message msg, String response)
473: throws Exception {
474: Queue replyTo = (Queue) (msg.getJMSReplyTo());
475: if (replyTo == null)
476: return;
477:
478: Message replyMsg = session.createTextMessage();
479: ((TextMessage) replyMsg).setText(response);
480:
481: setEchoProperties(msg, replyMsg);
482:
483: setReplyToQueue(replyTo);
484: String o = msg.getJMSMessageID();
485: try {
486: send(replyMsg, o, false);
487: } catch (Exception ex) {
488: ex.printStackTrace();
489: }
490: }
491:
492: private void setEchoProperties(Message inMsg, Message outMsg) {
493: try {
494: for (Enumeration en = inMsg.getPropertyNames(); en
495: .hasMoreElements();) {
496: String propName = (String) en.nextElement();
497: if (propName.startsWith("Echo")) {
498: String key = propName;
499: Object propValue = inMsg
500: .getObjectProperty(propName);
501: outMsg.setObjectProperty(key, propValue);
502: }
503: }
504: } catch (JMSException ex) {
505: ex.printStackTrace();
506: }
507: }
508:
509: /**
510: * this is needed as the native JMS inputonly method really is inputonly
511: * so doesn't wait for a response. Therefore the next request, such as an
512: * addressbook lookup may run before the previous add has completed.
513: */
514: public final Object getLock() {
515: return LOCK;
516: }
517:
518: }
|