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