1 /*------------------------------------------------------------------------------
2 Name: TestSubExact.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Demo code for a client using xmlBlaster
6 ------------------------------------------------------------------------------*/
7 package org.xmlBlaster.test.qos;
8
9 import java.util.logging.Logger;
10 import java.util.logging.Level;
11 import org.xmlBlaster.util.Global;
12 import org.xmlBlaster.client.qos.ConnectQos;
13 import org.xmlBlaster.util.XmlBlasterException;
14 import org.xmlBlaster.client.I_XmlBlasterAccess;
15 import org.xmlBlaster.client.I_Callback;
16 import org.xmlBlaster.client.key.UpdateKey;
17 import org.xmlBlaster.client.qos.UpdateQos;
18 import org.xmlBlaster.client.qos.EraseReturnQos;
19 import org.xmlBlaster.util.MsgUnit;
20
21 import junit.framework.*;
22
23
24 /**
25 * This client tests the method subscribe() with a later publish() with EXACT oid.
26 * <br />
27 * The subscribe() should be recognized for this later arriving publish()
28 * <p>
29 * This client may be invoked multiple time on the same xmlBlaster server,
30 * as it cleans up everything after his tests are done.
31 * <p>
32 * Invoke examples:<br />
33 * <pre>
34 * java junit.textui.TestRunner org.xmlBlaster.test.qos.TestSubExact
35 * java junit.swingui.TestRunner org.xmlBlaster.test.qos.TestSubExact
36 * </pre>
37 */
38 public class TestSubExact extends TestCase implements I_Callback
39 {
40 private static String ME = "TestSubExact";
41 private final Global glob;
42 private static Logger log = Logger.getLogger(TestSubExact.class.getName());
43
44 private boolean messageArrived = false;
45
46 private String subscribeOid;
47 private String oidExact = "HelloMessage";
48 private String publishOid = "";
49 private I_XmlBlasterAccess senderConnection;
50 private String senderName;
51 private String senderContent;
52 private String receiverName; // sender/receiver is here the same client
53
54 private int numReceived = 0; // error checking
55 private final String contentMime = "text/xml";
56 private final String contentMimeExtended = "1.0";
57
58 /**
59 * Constructs the TestSubExact object.
60 * <p />
61 * @param testName The name used in the test suite
62 * @param loginName The name to login to the xmlBlaster
63 */
64 public TestSubExact(Global glob, String testName, String loginName)
65 {
66 super(testName);
67 this.glob = glob;
68
69 this.senderName = loginName;
70 this.receiverName = loginName;
71 }
72
73
74 /**
75 * Sets up the fixture.
76 * <p />
77 * Connect to xmlBlaster and login
78 */
79 protected void setUp()
80 {
81 try {
82 senderConnection = glob.getXmlBlasterAccess(); // Find orb
83 String passwd = "secret";
84 ConnectQos qos = new ConnectQos(glob, senderName, passwd); // == "<qos></qos>";
85 senderConnection.connect(qos, this); // Login to xmlBlaster
86 }
87 catch (Exception e) {
88 log.severe("Login failed: " + e.toString());
89 e.printStackTrace();
90 assertTrue("Login failed: " + e.toString(), false);
91 }
92 }
93
94
95 /**
96 * Tears down the fixture.
97 * <p />
98 * cleaning up .... erase() the previous message OID and logout
99 */
100 protected void tearDown()
101 {
102 String xmlKey = "<key oid='" + publishOid + "' queryType='EXACT'>\n" +
103 "</key>";
104 try {
105 EraseReturnQos[] arr = senderConnection.erase(xmlKey, "<qos/>");
106 assertEquals("Erase", 1, arr.length);
107 } catch(XmlBlasterException e) { fail("Erase XmlBlasterException: " + e.getMessage()); }
108
109 senderConnection.disconnect(null);
110 }
111
112
113 /**
114 * Subscribe to message with EXACT oid
115 * <p />
116 * The returned subscribeOid is checked
117 */
118 public void subscribeExact()
119 {
120 if (log.isLoggable(Level.FINE)) log.fine("Subscribing using XPath syntax ...");
121
122 String xmlKey = "<key oid='" + oidExact + "' queryType='EXACT'>\n" +
123 "</key>";
124 String qos = "<qos></qos>";
125 numReceived = 0;
126 subscribeOid = null;
127 try {
128 subscribeOid = senderConnection.subscribe(xmlKey, qos).getSubscriptionId();
129 log.info("Success: Subscribe on " + subscribeOid + " done");
130 } catch(XmlBlasterException e) {
131 log.warning("XmlBlasterException: " + e.getMessage());
132 assertTrue("subscribe - XmlBlasterException: " + e.getMessage(), false);
133 }
134 assertTrue("returned null subscribeOid", subscribeOid != null);
135 assertTrue("returned subscribeOid is empty", 0 != subscribeOid.length());
136 }
137
138
139 /**
140 * TEST: Construct a message and publish it.
141 * <p />
142 * The returned publishOid is checked
143 */
144 public void testPublish()
145 {
146 if (log.isLoggable(Level.FINE)) log.fine("Publishing a message ...");
147
148 numReceived = 0;
149 String xmlKey = "<key oid='" + oidExact + "' contentMime='" + contentMime + "' contentMimeExtended='" + contentMimeExtended + "'>\n" +
150 "</key>";
151 senderContent = "Yeahh, i'm the new content";
152 try {
153 MsgUnit msgUnit = new MsgUnit(xmlKey, senderContent.getBytes(), "<qos></qos>");
154 publishOid = senderConnection.publish(msgUnit).getKeyOid();
155 log.info("Success: Publishing done, returned oid=" + publishOid);
156 } catch(XmlBlasterException e) {
157 log.warning("XmlBlasterException: " + e.getMessage());
158 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
159 }
160
161 assertTrue("returned publishOid == null", publishOid != null);
162 assertTrue("returned publishOid", 0 != publishOid.length());
163 assertEquals("returned publishOid is wrong", oidExact, publishOid);
164 }
165
166
167 /**
168 * TEST: Construct a message and publish it,<br />
169 * the previous XPath subscription should match and send an update.
170 */
171 public void testPublishAfterSubscribe()
172 {
173 subscribeExact();
174 try { Thread.sleep(1000L); } catch( InterruptedException i) {} // Wait some time for callback to arrive ...
175 assertEquals("numReceived after subscribe", 0, numReceived); // there should be no Callback
176
177 testPublish();
178 waitOnUpdate(5000L);
179 assertEquals("numReceived after publishing", 1, numReceived); // message arrived?
180 }
181
182 /**
183 * This is the callback method invoked from xmlBlaster
184 * delivering us a new asynchronous message.
185 * @see org.xmlBlaster.client.I_Callback#update(String, UpdateKey, byte[], UpdateQos)
186 */
187 public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos)
188 {
189 if (log.isLoggable(Level.FINER)) log.finer("Receiving update of a message from sender = " + updateQos.getSender() + " ...");
190
191 numReceived += 1;
192
193 // Wait that publish() returns and set 'publishOid' properly
194 try { Thread.sleep(200); } catch( InterruptedException i) {}
195
196 if (updateQos.isErased()) {
197 return "";
198 }
199
200 try {
201 assertEquals("Wrong sender", senderName, updateQos.getSender().getLoginName());
202 assertEquals("engine.qos.update.subscriptionId: Wrong subscriptionId", subscribeOid, updateQos.getSubscriptionId());
203 assertEquals("Wrong oid of message returned", publishOid, updateKey.getOid());
204 assertEquals("Message content is corrupted", new String(senderContent), new String(content));
205 assertEquals("Message contentMime is corrupted", contentMime, updateKey.getContentMime());
206 assertEquals("Message contentMimeExtended is corrupted", contentMimeExtended, updateKey.getContentMimeExtended());
207 }
208 catch (RuntimeException e) { // TODO: pass problem to junit
209 e.printStackTrace();
210 log.severe(e.toString());
211 throw e;
212 }
213
214 messageArrived = true;
215 return "";
216 }
217
218
219 /**
220 * Little helper, waits until the variable 'messageArrive' is set
221 * to true, or returns when the given timeout occurs.
222 * @param timeout in milliseconds
223 */
224 private void waitOnUpdate(final long timeout)
225 {
226 long pollingInterval = 50L; // check every 0.05 seconds
227 if (timeout < 50) pollingInterval = timeout / 10L;
228 long sum = 0L;
229 while (!messageArrived) {
230 try {
231 Thread.sleep(pollingInterval);
232 }
233 catch( InterruptedException i)
234 {}
235 sum += pollingInterval;
236 if (sum > timeout) {
237 log.warning("Timeout of " + timeout + " occurred");
238 break;
239 }
240 }
241 messageArrived = false;
242 }
243
244
245 /**
246 * Method is used by TestRunner to load these tests
247 */
248 public static Test suite()
249 {
250 TestSuite suite= new TestSuite();
251 String loginName = "Tim";
252 suite.addTest(new TestSubExact(new Global(), "testPublishAfterSubscribe", loginName));
253 return suite;
254 }
255
256
257 /**
258 * Invoke: java org.xmlBlaster.test.qos.TestSubExact
259 * @deprecated Use the TestRunner from the testsuite to run it:<p />
260 * <pre> java -Djava.compiler= junit.textui.TestRunner org.xmlBlaster.test.qos.TestSubExact</pre>
261 */
262 public static void main(String args[])
263 {
264 Global glob = new Global();
265 if (glob.init(args) != 0) {
266 System.err.println(ME + ": Init failed");
267 System.exit(1);
268 }
269 TestSubExact testSub = new TestSubExact(glob, "TestSubExact", "Tim");
270 testSub.setUp();
271 testSub.testPublishAfterSubscribe();
272 testSub.tearDown();
273 }
274 }
syntax highlighted by Code2HTML, v. 0.9.1