1 /*------------------------------------------------------------------------------
2 Name: TestUpdateClientException.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 ------------------------------------------------------------------------------*/
6 package org.xmlBlaster.test.qos;
7
8 import java.util.logging.Logger;
9
10 import junit.framework.Test;
11 import junit.framework.TestCase;
12 import junit.framework.TestSuite;
13
14 import org.xmlBlaster.client.I_Callback;
15 import org.xmlBlaster.client.I_XmlBlasterAccess;
16 import org.xmlBlaster.client.key.UpdateKey;
17 import org.xmlBlaster.client.qos.ConnectQos;
18 import org.xmlBlaster.client.qos.EraseReturnQos;
19 import org.xmlBlaster.client.qos.SubscribeQos;
20 import org.xmlBlaster.client.qos.UpdateQos;
21 import org.xmlBlaster.test.Util;
22 import org.xmlBlaster.util.EmbeddedXmlBlaster;
23 import org.xmlBlaster.util.Global;
24 import org.xmlBlaster.util.MsgUnit;
25 import org.xmlBlaster.util.XmlBlasterException;
26 import org.xmlBlaster.util.def.Constants;
27 import org.xmlBlaster.util.def.ErrorCode;
28
29
30 /**
31 * This client does test exceptions thrown in the update() method on client side.<br />
32 * <p />
33 * XmlBlaster should only accept exceptions of type ErrorCode.USER_UPDATE* and send the lost messages
34 * as 'dead messages' and proceed.
35 * <p>
36 * Invoke examples:<br />
37 * <pre>
38 * java junit.textui.TestRunner -noloading org.xmlBlaster.test.qos.TestUpdateClientException
39 * java junit.swingui.TestRunner -noloading org.xmlBlaster.test.qos.TestUpdateClientException
40 * </pre>
41 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/interface.update.html">The interface.update requirement</a>
42 */
43 public class TestUpdateClientException extends TestCase implements I_Callback
44 {
45 private static String ME = "TestUpdateClientException";
46 private final Global glob;
47 private static Logger log = Logger.getLogger(TestUpdateClientException.class.getName());
48
49 private I_XmlBlasterAccess con = null;
50 private String name;
51 private String passwd = "secret";
52 private int numReceived = 0; // error checking
53 private String updateOid;
54 private EmbeddedXmlBlaster serverThread;
55 private int serverPort = 7624;
56 private int filterMessageContentBiggerAs = 10;
57 private String msgOidWantException = "msgWantsUpdateException";
58 private String msgOidWantIllegalException = "msgWantsIllegalUpdateException";
59 private String msgOidWantNPE = "msgWantsNullPointerException";
60 private String msgOidNormal = "msgWantsNoUpdateException";
61
62 /**
63 * Constructs the TestUpdateClientException object.
64 * <p />
65 * @param testName The name used in the test suite
66 * @param name The name to login to the xmlBlaster
67 */
68 public TestUpdateClientException(Global glob, String testName, String name)
69 {
70 super(testName);
71 this.glob = glob;
72
73 this.name = name;
74 }
75
76 /**
77 * Sets up the fixture.
78 * <p />
79 * We start an own xmlBlaster server in a separate thread,
80 * it has configured to load our simple demo MIME filter plugin.
81 * <p />
82 * Then we connect as a client
83 */
84 protected void setUp()
85 {
86 // We register here the demo plugin with xmlBlaster server, supplying an argument to the plugin
87 String[] args = {
88 "-bootstrapPort", // For all protocol we may use set an alternate server port
89 "" + serverPort,
90 "-plugin/socket/port",
91 "" + (serverPort-1),
92 "-plugin/rmi/registryPort",
93 "" + (serverPort-2),
94 "-plugin/xmlrpc/port",
95 "" + (serverPort-3),
96 "-MimeAccessPlugin[ContentLenFilter][1.0]",
97 "org.xmlBlaster.engine.qos.demo.ContentLenFilter,DEFAULT_MAX_LEN=200,THROW_EXCEPTION_FOR_LEN=3",
98 "-admin.remoteconsole.port",
99 "0"};
100 glob.init(args);
101
102 serverThread = EmbeddedXmlBlaster.startXmlBlaster(args);
103 log.info("XmlBlaster is ready for testing subscribe MIME filter");
104
105 try {
106 log.info("Connecting ...");
107 con = glob.getXmlBlasterAccess();
108 ConnectQos qos = new ConnectQos(glob, name, passwd);
109 con.connect(qos, this); // Login to xmlBlaster
110 }
111 catch (Exception e) {
112 Thread.currentThread().dumpStack();
113 log.severe("Can't connect to xmlBlaster: " + e.toString());
114 }
115
116 // Subscribe to a message with a supplied filter
117 try {
118 SubscribeQos qos = new SubscribeQos(glob);
119
120 String subscriptionId = con.subscribe("<key oid='" + msgOidWantException + "'/>", qos.toXml()).getSubscriptionId();
121 log.info("Success: Subscribe subscription-id=" + subscriptionId + " on oid=" + msgOidWantException + " done");
122
123 subscriptionId = con.subscribe("<key oid='" + msgOidWantIllegalException + "'/>", qos.toXml()).getSubscriptionId();
124 log.info("Success: Subscribe subscription-id=" + subscriptionId + " on oid=" + msgOidWantIllegalException + " done");
125
126 subscriptionId = con.subscribe("<key oid='" + msgOidWantNPE + "'/>", qos.toXml()).getSubscriptionId();
127 log.info("Success: Subscribe subscription-id=" + subscriptionId + " on oid=" + msgOidWantNPE + " done");
128
129 subscriptionId = con.subscribe("<key oid='" + msgOidNormal + "'/>", qos.toXml()).getSubscriptionId();
130 log.info("Success: Subscribe subscription-id=" + subscriptionId + " on oid=" + msgOidNormal + " done");
131
132 subscriptionId = con.subscribe("<key oid='" + Constants.OID_DEAD_LETTER + "'/>", "<qos/>").getSubscriptionId();
133 log.info("Success: Subscribe subscription-id=" + subscriptionId + " on oid=" + Constants.OID_DEAD_LETTER + " done");
134
135 } catch(XmlBlasterException e) {
136 log.warning("XmlBlasterException: " + e.getMessage());
137 assertTrue("subscribe - XmlBlasterException: " + e.getMessage(), false);
138 }
139 }
140
141 /**
142 * Tears down the fixture.
143 * <p />
144 * cleaning up .... erase() the previous message OID and logout
145 */
146 protected void tearDown()
147 {
148 try { Thread.sleep(200L); } catch( InterruptedException i) {} // Wait 200 milli seconds, until all updates are processed ...
149
150 try {
151 EraseReturnQos[] arr = con.erase("<key oid='"+msgOidNormal+"'/>", "<qos/>");
152 assertEquals("Erase", 1, arr.length);
153 } catch(XmlBlasterException e) { fail("Erase XmlBlasterException: " + e.getMessage()); }
154
155 con.disconnect(null);
156 con=null;
157
158 try { Thread.sleep(500L); } catch( InterruptedException i) {} // Wait some time
159 EmbeddedXmlBlaster.stopXmlBlaster(this.serverThread);
160 this.serverThread = null;
161
162 // reset to default server port (necessary if other tests follow in the same JVM).
163 Util.resetPorts();
164 }
165
166 /**
167 * We throw different Exception types in the update() method back to xmlBlaster.
168 */
169 public void testException()
170 {
171 log.info("testException() with filterMessageContentBiggerAs=" + filterMessageContentBiggerAs + " ...");
172
173 log.info("TEST 1: Send a message which triggers an exception in update");
174 try {
175 con.publish(new MsgUnit("<key oid='" + msgOidWantException + "'/>", "Hello".getBytes(), null));
176 } catch(XmlBlasterException e) {
177 log.warning("XmlBlasterException: " + e.getMessage());
178 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
179 }
180 waitOnUpdate(2000L, 2);
181
182
183 log.info("TEST 2: Send a normal message, check if everything still works");
184 try {
185 con.publish(new MsgUnit("<key oid='" + msgOidNormal + "'/>", "Hello".getBytes(), null));
186 } catch(XmlBlasterException e) {
187 log.warning("XmlBlasterException: " + e.getMessage());
188 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
189 }
190 waitOnUpdate(2000L, 1);
191
192 log.info("TEST 3: Send a message which triggers an illegal exception in update");
193 try {
194 con.publish(new MsgUnit("<key oid='" + msgOidWantIllegalException + "'/>", "Hello".getBytes(), null));
195 } catch(XmlBlasterException e) {
196 log.warning("XmlBlasterException: " + e.getMessage());
197 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
198 }
199 waitOnUpdate(2000L, 2);
200
201 log.info("TEST 4: Send a normal message, check if everything still works");
202 try {
203 con.publish(new MsgUnit("<key oid='" + msgOidNormal + "'/>", "Hello".getBytes(), null));
204 } catch(XmlBlasterException e) {
205 log.warning("XmlBlasterException: " + e.getMessage());
206 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
207 }
208 waitOnUpdate(2000L, 1);
209
210 log.info("TEST 5: Send a message which triggers a nullpointer exception");
211 try {
212 con.publish(new MsgUnit("<key oid='" + msgOidWantNPE + "'/>", "Hello".getBytes(), null));
213 } catch(XmlBlasterException e) {
214 log.warning("XmlBlasterException: " + e.getMessage());
215 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
216 }
217 waitOnUpdate(2000L, 2);
218
219 log.info("TEST 6: Send a normal message, check if everything still works");
220 try {
221 con.publish(new MsgUnit("<key oid='" + msgOidNormal + "'/>", "Hello".getBytes(), null));
222 } catch(XmlBlasterException e) {
223 log.warning("XmlBlasterException: " + e.getMessage());
224 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
225 }
226 waitOnUpdate(2000L, 1);
227
228 log.info("Success in testException()");
229 }
230
231 /**
232 * This is the callback method invoked from xmlBlaster
233 * delivering us a new asynchronous message.
234 * @see org.xmlBlaster.client.I_Callback#update(String, UpdateKey, byte[], UpdateQos)
235 */
236 public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) throws XmlBlasterException
237 {
238 log.info("Receiving update of a message '" + updateKey.getOid() + "' state=" + updateQos.getState());
239 updateOid = updateKey.getOid();
240 numReceived++;
241
242 if (msgOidWantException.equals(updateKey.getOid()))
243 throw new XmlBlasterException(glob, ErrorCode.USER_UPDATE_ERROR, ME, "Test exception from clients update() method");
244
245 if (msgOidWantIllegalException.equals(updateKey.getOid()))
246 throw new XmlBlasterException(glob, ErrorCode.RESOURCE_CONFIGURATION_PLUGINFAILED, ME, "Test illegal exception from clients update() method");
247
248 if (msgOidWantNPE.equals(updateKey.getOid()))
249 throw new NullPointerException("An artifical NullPointerException");
250
251 return "";
252 }
253
254 /**
255 * Little helper, waits until the wanted number of messages are arrived
256 * or returns when the given timeout occurs.
257 * <p />
258 * @param timeout in milliseconds
259 * @param numWait how many messages to wait
260 */
261 private void waitOnUpdate(final long timeout, final int numWait)
262 {
263 long pollingInterval = 50L; // check every 0.05 seconds
264 if (timeout < 50) pollingInterval = timeout / 10L;
265 long sum = 0L;
266 // check if too few are arriving
267 while (numReceived < numWait) {
268 try { Thread.sleep(pollingInterval); } catch( InterruptedException i) {}
269 sum += pollingInterval;
270 assertTrue("Timeout of " + timeout + " occurred without update", sum <= timeout);
271 }
272
273 // check if too many are arriving
274 try { Thread.sleep(timeout); } catch( InterruptedException i) {}
275 assertEquals("Wrong number of messages arrived", numWait, numReceived);
276
277 numReceived = 0;
278 }
279
280 /**
281 * Method is used by TestRunner to load these tests
282 */
283 public static Test suite()
284 {
285 TestSuite suite= new TestSuite();
286 String loginName = "Tim";
287 suite.addTest(new TestUpdateClientException(new Global(), "testException", "Tim"));
288 return suite;
289 }
290
291 /**
292 * Invoke:
293 * <pre>
294 * java org.xmlBlaster.test.qos.TestUpdateClientException
295 * java -Djava.compiler= junit.textui.TestRunner org.xmlBlaster.test.qos.TestUpdateClientException
296 * <pre>
297 */
298 public static void main(String args[])
299 {
300 Global glob = new Global();
301 if (glob.init(args) != 0) {
302 System.err.println(ME + ": Init failed");
303 System.exit(1);
304 }
305 TestUpdateClientException testSub = new TestUpdateClientException(glob, "TestUpdateClientException", "Tim");
306 testSub.setUp();
307 testSub.testException();
308 testSub.tearDown();
309 }
310 }
syntax highlighted by Code2HTML, v. 0.9.1