1 /*------------------------------------------------------------------------------
  2 Name:      TestFailSafePing.java
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 ------------------------------------------------------------------------------*/
  6 package org.xmlBlaster.test.client;
  7 
  8 
  9 import java.util.logging.Level;
 10 import java.util.logging.Logger;
 11 
 12 import junit.framework.Test;
 13 import junit.framework.TestCase;
 14 import junit.framework.TestSuite;
 15 
 16 import org.xmlBlaster.client.I_ConnectionStateListener;
 17 import org.xmlBlaster.client.I_XmlBlasterAccess;
 18 import org.xmlBlaster.client.qos.ConnectQos;
 19 import org.xmlBlaster.client.qos.EraseReturnQos;
 20 import org.xmlBlaster.client.qos.PublishQos;
 21 import org.xmlBlaster.test.MsgInterceptor;
 22 import org.xmlBlaster.test.Util;
 23 import org.xmlBlaster.util.EmbeddedXmlBlaster;
 24 import org.xmlBlaster.util.Global;
 25 import org.xmlBlaster.util.MsgUnit;
 26 import org.xmlBlaster.util.XmlBlasterException;
 27 import org.xmlBlaster.util.def.ErrorCode;
 28 import org.xmlBlaster.util.dispatch.ConnectionStateEnum;
 29 import org.xmlBlaster.util.qos.address.Address;
 30 
 31 
 32 /**
 33  * Tests the fail save behavior of the I_XmlBlasterAccess client helper class,
 34  * especially the pinging to xmlBlaster. This allows auto detection if the
 35  * connection to xmlBlaster is lost.
 36  *
 37  * <br />For a description of what this fail save mode can do for you, please
 38  * read the API documentation of I_XmlBlasterAccess.
 39  * <p>
 40  * This is an interesting example, since it creates a XmlBlaster server instance
 41  * in the same JVM , but in a separate thread, talking over CORBA with it.
 42  * <p>
 43  * Invoke examples:<br />
 44  * <pre>
 45  *   java junit.textui.TestRunner org.xmlBlaster.test.client.TestFailSafePing
 46  *   java junit.swingui.TestRunner -noloading org.xmlBlaster.test.client.TestFailSafePing
 47  * </pre>
 48  */
 49 public class TestFailSafePing extends TestCase implements I_ConnectionStateListener
 50 {
 51    private static String ME = "TestFailSafePing";
 52    private Global glob;
 53    private static Logger log = Logger.getLogger(TestFailSafePing.class.getName());
 54 
 55    private int serverPort = 7604;
 56    private EmbeddedXmlBlaster serverThread;
 57 
 58    private MsgInterceptor updateInterceptor;
 59    private I_XmlBlasterAccess con;
 60    private String senderName;
 61    private MsgUnit[] msgUnitArr;
 62    private int counter;
 63 
 64    private final String contentMime = "text/plain";
 65 
 66    public TestFailSafePing(String testName) {
 67       this(null, testName);
 68    }
 69 
 70    /**
 71     * Constructs the TestFailSafePing object.
 72     * <p />
 73     * @param testName  The name used in the test suite
 74     */
 75    public TestFailSafePing(Global glob, String testName)
 76    {
 77       super(testName);
 78       this.glob = glob;
 79    }
 80 
 81 
 82    /**
 83     * Sets up the fixture.
 84     * <p />
 85     * Connect to xmlBlaster and login
 86     */
 87    protected void setUp()
 88    {
 89       this.glob = (this.glob == null) ? new Global() : this.glob;
 90 
 91       this.senderName = "TestFailSafePing-joe/97";
 92 
 93       this.glob.init(Util.getOtherServerPorts(serverPort));
 94 
 95       //this.serverThread = EmbeddedXmlBlaster.startXmlBlaster(Util.getOtherServerPorts(serverPort));
 96       try {
 97 
 98          con = this.glob.getXmlBlasterAccess(); // Find server
 99 
100          String passwd = "secret";
101          ConnectQos connectQos = new ConnectQos(this.glob, senderName, passwd);
102 
103          // Setup fail save handling ...
104          Address addressProp = new Address(this.glob);
105          addressProp.setDelay(1000L);         // retry connecting every 1 sec
106          addressProp.setRetries(-1);          // -1 == forever
107          addressProp.setPingInterval(1000L);  // ping every second
108          con.registerConnectionListener(this);
109 
110          connectQos.setAddress(addressProp);
111          
112          this.updateInterceptor = new MsgInterceptor(this.glob, log, null); // Collect received msgs
113 
114          // and do the login ...
115          con.connect(connectQos, this.updateInterceptor); // Login to xmlBlaster
116       }
117       catch (XmlBlasterException e) {
118           log.warning("setUp() - login failed");
119       }
120       catch (Exception e) {
121           log.severe("setUp() - login failed: " + e.toString());
122           e.printStackTrace();
123       }
124    }
125 
126    /**
127     * Tears down the fixture.
128     * <p />
129     * cleaning up .... erase() the previous message OID and logout
130     */
131    protected void tearDown() {
132       log.info("Entering tearDown(), test is finished");
133 
134       String xmlKey = "<key oid='' queryType='XPATH'>\n" +
135                       "   //TestFailSafe-AGENT" +
136                       "</key>";
137       String qos = "<qos><forceDestroy>true</forceDestroy></qos>";
138       try {
139          EraseReturnQos[] arr = con.erase(xmlKey, qos);
140          log.info("Erased " + arr.length);
141       }
142       catch(XmlBlasterException e) {
143          log.severe("XmlBlasterException: " + e.getMessage());
144       }
145 
146       con.disconnect(null);
147       con = null;
148 
149       // reset to default server port (necessary if other tests follow in the same JVM).
150       Util.resetPorts(this.glob);
151       Global.instance().shutdown();
152       this.glob = null;
153      
154       this.serverThread = null;
155       this.updateInterceptor = null;
156       this.msgUnitArr = null;
157    }
158 
159    /**
160     * TEST: Subscribe to messages with XPATH.
161     */
162    public void doSubscribe() {
163       if (log.isLoggable(Level.FINE)) log.fine("Subscribing using EXACT oid syntax ...");
164 
165       String xmlKey = "<key oid='' queryType='XPATH'>\n" +
166                       "   //TestFailSafePing-AGENT" +
167                       "</key>";
168       String qos = "<qos><initialUpdate>false</initialUpdate></qos>";
169       try {
170          String subscribeOid = con.subscribe(xmlKey, qos).getSubscriptionId();
171          log.info("Success: Subscribe on " + subscribeOid + " done");
172          assertTrue("returned null subscribeOid", subscribeOid != null);
173       } catch(XmlBlasterException e) {
174          log.warning("XmlBlasterException: " + e.getMessage());
175          assertTrue("subscribe - XmlBlasterException: " + e.getMessage(), false);
176       }
177    }
178 
179    /**
180     * TEST: Construct a message and publish it.
181     * <p />
182     */
183    public void doPublish() throws XmlBlasterException
184    {
185       counter++;
186       if (log.isLoggable(Level.FINE)) log.fine("Publishing a message " + counter + " ...");
187 
188       String oid = "MyMessage-" + counter;
189       String xmlKey = "<key oid='" + oid + "' contentMime='" + contentMime + "'>\n" +
190                       "   <TestFailSafePing-AGENT id='192.168.124.10' subId='1' type='generic'>" +
191                       "   </TestFailSafePing-AGENT>" +
192                       "</key>";
193       String content = "" + counter;
194       PublishQos qosWrapper = new PublishQos(glob); // == "<qos></qos>"
195       MsgUnit msgUnit = new MsgUnit(xmlKey, content.getBytes(), qosWrapper.toXml());
196       msgUnitArr = new MsgUnit[] { msgUnit };
197       con.publish(msgUnit);
198       log.info("Success: Publishing of " + oid + " done");
199    }
200 
201    /**
202     * TEST: <br />
203     */
204    public void testFailSafe()
205    {
206       for (int i=0; i<3; i++) {
207          this.serverThread = EmbeddedXmlBlaster.startXmlBlaster(serverPort);
208          // Wait some time, to allow the login poller to reconnect
209          try { Thread.sleep(2000L); } catch( InterruptedException ie) {}
210 
211          // reachedAlive published a msg on reconnect, check it here:
212          assertEquals("", 1, this.updateInterceptor.waitOnUpdate(2000L, 1));
213          this.updateInterceptor.compareToReceived(msgUnitArr, null);
214          this.updateInterceptor.clear();
215 
216          EmbeddedXmlBlaster.stopXmlBlaster(this.serverThread);
217          this.serverThread = null;
218          // Wait some time, ping should activate login polling
219          try { Thread.sleep(2000L); } catch( InterruptedException ie) {}
220       }
221    }
222 
223    /**
224     * This is the callback method invoked from I_XmlBlasterAccess
225     * informing the client in an asynchronous mode if the connection was established.
226     * <p />
227     * This method is enforced through interface I_ConnectionStateListener
228     */
229    public void reachedAlive(ConnectionStateEnum oldState, I_XmlBlasterAccess connection) {
230       log.info("I_ConnectionStateListener: We were lucky, reconnected to xmlBlaster");
231    }
232 
233    public void reachedAliveSync(ConnectionStateEnum oldState, I_XmlBlasterAccess connection) {
234       log.info("I_ConnectionStateListener: We were lucky, reconnected sync to xmlBlaster");
235       doSubscribe();    // initialize subscription
236       try {
237          doPublish();
238       }
239       catch(XmlBlasterException e) {
240          if (e.getErrorCode() == ErrorCode.COMMUNICATION_NOCONNECTION_POLLING)
241             log.warning("Lost connection, my connection layer is polling: " + e.getMessage());
242          else if (e.getErrorCode() == ErrorCode.COMMUNICATION_NOCONNECTION_DEAD)
243             assertTrue("Lost connection, my connection layer is not polling", false);
244          else
245             assertTrue("Publishing problems: " + e.getMessage(), false);
246       }
247    }
248 
249    public void reachedPolling(ConnectionStateEnum oldState, I_XmlBlasterAccess connection) {
250       log.warning("I_ConnectionStateListener: Lost connection to xmlBlaster");
251    }
252 
253    public void reachedDead(ConnectionStateEnum oldState, I_XmlBlasterAccess connection) {
254       log.severe("DEBUG ONLY: Changed from connection state " + oldState + " to " + ConnectionStateEnum.DEAD);
255    }
256 
257    /**
258     * Method is used by TestRunner to load these tests
259     */
260    public static Test suite()
261    {
262        TestSuite suite= new TestSuite();
263        suite.addTest(new TestFailSafePing(null, "testFailSafe"));
264        return suite;
265    }
266 
267    /**
268     * Invoke: java org.xmlBlaster.test.client.TestFailSafePing
269     * @deprecated Use the TestRunner from the testsuite to run it:<p />
270     * <pre>   java -Djava.compiler= junit.textui.TestRunner org.xmlBlaster.test.client.TestFailSafePing</pre>
271     */
272    public static void main(String args[])
273    {
274       Global glob = new Global();
275       if (glob.init(args) != 0) {
276          System.err.println(ME + ": Init failed");
277          System.exit(1);
278       }
279       TestFailSafePing testSub = new TestFailSafePing(glob, "TestFailSafePing");
280       testSub.setUp();
281       testSub.testFailSafe();
282       testSub.tearDown();
283    }
284 }


syntax highlighted by Code2HTML, v. 0.9.1