1 /*------------------------------------------------------------------------------
2 Name: TestLogin.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 ------------------------------------------------------------------------------*/
6 package org.xmlBlaster.test.authentication;
7
8 import java.util.logging.Logger;
9 import java.util.logging.Level;
10 import org.xmlBlaster.util.Global;
11 import org.xmlBlaster.util.def.ErrorCode;
12 import org.xmlBlaster.util.XmlBlasterException;
13 import org.xmlBlaster.client.qos.ConnectQos;
14 import org.xmlBlaster.client.qos.DisconnectQos;
15 import org.xmlBlaster.util.SessionName;
16 import org.xmlBlaster.util.MsgUnit;
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.key.PublishKey;
21 import org.xmlBlaster.client.qos.PublishQos;
22 import org.xmlBlaster.client.qos.UpdateQos;
23 import org.xmlBlaster.client.qos.EraseReturnQos;
24 import org.xmlBlaster.util.qos.address.Destination;
25
26 import junit.framework.*;
27
28
29 /**
30 * This client does test login and logout.<br />
31 * login/logout combinations are checked with subscribe()/publish() calls
32 * <p />
33 * This client may be invoked multiple time on the same xmlBlaster server,
34 * as it cleans up everything after his tests are done.
35 * <p>
36 * Invoke examples:<br />
37 * <pre>
38 * java junit.textui.TestRunner org.xmlBlaster.test.authentication.TestLogin
39 * java junit.swingui.TestRunner -noloading org.xmlBlaster.test.authentication.TestLogin
40 * </pre>
41 */
42 public class TestLogin extends TestCase implements I_Callback
43 {
44 private static String ME = "TestLogin";
45 private final Global glob;
46 private static Logger log = Logger.getLogger(TestLogin.class.getName());
47
48 private String publishOid = "";
49 private String firstOid = "FirstOid";
50 private I_XmlBlasterAccess callbackConnection;
51 private String senderName;
52 private String senderContent;
53
54 private I_XmlBlasterAccess secondConnection;
55 private String secondName;
56 private String secondOid = "SecondOid";
57
58 private MsgUnit msgUnit; // a message to play with
59
60 private int numReceived = 0; // error checking
61 private final String contentMime = "text/plain";
62 private final String contentMimeExtended = "1.0";
63
64 private final boolean IS_PTP = true;
65 private final boolean IS_PUBSUB = false;
66
67 /**
68 * Constructs the TestLogin object.
69 * <p />
70 * @param testName The name used in the test suite
71 * @param loginName The name to login to the xmlBlaster
72 * @param secondName The name to login to the xmlBlaster again
73 */
74 public TestLogin(Global glob, String testName, String senderName, String secondName)
75 {
76 super(testName);
77 this.glob = glob;
78
79 this.senderName = senderName;
80 this.secondName = secondName;
81 }
82
83
84 /**
85 * Sets up the fixture.
86 * <p />
87 * Connect to xmlBlaster and login
88 */
89 protected void setUp()
90 {
91 log.info("######## Entering setup");
92 try {
93 String passwd = "secret";
94
95 callbackConnection = glob.getXmlBlasterAccess(); // Find orb
96 ConnectQos qos = new ConnectQos(glob, senderName, passwd);
97 callbackConnection.connect(qos, this); // Login to xmlBlaster
98
99 Global secondGlobal = glob.getClone(null);
100 secondConnection = secondGlobal.getXmlBlasterAccess(); // Find orb
101 qos = new ConnectQos(secondGlobal, secondName, passwd);
102 secondConnection.connect(qos, this);
103
104 }
105 catch (XmlBlasterException e) {
106 if (e.getErrorCode() == ErrorCode.USER_CONNECT_MULTIPLE) {
107 // ignore
108 }
109 else {
110 log.severe(e.toString());
111 fail(ME + ".setup failed: " + e.toString());
112 }
113 }
114
115 // a sample message unit
116 String xmlKey = "<key oid='" + firstOid + "' contentMime='" + contentMime + "' contentMimeExtended='" + contentMimeExtended + "'>\n" +
117 " <TestLogin-AGENT>" +
118 " </TestLogin-AGENT>" +
119 "</key>";
120 senderContent = "Some content";
121 try {
122 msgUnit = new MsgUnit(xmlKey, senderContent.getBytes(), "<qos></qos>");
123 }
124 catch (XmlBlasterException e) {
125 log.severe("setup() failed: " + e.getMessage());
126 fail(e.getMessage());
127 }
128 }
129
130
131 /**
132 * Tears down the fixture.
133 * <p />
134 * cleaning up .... erase() the previous message OID and logout
135 */
136 protected void tearDown()
137 {
138 {
139 String xmlKey = "<key oid='" + firstOid + "' queryType='EXACT'>\n</key>";
140 String qos = "<qos></qos>";
141 try {
142 EraseReturnQos[] arr = callbackConnection.erase(xmlKey, qos);
143 if (arr != null && arr.length != 1) log.severe("Erased " + arr.length + " messages:");
144 assertEquals("Wrong number of messages erased", 1, arr.length);
145 } catch(XmlBlasterException e) {
146 log.severe("XmlBlasterException in erase(): " + e.getMessage());
147 fail(ME+"-tearDown() XmlBlasterException in erase(): " + e.getMessage());
148 }
149 }
150
151 {
152 String xmlKey = "<key oid='" + secondOid + "' queryType='EXACT'>\n</key>";
153 String qos = "<qos></qos>";
154 try {
155 EraseReturnQos[] arr = callbackConnection.erase(xmlKey, qos);
156 if (arr.length != 1)
157 log.severe("Erased " + arr.length + " messages of '" + secondOid + "'");
158 assertEquals("Wrong number of messages '" + secondOid + "' erased", 1, arr.length);
159 } catch(XmlBlasterException e) {
160 log.severe("XmlBlasterException in erase(): " + e.getMessage());
161 fail(ME+"-tearDown() XmlBlasterException in erase(): " + e.getMessage());
162 }
163 }
164
165 DisconnectQos qos = new DisconnectQos(glob);
166 qos.clearSessions(true);
167 callbackConnection.disconnect(qos);
168 secondConnection.disconnect(null);
169 }
170
171
172 /**
173 * TEST: Subscribe to messages with XPATH.
174 * <p />
175 * The returned subscribeOid is checked
176 */
177 public void doSubscribeXPath()
178 {
179 if (log.isLoggable(Level.FINE)) log.fine("Subscribing using XPath syntax ...");
180
181 String xmlKey = "<key oid='' queryType='XPATH'>\n" +
182 " //TestLogin-AGENT" +
183 "</key>";
184 String qos = "<qos></qos>";
185 numReceived = 0;
186 try {
187 String subscribeOid = callbackConnection.subscribe(xmlKey, qos).getSubscriptionId();
188 assertTrue("returned null subscribeOid", subscribeOid != null);
189 assertTrue("returned subscribeOid is empty", 0 != subscribeOid.length());
190 log.info("Success: Subscribe on " + subscribeOid + " done");
191 } catch(XmlBlasterException e) {
192 log.warning("XmlBlasterException: " + e.getMessage());
193 assertTrue("subscribe - XmlBlasterException: " + e.getMessage(), false);
194 }
195 }
196
197
198 /**
199 * TEST: Construct a message and publish it.
200 * <p />
201 * The returned publishOid is checked
202 * @param ptp Use the Point to Point style
203 */
204 public void doPublish(boolean ptp)
205 {
206 if (log.isLoggable(Level.FINE)) log.fine("Publishing a message ...");
207
208 numReceived = 0;
209 try {
210 PublishQos publishQos = new PublishQos(glob);
211 msgUnit = new MsgUnit(msgUnit, null, null, publishQos.getData());
212 if (ptp) {
213 PublishKey pk = new PublishKey(glob);
214 PublishQos pq = new PublishQos(glob);
215 pq.addDestination(new Destination(new SessionName(glob, secondName)));
216 msgUnit = new MsgUnit(msgUnit, pk.getData(), null, pq.getData());
217 }
218 publishOid = callbackConnection.publish(msgUnit).getKeyOid();
219 log.info("Success: Publish " + msgUnit.getKey() + " done");
220 if (!ptp)
221 assertEquals("oid is different", firstOid, publishOid);
222 } catch(XmlBlasterException e) {
223 log.warning("XmlBlasterException: " + e.getMessage());
224 assertTrue("publish - XmlBlasterException: " + e.getMessage(), false);
225 }
226
227 assertTrue("returned publishOid == null", publishOid != null);
228 assertTrue("returned publishOid", 0 != publishOid.length());
229 }
230
231
232 /**
233 * TEST: Construct a message and publish it,<br />
234 * the previous XPath subscription should match and send an update.
235 */
236 public void testLoginLogout()
237 {
238 log.info("TEST 1: Subscribe and publish -> Expecting one update");
239 numReceived = 0;
240 doSubscribeXPath();
241 doPublish(IS_PUBSUB);
242 waitOnUpdate(2000L, 1); // message arrived?
243
244 log.info("TEST 2: Login again without logout and publish PtP -> Expecting one update");
245 setUp();
246 doPublish(IS_PTP); // sending directly PtP to 'receiver'
247 waitOnUpdate(2000L, 1); // 2 times logged in, 2 messages arrived?
248
249 log.info("TEST 3: Login again without logout and publish Pub/Sub -> Expecting no update");
250 setUp();
251 doPublish(IS_PUBSUB);
252 waitOnUpdate(2000L, 1); // 1 times subscribed (TEST 1), 1 messages arrived?
253 numReceived = 0;
254
255 log.info("TEST 4: Now subscribe -> Expecting one update");
256 numReceived = 0;
257 doSubscribeXPath();
258 waitOnUpdate(2000L, 1); // message arrived?
259
260 log.info("TEST 5: Test publish from other user -> Expecting one update");
261 numReceived = 0;
262 try {
263 // a sample message unit
264 String xmlKey = "<key oid='" + secondOid + "' contentMime='" + contentMime + "' contentMimeExtended='" + contentMimeExtended + "'>\n" +
265 " <TestLogin-AGENT>" +
266 " </TestLogin-AGENT>" +
267 "</key>";
268 String content = "Some content";
269 MsgUnit mu = new MsgUnit(xmlKey, content.getBytes(), "<qos></qos>");
270 publishOid = secondConnection.publish(mu).getKeyOid();
271 } catch(XmlBlasterException e) {
272 log.warning("XmlBlasterException: " + e.getMessage());
273 assertTrue("second - publish - XmlBlasterException: " + e.getMessage(), false);
274 }
275 waitOnUpdate(2000L, 2); // 2 messages (we have subscribed 2 times, and the old session remained on relogin)
276
277 assertTrue("returned publishOid == null", publishOid != null);
278 assertTrue("returned publishOid", 0 != publishOid.length());
279
280 log.info("TEST 6: Test logout with following publish -> Should not be possible");
281 // test logout with following subscribe()
282 callbackConnection.disconnect(null);
283 try {
284 publishOid = callbackConnection.publish(msgUnit).getKeyOid();
285 assertTrue("Didn't expect successful publish after logout", false);
286 } catch(XmlBlasterException e) {
287 log.info("Success got exception for publishing after logout: " + e.toString());
288 }
289 try { Thread.sleep(1000L); } catch (Exception e) { } // wait a second
290 assertEquals("Didn't expect an update", 0, numReceived);
291
292 log.info("SUCCESS in testLoginLogout()");
293
294 // login again
295 setUp();
296
297 }
298
299 /**
300 * This is the callback method invoked from xmlBlaster
301 * delivering us a new asynchronous message.
302 * @see org.xmlBlaster.client.I_Callback#update(String, UpdateKey, byte[], UpdateQos)
303 */
304 public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos)
305 {
306 log.info("Receiving update of a message " + updateKey.getOid() + " state=" + updateQos.getState() +
307 " rcvTime=" + updateQos.getRcvTimestamp().toString());
308 log.info("Receiving update of a message " + updateKey.getOid() + updateQos.toXml());
309 numReceived++;
310 return "";
311 }
312
313
314 /**
315 * Little helper, waits until the wanted number of messages are arrived
316 * or returns when the given timeout occurs.
317 * <p />
318 * @param timeout in milliseconds
319 * @param numWait how many messages to wait
320 */
321 private void waitOnUpdate(final long timeout, final int numWait)
322 {
323 long pollingInterval = 50L; // check every 0.05 seconds
324 if (timeout < 50) pollingInterval = timeout / 10L;
325 long sum = 0L;
326 // check if too few are arriving
327 while (numReceived < numWait) {
328 try { Thread.sleep(pollingInterval); } catch( InterruptedException i) {}
329 sum += pollingInterval;
330 if (sum > timeout) {
331 log.severe("Timeout of " + timeout + " occurred without update");
332 Thread.dumpStack();
333 }
334 assertTrue("Timeout of " + timeout + " occurred without update", sum <= timeout);
335 }
336
337 // check if too many are arriving
338 try { Thread.sleep(timeout); } catch( InterruptedException i) {}
339 if (numWait != numReceived) {
340 log.severe("Wrong number of messages arrived, expected numWait=" + numWait + " but got numReceived=" + numReceived);
341 Thread.dumpStack();
342 }
343 assertEquals("Wrong number of messages arrived", numWait, numReceived);
344
345 numReceived = 0;
346 }
347
348
349 /**
350 * Method is used by TestRunner to load these tests
351 */
352 public static Test suite()
353 {
354 TestSuite suite= new TestSuite();
355 String loginName = "Tim";
356 suite.addTest(new TestLogin(new Global(), "testLoginLogout", loginName, "Joe"));
357 return suite;
358 }
359
360
361 /**
362 * Invoke: java org.xmlBlaster.test.authentication.TestLogin
363 * <br />
364 * @deprecated Use the TestRunner from the testsuite to run it:<p />
365 * <pre> java -Djava.compiler= junit.textui.TestRunner org.xmlBlaster.test.authentication.TestLogin</pre>
366 */
367 public static void main(String args[])
368 {
369 Global glob = new Global();
370 if (glob.init(args) != 0) {
371 System.err.println(ME + ": Init failed");
372 System.exit(1);
373 }
374 TestLogin testSub = new TestLogin(glob, "TestLogin", "Tim", "Joe");
375 testSub.setUp();
376 testSub.testLoginLogout();
377 testSub.tearDown();
378 }
379 }
syntax highlighted by Code2HTML, v. 0.9.1