1 package org.xmlBlaster.test.cluster;
2
3 import java.util.logging.Logger;
4 import org.xmlBlaster.util.Global;
5
6 // for client connections:
7 import org.xmlBlaster.util.*;
8 import org.xmlBlaster.client.I_Callback;
9 import org.xmlBlaster.client.key.PublishKey;
10 import org.xmlBlaster.client.key.SubscribeKey;
11 import org.xmlBlaster.client.key.UpdateKey;
12 import org.xmlBlaster.client.qos.PublishQos;
13 import org.xmlBlaster.client.qos.PublishReturnQos;
14 import org.xmlBlaster.client.qos.UpdateQos;
15 import org.xmlBlaster.client.qos.SubscribeQos;
16 import org.xmlBlaster.client.I_XmlBlasterAccess;
17 import org.xmlBlaster.util.MsgUnit;
18
19 import junit.framework.*;
20
21 /**
22 * Test publishing a message to frodo which forwards it to heron, the message
23 * is dirty read in fordo.
24 * <p />
25 * <pre>
26 * java -Djava.compiler= junit.textui.TestRunner -noloading org.xmlBlaster.test.cluster.DirtyReadTest
27 * </pre>
28 * NOTE: asserts() in update() methods are routed back to server and are not handled
29 * by the junit testsuite, so we check double (see code).
30 *
31 * @see <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/cluster.dirtyRead.html" target="others">Cluster requirement</a>
32 */
33 public class DirtyReadTest extends TestCase {
34 private String ME = "DirtyReadTest";
35 private Global glob;
36 private static Logger log = Logger.getLogger(DirtyReadTest.class.getName());
37 private ServerHelper serverHelper;
38
39 private I_XmlBlasterAccess heronCon, frodoCon;
40
41 private int updateCounterFrodo = 0;
42 private String contentStr = "Lets have another game.";
43
44 private String assertInUpdate = null;
45
46 public DirtyReadTest(String name) {
47 super(name);
48 this.glob = new Global(null, true, false);
49 }
50
51 /**
52 * Initialize the test ...
53 */
54 protected void setUp() {
55
56 log.info("Entering setUp(), test starts");
57
58 assertInUpdate = null;
59 updateCounterFrodo = 0;
60
61 serverHelper = new ServerHelper(glob, log, ME);
62
63 serverHelper.startHeron();
64 serverHelper.startFrodo();
65 }
66
67 /**
68 * cleaning up ...
69 */
70 protected void tearDown() {
71 log.info("Entering tearDown(), test is finished");
72 try { Thread.sleep(1000); } catch( InterruptedException i) {} // Wait some time
73
74 if (frodoCon != null) { frodoCon.disconnect(null); frodoCon = null; }
75 if (heronCon != null) { heronCon.disconnect(null); heronCon = null; }
76
77 serverHelper.tearDown();
78 }
79
80 public void testDirtyRead() {
81 runIt("RUGBY_NEWS"); // heron is master for RUGBY_NEWS and has dirtyRead allowed
82 }
83
84 public void testNoDirtyRead() {
85 runIt("SOCCER_NEWS"); // heron is master for SOCCER_NEWS WITHOUT dirty read!
86 }
87
88 /**
89 * We start all nodes as described in requirement
90 * <a href="http://www.xmlblaster.org/xmlBlaster/doc/requirements/cluster.html" target="others">cluster</a>
91 * publish a message to bilbo which should be routed to heron.
92 * Than we try to access the message at heron and check if heron has not
93 * updated one to frodo because of dirtyRead configured in heron.properties
94 */
95 public void runIt(String domain) {
96 boolean isDirtyReadTest = domain.equals("RUGBY_NEWS");
97 ME = "DirtyReadTest domain=" + domain + ": ";
98 System.err.println("***DirtyReadTest: Publish a message to a cluster slave isDirtyReadTest=" + isDirtyReadTest + " ...");
99
100 final String oid = isDirtyReadTest ? "PublishToBilbo-DirtyRead" : "PublishToBilbo-NODirtyRead";
101
102 SubscribeKey sk;
103 SubscribeQos sq;
104
105 PublishKey pk;
106 PublishQos pq;
107 PublishReturnQos prq;
108 MsgUnit msgUnit;
109
110 try {
111 System.err.println(ME+"->Connect to frodo ...");
112 frodoCon = serverHelper.connect(serverHelper.getFrodoGlob(), new I_Callback() {
113 public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) {
114 assertInUpdate = serverHelper.getFrodoGlob().getId() + ": Receive unexpected message '" + updateKey.getOid() + "'";
115 return "";
116 }
117 });
118 try { Thread.sleep(1000); } catch( InterruptedException i) {} // Wait some time
119 assertTrue(assertInUpdate, assertInUpdate == null);
120
121
122 System.err.println(ME+"->Subscribe '" + oid + "' from frodo ...");
123 sk = new SubscribeKey(glob, oid);
124 sk.setDomain(domain);
125 sq = new SubscribeQos(glob);
126 frodoCon.subscribe(sk.toXml(), sq.toXml(), new I_Callback() {
127 public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos) {
128 log.info("Reveiving asynchronous message '" + updateKey.getOid() + "' in " + oid + " handler");
129 updateCounterFrodo++;
130 assertInUpdate = null;
131 return "";
132 }
133 }); // subscribe with our specific update handler
134 try { Thread.sleep(1000); } catch( InterruptedException i) {} // Wait some time
135 assertTrue(assertInUpdate, assertInUpdate == null);
136 assertInUpdate = null;
137
138
139 System.err.println(ME+"->Check publish '" + oid + "', frodo should get it ...");
140 pk = new PublishKey(glob, oid, "text/plain", "1.0", domain);
141 pq = new PublishQos(glob);
142 msgUnit = new MsgUnit(pk, contentStr.getBytes(), pq);
143 prq = frodoCon.publish(msgUnit);
144 log.info("Published message of domain='" + pk.getDomain() + "' and content='" + contentStr +
145 "' to xmlBlaster node with IP=" + serverHelper.getFrodoGlob().getProperty().get("bootstrapPort",0) +
146 ", the returned QoS is: " + prq.getKeyOid());
147
148 try { Thread.sleep(2000); } catch( InterruptedException i) {} // Wait some time
149 assertEquals("frodo has not received message", 1, updateCounterFrodo);
150
151 System.err.println("Query heron if he did not send any update message ...");
152 System.err.println("->Connect to heron ...");
153 heronCon = serverHelper.connect(serverHelper.getHeronGlob(), null);
154
155
156 String cmd = "__cmd:client/frodo/?sessionList";
157 System.err.println(ME+"->Find out the public session Id of slave frodo at heron with '" + cmd + "' ...");
158 MsgUnit[] msgs = heronCon.get("<key oid='" + cmd + "'/>", null);
159 assertEquals("Command failed", 1, msgs.length);
160 String pubSessionId = msgs[0].getContentStr();
161
162
163 // command = "__cmd:client/frodo/2/?numUpdate" : (the cluster slave loggs in usually with its glob.getId()
164 cmd = "__cmd:client/frodo/" + pubSessionId + "/?numUpdate";
165 System.err.println("->Query numUpdate with '" + cmd + "' ...");
166 msgs = heronCon.get("<key oid='" + cmd + "'/>", null);
167
168 assertEquals("Command failed", 1, msgs.length);
169 if (isDirtyReadTest) {
170 assertEquals("frodo has received updates from heron but should not because of dirty read",
171 "0", msgs[0].getContentStr());
172 log.info("Success, the update was a dirty read as heron did not send it!");
173 }
174 else {
175 assertEquals("frodo has not received updates from its master heron",
176 "1", msgs[0].getContentStr());
177 log.info("Success, the update was NO dirty read as heron did send it!");
178 }
179
180 System.err.println(ME+"Check if heron has got the message ...");
181 msgs = heronCon.get("<key oid='" + oid + "'/>", null);
182 assertEquals("The master never got the message", 1, msgs.length);
183 }
184 catch (XmlBlasterException e) {
185 e.printStackTrace();
186 fail("PublishToBilbo-DirtyRead-Exception: " + e.toString());
187 }
188
189 System.err.println("***DirtyReadTest: testDirtyRead [SUCCESS]");
190 }
191 }
syntax highlighted by Code2HTML, v. 0.9.1