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