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.io.IOException;
23  import java.net.InetAddress;
24  import java.net.NetworkInterface;
25  import java.util.Enumeration;
26  
27  import org.apache.commons.jcs3.auxiliary.AuxiliaryCache;
28  import org.apache.commons.jcs3.auxiliary.MockCacheEventLogger;
29  import org.apache.commons.jcs3.auxiliary.remote.MockRemoteCacheListener;
30  import org.apache.commons.jcs3.auxiliary.remote.RemoteCacheAttributes;
31  import org.apache.commons.jcs3.auxiliary.remote.RemoteCacheFactory;
32  import org.apache.commons.jcs3.auxiliary.remote.RemoteCacheManager;
33  import org.apache.commons.jcs3.engine.CacheElement;
34  import org.apache.commons.jcs3.engine.CacheStatus;
35  import org.apache.commons.jcs3.engine.behavior.ICacheElement;
36  import org.apache.commons.jcs3.engine.control.MockCompositeCacheManager;
37  import org.apache.commons.jcs3.engine.control.MockElementSerializer;
38  import org.apache.commons.jcs3.utils.net.HostNameUtil;
39  import org.apache.commons.jcs3.utils.timing.SleepUtil;
40  import org.junit.AfterClass;
41  import org.junit.Assert;
42  import org.junit.BeforeClass;
43  import org.junit.FixMethodOrder;
44  import org.junit.Test;
45  import org.junit.runners.MethodSorters;
46  
47  /**
48   * These tests startup the remote server and make requests to it.
49   */
50  @FixMethodOrder(MethodSorters.NAME_ASCENDING)
51  public class BasicRemoteCacheClientServerUnitTest extends Assert
52  {
53      private static final int LOCAL_PORT = 12020;
54  
55     /**
56       * Server instance to use in the tests.
57       */
58      private static RemoteCacheServer<String, String> server;
59  
60      /**
61       * Factory instance to use in the tests.
62       */
63      private static RemoteCacheFactory factory;
64  
65      /**
66       * the remote server port
67       */
68      private static int remotePort;
69  
70      /**
71       * Starts the server. This is not in a setup, since the server is slow to kill right now.
72       */
73      @BeforeClass
74      public static void setup()
75      {
76          // Add some debug to try and find out why test fails on Jenkins/Continuum
77          try {
78              final InetAddress lh = InetAddress.getByName("localhost");
79              System.out.println("localhost="+lh);
80              final InetAddress ina=InetAddress.getLocalHost();
81              System.out.println("InetAddress.getLocalHost()="+ina);
82              // Iterate all NICs (network interface cards)...
83              final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
84              if ( ifaces != null ) {
85              while ( ifaces.hasMoreElements() )
86                  {
87                      final NetworkInterface iface = ifaces.nextElement();
88                      // Iterate all IP addresses assigned to each card...
89                      for ( final Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); )
90                      {
91                          final InetAddress inetAddr = inetAddrs.nextElement();
92                          final boolean loopbackAddress = inetAddr.isLoopbackAddress();
93                          final boolean siteLocalAddress = inetAddr.isSiteLocalAddress();
94                          System.out.println("Found: "+ inetAddr +
95                                  " isLoopback: " + loopbackAddress +
96                                  " isSiteLocal: " + siteLocalAddress +
97                                  ((!loopbackAddress && siteLocalAddress) ? " *" : ""));
98                      }
99                  }
100             }
101         } catch (final Exception e) {
102             e.printStackTrace();
103         }
104         // end of debug
105         final String configFile = "TestRemoteCacheClientServer.ccf";
106         server = RemoteCacheServerStartupUtil.startServerUsingProperties(configFile);
107         factory = new RemoteCacheFactory();
108         factory.initialize();
109         remotePort = server.remoteCacheServerAttributes.getRemoteLocation().getPort();
110     }
111 
112     @AfterClass
113     public static void stop() throws IOException
114     {
115         if (server != null) { // in case setup failed, no point throwing NPE as well
116             server.shutdown("localhost", remotePort);
117         }
118     }
119 
120     /**
121      * Verify that we can start the remote cache server. Send an item to the remote. Verify that the
122      * remote put count goes up. If we go through JCS, the manager will be shared and we will get
123      * into an endless loop. We will use a mock cache manager instead.
124      * <p>
125      * The remote server uses the real JCS. We can verify that items are added to JCS behind the
126      * server by calling get. We cannot access it directly via JCS since it is serialized.
127      * <p>
128      * This test uses a mock injected client to test a normal server.
129      * <p>
130      *
131      * @throws Exception
132      */
133     @Test
134     public void test1SinglePut()
135             throws Exception
136             {
137         // SETUP
138         final MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
139 
140         final RemoteCacheAttributes attributes = new RemoteCacheAttributes();
141         attributes.setRemoteLocation("localhost", remotePort);
142         attributes.setLocalPort(LOCAL_PORT);
143         attributes.setCacheName("testSinglePut");
144 
145         final RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
146         final AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
147 
148         // DO WORK
149         final int numPutsPrior = server.getPutCount();
150         final ICacheElement<String, String> element = new CacheElement<>(cache.getCacheName(), "key", "value");
151         cache.update(element);
152         SleepUtil.sleepAtLeast(200);
153 
154         // VERIFY
155         try
156         {
157             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
158             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
159         }
160         catch (final junit.framework.AssertionFailedError e)
161         {
162             System.out.println(cache.getStats());
163             System.out.println(server.getStats());
164             throw e;
165         }
166 
167         // DO WORK
168         final ICacheElement<String, String> result = cache.get("key");
169 
170         // VERIFY
171         assertEquals("Wrong element.", element.getVal(), result.getVal());
172             }
173 
174     /**
175      * Verify that we can remove an item via the remote server.
176      * <p>
177      *
178      * @throws Exception
179      */
180     @Test
181     public void test2PutRemove()
182             throws Exception
183             {
184         // SETUP
185         final MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
186 
187         final RemoteCacheAttributes attributes = new RemoteCacheAttributes();
188         attributes.setRemoteLocation("localhost", remotePort);
189         attributes.setLocalPort(LOCAL_PORT);
190         attributes.setCacheName("testPutRemove");
191 
192         final MockCacheEventLogger cacheEventLogger = new MockCacheEventLogger();
193 
194         final RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, cacheEventLogger, null);
195         final AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
196 
197         // DO WORK
198         final int numPutsPrior = server.getPutCount();
199         final ICacheElement<String, String> element = new CacheElement<>(cache.getCacheName(), "key", "value");
200         cache.update(element);
201         SleepUtil.sleepAtLeast(50);
202 
203         // VERIFY
204         try
205         {
206             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
207             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
208         }
209         catch (final junit.framework.AssertionFailedError e)
210         {
211             System.out.println(cache.getStats());
212             System.out.println(server.getStats());
213             throw e;
214         }
215 
216         // DO WORK
217         final ICacheElement<String, String> result = cache.get("key");
218 
219         // VERIFY
220         assertEquals("Wrong element.", element.getVal(), result.getVal());
221 
222         // DO WORK
223         cache.remove("key");
224         SleepUtil.sleepAtLeast(200);
225         final ICacheElement<String, String> resultAfterRemote = cache.get("key");
226 
227         // VERIFY
228         assertNull("Element resultAfterRemote should be null.", resultAfterRemote);
229             }
230 
231     /**
232      * Register a listener with the server. Send an update. Verify that the listener received it.
233      *
234      * @throws Exception
235      */
236     @Test
237     public void test3PutAndListen()
238             throws Exception
239             {
240         // SETUP
241         final MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
242 
243         final RemoteCacheAttributes attributes = new RemoteCacheAttributes();
244         attributes.setRemoteLocation("localhost", remotePort);
245         attributes.setLocalPort(LOCAL_PORT);
246         attributes.setCacheName("testPutAndListen");
247 
248         final RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
249         final AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
250 
251         final MockRemoteCacheListener<String, String> listener = new MockRemoteCacheListener<>();
252         server.addCacheListener(cache.getCacheName(), listener);
253 
254         // DO WORK
255         final int numPutsPrior = server.getPutCount();
256         final ICacheElement<String, String> element = new CacheElement<>(cache.getCacheName(), "key", "value");
257         cache.update(element);
258         SleepUtil.sleepAtLeast(50);
259 
260         // VERIFY
261         try
262         {
263             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
264             assertEquals("Wrong number of puts", 1, server.getPutCount() - numPutsPrior);
265             assertEquals("Wrong number of puts to listener.", 1, listener.putCount);
266         }
267         catch (final junit.framework.AssertionFailedError e)
268         {
269             System.out.println(cache.getStats());
270             System.out.println(server.getStats());
271             throw e;
272         }
273         finally
274         {
275             // remove from all regions.
276             server.removeCacheListener(listener);
277         }
278     }
279 
280     /**
281      * Register a listener with the server. Send an update. Verify that the listener received it.
282      *
283      * @throws Exception
284      */
285     @Test
286     public void test4PutaMultipleAndListen()
287             throws Exception
288     {
289         // SETUP
290         final MockCompositeCacheManager compositeCacheManager = new MockCompositeCacheManager();
291 
292         final RemoteCacheAttributes attributes = new RemoteCacheAttributes();
293         attributes.setRemoteLocation("localhost", remotePort);
294         attributes.setLocalPort(LOCAL_PORT);
295         attributes.setCacheName("testPutaMultipleAndListen");
296 
297         final RemoteCacheManager remoteCacheManager = factory.getManager(attributes, compositeCacheManager, new MockCacheEventLogger(), new MockElementSerializer());
298         final AuxiliaryCache<String, String> cache = remoteCacheManager.getCache(attributes);
299 
300         final MockRemoteCacheListener<String, String> listener = new MockRemoteCacheListener<>();
301         server.addCacheListener(cache.getCacheName(), listener);
302 
303         // DO WORK
304         final int numPutsPrior = server.getPutCount();
305         final int numToPut = 100;
306         for (int i = 0; i < numToPut; i++)
307         {
308             final ICacheElement<String, String> element = new CacheElement<>(cache.getCacheName(), "key" + 1, "value" + i);
309             cache.update(element);
310         }
311         SleepUtil.sleepAtLeast(500);
312 
313         // VERIFY
314         try
315         {
316             assertEquals("Cache is alive", CacheStatus.ALIVE, cache.getStatus());
317             assertEquals("Wrong number of puts", numToPut, server.getPutCount() - numPutsPrior);
318             assertEquals("Wrong number of puts to listener.", numToPut, listener.putCount);
319         }
320         catch (final junit.framework.AssertionFailedError e)
321         {
322             System.out.println(cache.getStats());
323             System.out.println(server.getStats());
324             throw e;
325         }
326     }
327 
328     @Test
329     public void testLocalHost() throws Exception
330     {
331         final InetAddress byName = InetAddress.getByName("localhost");
332         assertTrue("Expected localhost (" + byName.getHostAddress() + ") to be a loopback address", byName.isLoopbackAddress());
333         final InetAddress localHost = HostNameUtil.getLocalHostLANAddress();
334         assertTrue("Expected getLocalHostLANAddress() (" + localHost + ") to return a site local address", localHost.isSiteLocalAddress());
335     }
336 }