View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.distribution;
18  
19  
20  import net.sf.ehcache.AbstractCacheTest;
21  import net.sf.ehcache.Cache;
22  import net.sf.ehcache.CacheManager;
23  import net.sf.ehcache.Ehcache;
24  import net.sf.ehcache.Element;
25  import net.sf.ehcache.Status;
26  import net.sf.ehcache.event.CacheEventListener;
27  import net.sf.ehcache.event.CountingCacheEventListener;
28  
29  import org.junit.After;
30  
31  import static net.sf.ehcache.util.RetryAssert.assertBy;
32  import static net.sf.ehcache.util.RetryAssert.elementAt;
33  import static net.sf.ehcache.util.RetryAssert.sizeOf;
34  import static org.hamcrest.core.Is.is;
35  import static org.hamcrest.core.IsNull.notNullValue;
36  import static org.junit.Assert.assertEquals;
37  import static org.junit.Assert.assertNotNull;
38  
39  import org.junit.Before;
40  import org.junit.Test;
41  
42  import java.rmi.Remote;
43  import java.rmi.RemoteException;
44  import java.util.Collections;
45  import java.util.List;
46  import java.util.concurrent.TimeUnit;
47  
48  /***
49   * Unit tests for the RMICacheManagerPeerListener
50   * <p/>
51   * Note these tests need a live network interface running in multicast mode to work
52   *
53   * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
54   * @version $Id: RMICacheManagerPeerListenerTest.html 13146 2011-08-01 17:12:39Z oletizi $
55   */
56  public class RMICacheManagerPeerListenerTest extends AbstractRMITest {
57  
58      /***
59       * CacheManager 1 in the cluster
60       */
61      protected CacheManager manager1;
62      /***
63       * CacheManager 2 in the cluster
64       */
65      protected CacheManager manager2;
66      /***
67       * CacheManager 3 in the cluster
68       */
69      protected CacheManager manager3;
70      /***
71       * CacheManager 4 in the cluster
72       */
73      protected CacheManager manager4;
74      /***
75       * CacheManager 5 in the cluster
76       */
77      protected CacheManager manager5;
78      /***
79       * CacheManager 6 in the cluster
80       */
81      protected CacheManager manager6;
82  
83      /***
84       * The name of the cache under test
85       */
86      protected String cacheName = "sampleCache1";
87      /***
88       * CacheManager 1 of 2s cache being replicated
89       */
90      protected Ehcache cache1;
91  
92      /***
93       * CacheManager 2 of 2s cache being replicated
94       */
95      protected Ehcache cache2;
96  
97      /***
98       * {@inheritDoc}
99       * Sets up two caches: cache1 is local. cache2 is to be receive updates
100      *
101      * @throws Exception
102      */
103     @Before
104     public void setUp() throws Exception {
105         manager1 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed1.xml");
106         manager2 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed2.xml");
107         manager3 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed3.xml");
108         manager4 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed4.xml");
109         manager5 = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed5.xml");
110 
111         //allow cluster to be established
112         waitForClusterMembership(10, TimeUnit.SECONDS, Collections.singleton(cacheName), manager1, manager2, manager3, manager4, manager5);
113 
114         manager1.getCache(cacheName).put(new Element("setup", "setup"));
115         for (CacheManager manager : new CacheManager[] {manager1, manager2, manager3, manager4, manager5}) {
116             assertBy(10, TimeUnit.SECONDS, elementAt(manager.getCache(cacheName), "setup"), notNullValue());
117         }
118 
119         manager1.getCache(cacheName).removeAll();
120         for (CacheManager manager : new CacheManager[] {manager1, manager2, manager3, manager4, manager5}) {
121             assertBy(10, TimeUnit.SECONDS, sizeOf(manager.getCache(cacheName)), is(0));
122         }
123 
124         CountingCacheEventListener.resetCounters();
125         cache1 = manager1.getCache(cacheName);
126         cache2 = manager2.getCache(cacheName);
127     }
128 
129 
130     /***
131      * {@inheritDoc}
132      *
133      * @throws Exception
134      */
135     @After
136     public void tearDown() throws Exception {
137 
138         if (manager1 != null) {
139             manager1.shutdown();
140         }
141         if (manager2 != null) {
142             manager2.shutdown();
143         }
144         if (manager3 != null) {
145             manager3.shutdown();
146         }
147         if (manager4 != null) {
148             manager4.shutdown();
149         }
150         if (manager5 != null) {
151             manager5.shutdown();
152         }
153         if (manager6 != null) {
154             manager6.shutdown();
155         }
156 
157         /*
158          * We can't assert this here, since one of these tests intentionally doesn't
159          * shutdown the last cache manager - intended to test the shutdown hooks...
160          */
161         //RetryAssert.assertBy(30, TimeUnit.SECONDS, new Callable<Set<Thread>>() {
162         //    public Set<Thread> call() throws Exception {
163         //        return getActiveReplicationThreads();
164         //    }
165         //}, IsEmptyCollection.<Thread>empty());
166     }
167 
168 
169     /***
170      * Are all of the replicated caches bound to the RMI listener?
171      */
172     @Test
173     public void testPeersBound() {
174 
175         List cachePeers1 = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).getBoundCachePeers();
176         assertEquals(55, cachePeers1.size());
177         String[] boundCachePeers1 = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
178         assertEquals(55, boundCachePeers1.length);
179         assertEquals(cachePeers1.size(), boundCachePeers1.length);
180 
181         List cachePeers2 = ((RMICacheManagerPeerListener) manager2.getCachePeerListener("RMI")).getBoundCachePeers();
182         assertEquals(55, cachePeers2.size());
183         String[] boundCachePeers2 = ((RMICacheManagerPeerListener) manager2.getCachePeerListener("RMI")).listBoundRMICachePeers();
184         assertEquals(55, boundCachePeers2.length);
185         assertEquals(cachePeers2.size(), boundCachePeers2.length);
186 
187 
188         List cachePeers3 = ((RMICacheManagerPeerListener) manager3.getCachePeerListener("RMI")).getBoundCachePeers();
189         assertEquals(55, cachePeers3.size());
190         String[] boundCachePeers3 = ((RMICacheManagerPeerListener) manager3.getCachePeerListener("RMI")).listBoundRMICachePeers();
191         assertEquals(55, boundCachePeers3.length);
192         assertEquals(cachePeers3.size(), boundCachePeers3.length);
193 
194 
195         List cachePeers4 = ((RMICacheManagerPeerListener) manager4.getCachePeerListener("RMI")).getBoundCachePeers();
196         assertEquals(55, cachePeers4.size());
197         String[] boundCachePeers4 = ((RMICacheManagerPeerListener) manager4.getCachePeerListener("RMI")).listBoundRMICachePeers();
198         assertEquals(55, boundCachePeers4.length);
199         assertEquals(cachePeers4.size(), boundCachePeers4.length);
200 
201         List cachePeers5 = ((RMICacheManagerPeerListener) manager5.getCachePeerListener("RMI")).getBoundCachePeers();
202         assertEquals(55, cachePeers5.size());
203         String[] boundCachePeers5 = ((RMICacheManagerPeerListener) manager5.getCachePeerListener("RMI")).listBoundRMICachePeers();
204         assertEquals(55, boundCachePeers5.length);
205         assertEquals(cachePeers5.size(), boundCachePeers5.length);
206     }
207 
208 
209     /***
210      * Are all of the replicated caches bound to the listener and working?
211      */
212     @Test
213     public void testBoundListenerPeers() throws RemoteException {
214 
215         String[] boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
216         validateBoundCachePeer(boundCachePeers);
217     }
218 
219     /***
220      * Are all of the CachePeers for replicated caches bound to the listener and working?
221      */
222     @Test
223     public void testBoundListenerPeersAfterDefaultCacheAdd() throws RemoteException {
224 
225         String[] boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
226         assertEquals(55, boundCachePeers.length);
227         validateBoundCachePeer(boundCachePeers);
228 
229         //Add from default which is has a CacheReplicator configured.
230         manager1.addCache("fromDefaultCache");
231         boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
232         assertEquals(56, boundCachePeers.length);
233         validateBoundCachePeer(boundCachePeers);
234     }
235 
236     /***
237      * Are all of the CachePeers for replicated caches bound to the listener and working?
238      */
239     @Test
240     public void testBoundListenerPeersAfterProgrammaticCacheAdd() throws RemoteException {
241 
242         String[] boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
243         assertEquals(55, boundCachePeers.length);
244         validateBoundCachePeer(boundCachePeers);
245 
246         //Add from default which is has a CacheReplicator configured.
247 
248 
249         RMICacheReplicatorFactory factory = new RMICacheReplicatorFactory();
250         CacheEventListener replicatingListener = factory.createCacheEventListener(null);
251         Cache cache = new Cache("programmaticallyAdded",
252                 10, null, true, System.getProperty("java.io.tmpdir"), false, 10, 10, false, 60, null);
253         cache.getCacheEventNotificationService().registerListener(replicatingListener);
254 
255         manager1.addCache(cache);
256         boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
257         assertEquals(56, boundCachePeers.length);
258         validateBoundCachePeer(boundCachePeers);
259     }
260 
261     /***
262      * Are all of the CachePeers for replicated caches bound to the listener and working?
263      */
264     @Test
265     public void testBoundListenerPeersAfterCacheRemove() throws RemoteException {
266         String[] boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
267         assertEquals(55, boundCachePeers.length);
268         validateBoundCachePeer(boundCachePeers);
269 
270         //Remove a replicated cache
271         manager1.removeCache("sampleCache1");
272         boundCachePeers = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).listBoundRMICachePeers();
273         assertEquals(54, boundCachePeers.length);
274         validateBoundCachePeer(boundCachePeers);
275     }
276 
277 
278     private void validateBoundCachePeer(String[] boundCachePeers) {
279         for (String boundCacheName : boundCachePeers) {
280             Remote remote = ((RMICacheManagerPeerListener) manager1.getCachePeerListener("RMI")).lookupPeer(boundCacheName);
281             assertNotNull(remote);
282         }
283     }
284 
285 
286     /***
287      * Does the RMI listener stop?
288      */
289     @Test
290     public void testListenerShutsdown() {
291         CacheManagerPeerListener cachePeerListener = manager1.getCachePeerListener("RMI");
292         List cachePeers1 = cachePeerListener.getBoundCachePeers();
293         assertEquals(55, cachePeers1.size());
294         assertEquals(Status.STATUS_ALIVE, cachePeerListener.getStatus());
295 
296         manager1.shutdown();
297         assertEquals(Status.STATUS_SHUTDOWN, cachePeerListener.getStatus());
298 
299     }
300 
301     /***
302      * Does the RMI listener stop?
303      * <p/>
304      * This test does not actually do test the shutdown hook automatically. But you should be able to
305      * see "VM shutting down with the RMICacheManagerPeerListener for localhost still active. Calling dispose..."
306      * in the log with FINE level when this test is run individually or as the last test in the run. i.e. on VM shutdown.
307      */
308     @Test
309     public void testListenerShutsdownFromShutdownHook() {
310         CacheManager manager = new CacheManager(AbstractCacheTest.TEST_CONFIG_DIR + "distribution/ehcache-distributed6.xml");
311         try {
312             CacheManagerPeerListener cachePeerListener = manager.getCachePeerListener("RMI");
313             List cachePeers1 = cachePeerListener.getBoundCachePeers();
314             assertEquals(55, cachePeers1.size());
315             assertEquals(Status.STATUS_ALIVE, cachePeerListener.getStatus());
316         } finally {
317             /*
318              * This test intentionally doesn't call shutdown - the VM should do it for us.
319              */
320             //manager.shutdown();
321         }
322     }
323 }