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


syntax highlighted by Code2HTML, v. 0.9.1