View Javadoc
1   package org.apache.commons.jcs3.auxiliary.remote.server;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.HashSet;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Properties;
26  
27  import org.apache.commons.jcs3.auxiliary.MockCacheEventLogger;
28  import org.apache.commons.jcs3.auxiliary.remote.MockRemoteCacheListener;
29  import org.apache.commons.jcs3.utils.timing.SleepUtil;
30  import org.apache.commons.jcs3.auxiliary.remote.RemoteUtils;
31  import org.apache.commons.jcs3.auxiliary.remote.server.behavior.IRemoteCacheServerAttributes;
32  import org.apache.commons.jcs3.auxiliary.remote.server.behavior.RemoteType;
33  import org.apache.commons.jcs3.engine.CacheElement;
34  import org.apache.commons.jcs3.engine.behavior.ICacheElement;
35  
36  import junit.framework.TestCase;
37  
38  /**
39   * Since the server does not know that it is a server, it is easy to unit test. The factory does all
40   * the rmi work.
41   */
42  public class RemoteCacheServerUnitTest
43      extends TestCase
44  {
45      private static final String expectedIp1 = "adfasdf";
46      private static final String expectedIp2 = "adsfadsafaf";
47  
48      private RemoteCacheServer<String, String> server;
49  
50      @Override
51      protected void setUp() throws Exception
52      {
53          super.setUp();
54  
55          final IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
56          rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
57          final Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
58          this.server = new RemoteCacheServer<>( rcsa, config );
59      }
60  
61      @Override
62      protected void tearDown() throws Exception
63      {
64          this.server.shutdown();
65  
66          super.tearDown();
67      }
68  
69      /**
70       * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
71       * and verify that the second gets an id of 2.
72       * <p>
73       * @throws Exception
74       */
75      public void testAddListenerToCache_LOCALtype()
76          throws Exception
77      {
78          final MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<>();
79          mockListener1.remoteType = RemoteType.LOCAL;
80          mockListener1.localAddress = expectedIp1;
81          final MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<>();
82          mockListener1.remoteType = RemoteType.LOCAL;
83          mockListener2.localAddress = expectedIp2;
84  
85          final String cacheName = "testAddListener";
86  
87          // DO WORK
88          server.addCacheListener( cacheName, mockListener1 );
89          server.addCacheListener( cacheName, mockListener2 );
90  
91          // VERIFY
92          assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
93          assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
94          assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
95          assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
96      }
97  
98      /**
99       * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
100      * and verify that the second gets an id of 2.
101      * <p>
102      * @throws Exception
103      */
104     public void testAddListenerToCache_CLUSTERtype()
105         throws Exception
106     {
107         final MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<>();
108         mockListener1.remoteType = RemoteType.CLUSTER;
109         mockListener1.localAddress = expectedIp1;
110         final MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<>();
111         mockListener1.remoteType = RemoteType.CLUSTER;
112         mockListener2.localAddress = expectedIp2;
113 
114         final String cacheName = "testAddListener";
115 
116         // DO WORK
117         server.addCacheListener( cacheName, mockListener1 );
118         server.addCacheListener( cacheName, mockListener2 );
119 
120         // VERIFY
121         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
122         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
123         assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
124         assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
125     }
126 
127     // TODO: This test only works if preconfigured remote caches exist. Need to fix.
128 //    /**
129 //     * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
130 //     * and verify that the second gets an id of 2.
131 //     * <p>
132 //     * @throws Exception
133 //     */
134 //    public void testAddListener_ToAll()
135 //        throws Exception
136 //    {
137 //        MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<>();
138 //        mockListener1.localAddress = expectedIp1;
139 //        MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<>();
140 //        mockListener2.localAddress = expectedIp2;
141 //
142 //        // DO WORK
143 //        // don't specify the cache name
144 //        server.addCacheListener( mockListener1 );
145 //        server.addCacheListener( mockListener2 );
146 //
147 //        // VERIFY
148 //        assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
149 //        assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
150 //        assertEquals( "Wrong ip.", expectedIp1, server.getExtraInfoForRequesterId( 1 ) );
151 //        assertEquals( "Wrong ip.", expectedIp2, server.getExtraInfoForRequesterId( 2 ) );
152 //    }
153 
154     /**
155      * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
156      * and verify that the second gets an id of 2. Call remove Listener and verify that it is
157      * removed.
158      * <p>
159      * @throws Exception
160      */
161     public void testAddListener_ToAllThenRemove()
162         throws Exception
163     {
164         final MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<>();
165         final MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<>();
166 
167         final String cacheName = "testAddListenerToAllThenRemove";
168 
169         // DO WORK
170         server.addCacheListener( cacheName, mockListener1 );
171         server.addCacheListener( cacheName, mockListener2 );
172 
173         // VERIFY
174         assertEquals( "Wrong number of listeners.", 2, server.getCacheListeners( cacheName ).eventQMap.size() );
175         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
176         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
177 
178         // DO WORK
179         server.removeCacheListener( cacheName, mockListener1.getListenerId() );
180         assertEquals( "Wrong number of listeners.", 1, server.getCacheListeners( cacheName ).eventQMap.size() );
181     }
182 
183     /**
184      * Add a listener. Pass the id of 0, verify that the server sets a new listener id. Do another
185      * and verify that the second gets an id of 2. Call remove Listener and verify that it is
186      * removed.
187      * <p>
188      * @throws Exception
189      */
190     public void testAddListener_ToAllThenRemove_clusterType()
191         throws Exception
192     {
193         final MockRemoteCacheListener<String, String> mockListener1 = new MockRemoteCacheListener<>();
194         mockListener1.remoteType = RemoteType.CLUSTER;
195         final MockRemoteCacheListener<String, String> mockListener2 = new MockRemoteCacheListener<>();
196         mockListener2.remoteType = RemoteType.CLUSTER;
197 
198         final String cacheName = "testAddListenerToAllThenRemove";
199 
200         // DO WORK
201         server.addCacheListener( cacheName, mockListener1 );
202         server.addCacheListener( cacheName, mockListener2 );
203 
204         // VERIFY
205         assertEquals( "Wrong number of listeners.", 0, server.getCacheListeners( cacheName ).eventQMap.size() );
206         assertEquals( "Wrong number of listeners.", 2, server.getClusterListeners( cacheName ).eventQMap.size() );
207         assertEquals( "Wrong listener id.", 1, mockListener1.getListenerId() );
208         assertEquals( "Wrong listener id.", 2, mockListener2.getListenerId() );
209 
210         // DO WORK
211         server.removeCacheListener( cacheName, mockListener1.getListenerId() );
212         assertEquals( "Wrong number of listeners.", 1, server.getClusterListeners( cacheName ).eventQMap.size() );
213         assertNull( "Should be no entry in the ip map.", server.getExtraInfoForRequesterId( 1 ) );
214     }
215 
216     /**
217      * Register a listener and then verify that it is called when we put using a different listener
218      * id.
219      * @throws Exception
220      */
221     public void testSimpleRegisterListenerAndPut()
222         throws Exception
223     {
224         final IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
225         rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
226 
227         final Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
228         final MockRemoteCacheListener<String, Long> mockListener = new MockRemoteCacheListener<>();
229         final RemoteCacheServer<String, Long> server = new RemoteCacheServer<>( rcsa, config );
230 
231         final String cacheName = "testSimpleRegisterListenerAndPut";
232         server.addCacheListener( cacheName, mockListener );
233 
234         // DO WORK
235         final List<ICacheElement<String, Long>> inputItems = new LinkedList<>();
236         final int numToPut = 10;
237 
238         for ( int i = 0; i < numToPut; i++ )
239         {
240             final ICacheElement<String, Long> element = new CacheElement<>( cacheName, String.valueOf( i ), Long.valueOf( i ) );
241             inputItems.add( element );
242             server.update( element, 9999 );
243         }
244 
245         Thread.sleep( 100 );
246         Thread.yield();
247         Thread.sleep( 100 );
248 
249         // VERIFY
250         assertEquals( "Wrong number of items put to listener.", numToPut, mockListener.putItems.size() );
251         for ( int i = 0; i < numToPut; i++ )
252         {
253             assertEquals( "Wrong item.", inputItems.get( i ), mockListener.putItems.get( i ) );
254         }
255 
256         server.shutdown();
257     }
258 
259     /**
260      * Register a listener and then verify that it is called when we put using a different listener
261      * id. The updates should come from a cluster listener and local cluster consistency should be
262      * true.
263      * <p>
264      * @throws Exception
265      */
266     public void testSimpleRegisterListenerAndPut_FromClusterWithLCC()
267         throws Exception
268     {
269         // SETUP
270         final IRemoteCacheServerAttributes rcsa = new RemoteCacheServerAttributes();
271         rcsa.setLocalClusterConsistency( true );
272         rcsa.setConfigFileName( "/TestRemoteCacheServer.ccf" );
273         final Properties config = RemoteUtils.loadProps(rcsa.getConfigFileName());
274         final RemoteCacheServer<String, Long> server = new RemoteCacheServer<>( rcsa, config );
275 
276         // this is to get the listener id for inserts.
277         final MockRemoteCacheListener<String, Long> clusterListener = new MockRemoteCacheListener<>();
278         clusterListener.remoteType = RemoteType.CLUSTER;
279 
280         // this should get the updates
281         final MockRemoteCacheListener<String, Long> localListener = new MockRemoteCacheListener<>();
282         localListener.remoteType = RemoteType.LOCAL;
283 
284         final String cacheName = "testSimpleRegisterListenerAndPut_FromClusterWithLCC";
285         server.addCacheListener( cacheName, clusterListener );
286         server.addCacheListener( cacheName, localListener );
287 
288         // DO WORK
289         final List<ICacheElement<String, Long>> inputItems = new LinkedList<>();
290         final int numToPut = 10;
291 
292         for ( int i = 0; i < numToPut; i++ )
293         {
294             final ICacheElement<String, Long> element = new CacheElement<>( cacheName, String.valueOf( i ), Long.valueOf( i ) );
295             inputItems.add( element );
296             // update using the cluster listener id
297             server.update( element, clusterListener.getListenerId() );
298         }
299 
300         SleepUtil.sleepAtLeast( 200 );
301         Thread.yield();
302         SleepUtil.sleepAtLeast( 200 );
303 
304         // VERIFY
305         assertEquals( "Wrong number of items put to listener.", numToPut, localListener.putItems.size() );
306         for ( int i = 0; i < numToPut; i++ )
307         {
308             assertEquals( "Wrong item.", inputItems.get( i ), localListener.putItems.get( i ) );
309         }
310 
311         server.shutdown();
312     }
313 
314     /**
315      * Register a listener and then verify that it is called when we put using a different listener
316      * id.
317      * @throws Exception
318      */
319     public void testSimpleRegisterListenerAndRemove()
320         throws Exception
321     {
322         final MockRemoteCacheListener<String, String> mockListener = new MockRemoteCacheListener<>();
323 
324         final String cacheName = "testSimpleRegisterListenerAndPut";
325         server.addCacheListener( cacheName, mockListener );
326 
327         // DO WORK
328         final int numToPut = 10;
329 
330         for ( int i = 0; i < numToPut; i++ )
331         {
332             // use a junk listener id
333             server.remove( cacheName, String.valueOf( i ), 9999 );
334         }
335 
336         Thread.sleep( 100 );
337         Thread.yield();
338         Thread.sleep( 100 );
339 
340         // VERIFY
341         assertEquals( "Wrong number of items removed from listener.", numToPut, mockListener.removedKeys.size() );
342         for ( int i = 0; i < numToPut; i++ )
343         {
344             assertEquals( "Wrong key.", String.valueOf( i ), mockListener.removedKeys.get( i ) );
345         }
346     }
347 
348     /**
349      * Verify event log calls.
350      * <p>
351      * @throws Exception
352      */
353     public void testUpdate_simple()
354         throws Exception
355     {
356         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
357         server.setCacheEventLogger( cacheEventLogger );
358 
359         final ICacheElement<String, String> item = new CacheElement<>( "region", "key", "value" );
360 
361         // DO WORK
362         server.update( item );
363 
364         // VERIFY
365         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
366         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
367     }
368 
369     /**
370      * Verify event log calls.
371      * <p>
372      * @throws Exception
373      */
374     public void testGet_simple()
375         throws Exception
376     {
377         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
378         server.setCacheEventLogger( cacheEventLogger );
379 
380         // DO WORK
381         server.get( "region", "key" );
382 
383         // VERIFY
384         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
385         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
386     }
387 
388     /**
389      * Verify event log calls.
390      * <p>
391      * @throws Exception
392      */
393     public void testGetMatching_simple()
394         throws Exception
395     {
396         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
397         server.setCacheEventLogger( cacheEventLogger );
398 
399         // DO WORK
400         server.getMatching( "region", "pattern", 0 );
401 
402         // VERIFY
403         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
404         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
405     }
406 
407     /**
408      * Verify event log calls.
409      * <p>
410      * @throws Exception
411      */
412     public void testGetMultiple_simple()
413         throws Exception
414     {
415         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
416         server.setCacheEventLogger( cacheEventLogger );
417 
418         // DO WORK
419         server.getMultiple( "region", new HashSet<>() );
420 
421         // VERIFY
422         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
423         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
424     }
425 
426     /**
427      * Verify event log calls.
428      * <p>
429      * @throws Exception
430      */
431     public void testRemove_simple()
432         throws Exception
433     {
434         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
435         server.setCacheEventLogger( cacheEventLogger );
436 
437         // DO WORK
438         server.remove( "region", "key" );
439 
440         // VERIFY
441         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
442         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
443     }
444 
445     /**
446      * Verify event log calls.
447      * <p>
448      * @throws Exception
449      */
450     public void testRemoveAll_simple()
451         throws Exception
452     {
453         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
454         server.setCacheEventLogger( cacheEventLogger );
455 
456         // DO WORK
457         server.removeAll( "region" );
458 
459         // VERIFY
460         assertEquals( "Start should have been called.", 1, cacheEventLogger.startICacheEventCalls );
461         assertEquals( "End should have been called.", 1, cacheEventLogger.endICacheEventCalls );
462     }
463 }