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