1 package com.atlassian.cache.ehcache;
2
3 import net.sf.ehcache.distribution.CacheReplicator;
4 import net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator;
5 import net.sf.ehcache.event.CacheEventListener;
6 import net.sf.ehcache.event.CacheEventListenerFactory;
7 import net.sf.ehcache.util.PropertyUtil;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10
11 import java.util.Properties;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class RMICacheReplicatorFactory extends CacheEventListenerFactory {
31
32
33
34
35
36 protected static final int DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS = 1000;
37
38
39
40
41 protected static final int DEFAULT_ASYNCHRONOUS_REPLICATION_MAXIMUM_BATCH_SIZE = 1000;
42
43 private static final Logger LOG = LoggerFactory.getLogger(RMICacheReplicatorFactory.class.getName());
44 private static final String REPLICATE_PUTS = "replicatePuts";
45 private static final String REPLICATE_PUTS_VIA_COPY = "replicatePutsViaCopy";
46 private static final String REPLICATE_UPDATES = "replicateUpdates";
47 private static final String REPLICATE_UPDATES_VIA_COPY = "replicateUpdatesViaCopy";
48 private static final String REPLICATE_REMOVALS = "replicateRemovals";
49 static final String REPLICATE_ASYNCHRONOUSLY = "replicateAsynchronously";
50 private static final String ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS = "asynchronousReplicationIntervalMillis";
51 private static final String ASYNCHRONOUS_REPLICATION_MAXIMUM_BATCH_SIZE = "asynchronousReplicationMaximumBatchSize";
52 private static final int MINIMUM_REASONABLE_INTERVAL = 10;
53
54 private static boolean extractBoolean(final String key, final Properties properties) {
55 String booleanString = PropertyUtil.extractAndLogProperty(key, properties);
56 return booleanString == null || PropertyUtil.parseBoolean(booleanString);
57 }
58
59
60
61
62
63
64
65 private static int extractReplicationIntervalMilis(Properties properties) {
66 int asynchronousReplicationIntervalMillis;
67 String asynchronousReplicationIntervalMillisString =
68 PropertyUtil.extractAndLogProperty(ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS, properties);
69 if (asynchronousReplicationIntervalMillisString != null) {
70 try {
71 int asynchronousReplicationIntervalMillisCandidate =
72 Integer.parseInt(asynchronousReplicationIntervalMillisString);
73 if (asynchronousReplicationIntervalMillisCandidate < MINIMUM_REASONABLE_INTERVAL) {
74 LOG.debug("Trying to set the asynchronousReplicationIntervalMillis to an unreasonable number." +
75 " Using the default instead.");
76 asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
77 } else {
78 asynchronousReplicationIntervalMillis = asynchronousReplicationIntervalMillisCandidate;
79 }
80 } catch (NumberFormatException e) {
81 LOG.warn("Number format exception trying to set asynchronousReplicationIntervalMillis. " +
82 "Using the default instead. String value was: '" + asynchronousReplicationIntervalMillisString + "'");
83 asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
84 }
85 } else {
86 asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
87 }
88 return asynchronousReplicationIntervalMillis;
89 }
90
91
92
93
94
95
96
97 private static int extractMaximumBatchSize(final Properties properties) {
98 String maximumBatchSizeString =
99 PropertyUtil.extractAndLogProperty(ASYNCHRONOUS_REPLICATION_MAXIMUM_BATCH_SIZE, properties);
100 if (maximumBatchSizeString == null) {
101 return DEFAULT_ASYNCHRONOUS_REPLICATION_MAXIMUM_BATCH_SIZE;
102 } else {
103 try {
104 return Integer.parseInt(maximumBatchSizeString);
105 } catch (NumberFormatException e) {
106 LOG.warn("Number format exception trying to set maximumBatchSize. " +
107 "Using the default instead. String value was: '" + maximumBatchSizeString + "'");
108 return DEFAULT_ASYNCHRONOUS_REPLICATION_MAXIMUM_BATCH_SIZE;
109 }
110 }
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 public CacheEventListener createCacheEventListener(final Properties properties) {
143 final boolean replicatePuts = extractBoolean(REPLICATE_PUTS, properties);
144 final boolean replicatePutsViaCopy = extractBoolean(REPLICATE_PUTS_VIA_COPY, properties);
145 final boolean replicateUpdates = extractBoolean(REPLICATE_UPDATES, properties);
146 final boolean replicateUpdatesViaCopy = extractBoolean(REPLICATE_UPDATES_VIA_COPY, properties);
147 final boolean replicateRemovals = extractBoolean(REPLICATE_REMOVALS, properties);
148 final boolean replicateAsynchronously = extractBoolean(REPLICATE_ASYNCHRONOUSLY, properties);
149 final int replicationIntervalMillis = extractReplicationIntervalMilis(properties);
150 final int maximumBatchSize = extractMaximumBatchSize(properties);
151
152 if (replicateAsynchronously) {
153 return new RMIAsynchronousCacheReplicator(
154 replicatePuts,
155 replicatePutsViaCopy,
156 replicateUpdates,
157 replicateUpdatesViaCopy,
158 replicateRemovals,
159 replicationIntervalMillis,
160 maximumBatchSize);
161 }
162
163 return new RMISynchronousCacheReplicator(
164 replicatePuts,
165 replicatePutsViaCopy,
166 replicateUpdates,
167 replicateUpdatesViaCopy,
168 replicateRemovals);
169 }
170 }