1 package com.atlassian.cache.ehcache.cluster;
2
3 import java.util.List;
4 import java.util.concurrent.atomic.AtomicInteger;
5
6 import com.atlassian.cache.Cache;
7 import com.atlassian.cache.CachedReference;
8 import com.atlassian.cache.ManagedCache;
9 import com.atlassian.cache.ehcache.EhCacheManager;
10
11 import com.google.common.base.Function;
12 import com.google.common.base.Throwables;
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.collect.Iterables;
15
16 import org.junit.rules.ExternalResource;
17
18 import net.sf.ehcache.CacheManager;
19 import net.sf.ehcache.config.Configuration;
20
21 import static com.atlassian.cache.ehcache.cluster.EhCacheConfigurationFactory.newConfiguration;
22
23
24
25
26 public class EhCacheCluster extends ExternalResource
27 {
28 private final AtomicInteger activeCount = new AtomicInteger();
29 private final int count;
30
31 private volatile List<CacheManager> rawNodes = ImmutableList.of();
32 private volatile List<EhCacheManager> decoratedNodes = ImmutableList.of();
33
34 public EhCacheCluster(final int count)
35 {
36 this.count = count;
37 }
38
39 @Override
40 protected void after()
41 {
42 try
43 {
44 if (activeCount.decrementAndGet() == 0)
45 {
46
47 final List<CacheManager> nodes = rawNodes;
48 decoratedNodes = null;
49 rawNodes = null;
50 for (CacheManager instance : nodes)
51 {
52 instance.shutdown();
53 }
54 }
55 }
56 finally
57 {
58 super.after();
59 }
60 }
61
62 @Override
63 protected void before() throws Throwable
64 {
65 super.before();
66
67 if (activeCount.getAndIncrement() == 0)
68 {
69
70 rawNodes = EhCacheCluster.newCluster(count);
71 decoratedNodes = ImmutableList.copyOf(Iterables.transform(rawNodes,
72 new Function<CacheManager, EhCacheManager>()
73 {
74 @Override
75 public EhCacheManager apply(CacheManager rawNode)
76 {
77 return new EhCacheManager(rawNode, null);
78 }
79 }));
80 }
81 }
82
83 public EhCacheManager getNode(int index)
84 {
85 return decoratedNodes.get(index);
86 }
87
88 public void reset()
89 {
90 if (size() > 0)
91 {
92 final EhCacheManager node = decoratedNodes.get(0);
93 for (ManagedCache cache : node.getManagedCaches())
94 {
95 if (cache instanceof Cache<?,?>)
96 {
97 ((Cache<?,?>)cache).removeAll();
98 }
99 else
100 {
101 ((CachedReference<?>)cache).reset();
102 }
103 }
104 }
105 }
106
107 public int size()
108 {
109 return decoratedNodes.size();
110 }
111
112 public static EhCacheCluster createCluster(int count)
113 {
114 return new EhCacheCluster(count);
115 }
116
117 public static List<CacheManager> newCluster(final int maxNodeId)
118 {
119 final ImmutableList.Builder<CacheManager> nodes = new ImmutableList.Builder<CacheManager>();
120 for (int thisNodeId = 1; thisNodeId <= maxNodeId; ++thisNodeId)
121 {
122 final Configuration config = newConfiguration(thisNodeId, maxNodeId);
123 final CacheManager ehcache = CacheManager.newInstance(config);
124 nodes.add(ehcache);
125 }
126 return nodes.build();
127 }
128
129 public static void clusteredTest(int nodeCount, ClusteredTest test) throws Exception
130 {
131 final EhCacheCluster cluster = new EhCacheCluster(nodeCount);
132 try
133 {
134 cluster.before();
135 try
136 {
137 test.runTest(cluster);
138 }
139 finally
140 {
141 cluster.after();
142 }
143 }
144 catch (Throwable e)
145 {
146 Throwables.propagate(e);
147 }
148 }
149
150 public interface ClusteredTest
151 {
152 void runTest(EhCacheCluster cluster) throws Exception;
153 }
154 }