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  import net.sf.ehcache.event.CacheEventListener;
20  import net.sf.ehcache.event.CacheEventListenerFactory;
21  import net.sf.ehcache.util.PropertyUtil;
22  
23  import java.util.Properties;
24  
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  
29  /***
30   * Creates an RMICacheReplicator using properties. Config lines look like:
31   * <pre>&lt;cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
32   * properties="
33   * replicateAsynchronously=true,
34   * replicatePuts=true
35   * replicateUpdates=true
36   * replicateUpdatesViaCopy=true
37   * replicateRemovals=true
38   * "/&gt;</pre>
39   *
40   * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
41   * @version $Id: RMICacheReplicatorFactory.html 13146 2011-08-01 17:12:39Z oletizi $
42   */
43  public class RMICacheReplicatorFactory extends CacheEventListenerFactory {
44  
45      /***
46       * A default for the amount of time the replication thread sleeps after it detects the replicationQueue is empty
47       * before checking again.
48       */
49      protected static final int DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS = 1000;
50  
51      private static final Logger LOG = LoggerFactory.getLogger(RMICacheReplicatorFactory.class.getName());
52      private static final String REPLICATE_PUTS = "replicatePuts";
53      private static final String REPLICATE_PUTS_VIA_COPY = "replicatePutsViaCopy";
54      private static final String REPLICATE_UPDATES = "replicateUpdates";
55      private static final String REPLICATE_UPDATES_VIA_COPY = "replicateUpdatesViaCopy";
56      private static final String REPLICATE_REMOVALS = "replicateRemovals";
57      private static final String REPLICATE_ASYNCHRONOUSLY = "replicateAsynchronously";
58      private static final String ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS = "asynchronousReplicationIntervalMillis";
59      private static final int MINIMUM_REASONABLE_INTERVAL = 10;
60  
61      /***
62       * Create a <code>CacheEventListener</code> which is also a CacheReplicator.
63       * <p/>
64       * The defaults if properties are not specified are:
65       * <ul>
66       * <li>replicatePuts=true
67       * <li>replicatePutsViaCopy=true
68       * <li>replicateUpdates=true
69       * <li>replicateUpdatesViaCopy=true
70       * <li>replicateRemovals=true;
71       * <li>replicateAsynchronously=true
72       * <li>asynchronousReplicationIntervalMillis=1000
73       * </ul>
74       *
75       * @param properties implementation specific properties. These are configured as comma
76       *                   separated name value pairs in ehcache.xml e.g.
77       *                   <p/>
78       *                   <code>
79       *                   &lt;cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
80       *                   properties="
81       *                   replicateAsynchronously=true,
82       *                   replicatePuts=true
83       *                   replicateUpdates=true
84       *                   replicateUpdatesViaCopy=true
85       *                   replicateRemovals=true
86       *                   asynchronousReplicationIntervalMillis=1000
87       *                   "/&gt;</code>
88       * @return a constructed CacheEventListener
89       */
90      public final CacheEventListener createCacheEventListener(Properties properties) {
91          boolean replicatePuts = extractReplicatePuts(properties);
92          boolean replicatePutsViaCopy = extractReplicatePutsViaCopy(properties);
93          boolean replicateUpdates = extractReplicateUpdates(properties);
94          boolean replicateUpdatesViaCopy = extractReplicateUpdatesViaCopy(properties);
95          boolean replicateRemovals = extractReplicateRemovals(properties);
96          boolean replicateAsynchronously = extractReplicateAsynchronously(properties);
97          int asynchronousReplicationIntervalMillis = extractReplicationIntervalMilis(properties);
98  
99          if (replicateAsynchronously) {
100             return new RMIAsynchronousCacheReplicator(
101                     replicatePuts,
102                     replicatePutsViaCopy,
103                     replicateUpdates,
104                     replicateUpdatesViaCopy,
105                     replicateRemovals,
106                     asynchronousReplicationIntervalMillis);
107         } else {
108             return new RMISynchronousCacheReplicator(
109                     replicatePuts,
110                     replicatePutsViaCopy,
111                     replicateUpdates,
112                     replicateUpdatesViaCopy,
113                     replicateRemovals);
114         }
115     }
116 
117     /***
118      * Extracts the value of asynchronousReplicationIntervalMillis. Sets it to 1000ms if
119      * either not set or there is a problem parsing the number
120      * @param properties
121      */
122     protected int extractReplicationIntervalMilis(Properties properties) {
123         int asynchronousReplicationIntervalMillis;
124         String asynchronousReplicationIntervalMillisString =
125                 PropertyUtil.extractAndLogProperty(ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS, properties);
126         if (asynchronousReplicationIntervalMillisString != null) {
127             try {
128                 int asynchronousReplicationIntervalMillisCandidate =
129                         Integer.parseInt(asynchronousReplicationIntervalMillisString);
130                 if (asynchronousReplicationIntervalMillisCandidate < MINIMUM_REASONABLE_INTERVAL) {
131                     LOG.debug("Trying to set the asynchronousReplicationIntervalMillis to an unreasonable number." +
132                             " Using the default instead.");
133                     asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
134                 } else {
135                     asynchronousReplicationIntervalMillis = asynchronousReplicationIntervalMillisCandidate;
136                 }
137             } catch (NumberFormatException e) {
138                 LOG.warn("Number format exception trying to set asynchronousReplicationIntervalMillis. " +
139                         "Using the default instead. String value was: '" + asynchronousReplicationIntervalMillisString + "'");
140                 asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
141             }
142         } else {
143             asynchronousReplicationIntervalMillis = DEFAULT_ASYNCHRONOUS_REPLICATION_INTERVAL_MILLIS;
144         }
145         return asynchronousReplicationIntervalMillis;
146     }
147 
148     /***
149      * Extracts the value of replicateAsynchronously from the properties
150      * @param properties
151      */
152     protected boolean extractReplicateAsynchronously(Properties properties) {
153         boolean replicateAsynchronously;
154         String replicateAsynchronouslyString = PropertyUtil.extractAndLogProperty(REPLICATE_ASYNCHRONOUSLY, properties);
155         if (replicateAsynchronouslyString != null) {
156             replicateAsynchronously = PropertyUtil.parseBoolean(replicateAsynchronouslyString);
157         } else {
158             replicateAsynchronously = true;
159         }
160         return replicateAsynchronously;
161     }
162 
163     /***
164      * Extracts the value of replicateRemovals from the properties
165      * @param properties
166      */
167     protected boolean extractReplicateRemovals(Properties properties) {
168         boolean replicateRemovals;
169         String replicateRemovalsString = PropertyUtil.extractAndLogProperty(REPLICATE_REMOVALS, properties);
170         if (replicateRemovalsString != null) {
171             replicateRemovals = PropertyUtil.parseBoolean(replicateRemovalsString);
172         } else {
173             replicateRemovals = true;
174         }
175         return replicateRemovals;
176     }
177 
178     /***
179      * Extracts the value of replicateUpdatesViaCopy from the properties
180      * @param properties
181      */
182     protected boolean extractReplicateUpdatesViaCopy(Properties properties) {
183         boolean replicateUpdatesViaCopy;
184         String replicateUpdatesViaCopyString = PropertyUtil.extractAndLogProperty(REPLICATE_UPDATES_VIA_COPY, properties);
185         if (replicateUpdatesViaCopyString != null) {
186             replicateUpdatesViaCopy = PropertyUtil.parseBoolean(replicateUpdatesViaCopyString);
187         } else {
188             replicateUpdatesViaCopy = true;
189         }
190         return replicateUpdatesViaCopy;
191     }
192 
193     /***
194      * Extracts the value of replicatePutsViaCopy from the properties
195      * @param properties
196      */
197     protected boolean extractReplicatePutsViaCopy(Properties properties) {
198         boolean replicatePutsViaCopy;
199         String replicatePutsViaCopyString = PropertyUtil.extractAndLogProperty(REPLICATE_PUTS_VIA_COPY, properties);
200         if (replicatePutsViaCopyString != null) {
201             replicatePutsViaCopy = PropertyUtil.parseBoolean(replicatePutsViaCopyString);
202         } else {
203             replicatePutsViaCopy = true;
204         }
205         return replicatePutsViaCopy;
206     }
207 
208     /***
209      * Extracts the value of replicateUpdates from the properties
210      * @param properties
211      */
212     protected boolean extractReplicateUpdates(Properties properties) {
213         boolean replicateUpdates;
214         String replicateUpdatesString = PropertyUtil.extractAndLogProperty(REPLICATE_UPDATES, properties);
215         if (replicateUpdatesString != null) {
216             replicateUpdates = PropertyUtil.parseBoolean(replicateUpdatesString);
217         } else {
218             replicateUpdates = true;
219         }
220         return replicateUpdates;
221     }
222 
223     /***
224      * Extracts the value of replicatePuts from the properties
225      * @param properties
226      */
227     protected boolean extractReplicatePuts(Properties properties) {
228         boolean replicatePuts;
229         String replicatePutsString = PropertyUtil.extractAndLogProperty(REPLICATE_PUTS, properties);
230         if (replicatePutsString != null) {
231             replicatePuts = PropertyUtil.parseBoolean(replicatePutsString);
232         } else {
233             replicatePuts = true;
234         }
235         return replicatePuts;
236     }
237 
238 
239 }