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.config;
18  
19  import org.slf4j.Logger;
20  import org.slf4j.LoggerFactory;
21  
22  /***
23   * Class to hold the Terracotta configuration - either a pointer to the real config or a
24   * container for embedded config.
25   *
26   * @author Alex Miller
27   * @author Geert Bevin
28   * @author Abhishek Sanoujam
29   */
30  public class TerracottaConfiguration implements Cloneable {
31  
32      /***
33       * Default clustered mode
34       */
35      public static final boolean DEFAULT_CLUSTERED = true;
36      /***
37       * Default value mode
38       */
39      public static final ValueMode DEFAULT_VALUE_MODE = ValueMode.SERIALIZATION;
40      /***
41       * Default coherent read behavior
42       */
43      public static final boolean DEFAULT_COHERENT_READS = true;
44      /***
45       * Default xa enabled
46       */
47      public static final boolean DEFAULT_CACHE_XA = false;
48      /***
49       * Default orphan eviction status
50       */
51      public static final boolean DEFAULT_ORPHAN_EVICTION = true;
52      /***
53       * Default orphan eviction period
54       */
55      public static final int DEFAULT_ORPHAN_EVICTION_PERIOD = 4;
56      /***
57       * Default local key cache status
58       */
59      public static final boolean DEFAULT_LOCAL_KEY_CACHE = false;
60      /***
61       * Default local key cache size
62       */
63      public static final int DEFAULT_LOCAL_KEY_CACHE_SIZE = 300000;
64      /***
65       * Default copy on read setting
66       */
67      public static final boolean DEFAULT_COPY_ON_READ = false;
68  
69      /***
70       * Default value for {@link NonstopConfiguration}
71       */
72      public static final NonstopConfiguration DEFAULT_NON_STOP_CONFIGURATION = new NonstopConfiguration().enabled(false);
73  
74      /***
75       * Default cache coherence setting
76       *
77       * @deprecated since 2.4 Use {@link #DEFAULT_CONSISTENCY_TYPE} instead.
78       */
79      @Deprecated
80      public static final boolean DEFAULT_CACHE_COHERENT = true;
81  
82      /***
83       * Default cache consistency setting
84       */
85      public static final Consistency DEFAULT_CONSISTENCY_TYPE = Consistency.EVENTUAL;
86  
87      /***
88       * Default setting for synchronous-write
89       */
90      public static final boolean DEFAULT_SYNCHRONOUS_WRITES = false;
91  
92      /***
93       * Default setting for storageStrategy
94       */
95      public static final StorageStrategy DEFAULT_STORAGE_STRATEGY = StorageStrategy.DCV2;
96  
97      /***
98       * Default value for concurrency of the internal Store.
99       */
100     public static final int DEFAULT_CONCURRENCY = 0;
101 
102 
103     /***
104      * Default value for whether local cache is enabled or not
105      */
106     public static final boolean DEFAULT_LOCAL_CACHE_ENABLED = true;
107 
108     /***
109      * Represents whether values are stored with serialization in the clustered store
110      * or through Terracotta clustered identity.
111      *
112      * @author amiller
113      */
114     public static enum ValueMode {
115         /***
116          * When a key or value is put in the cache, serialize the data for sending around the cluster
117          */
118         SERIALIZATION,
119 
120         /***
121          * Use Terracotta clustered identity to preserve object identity without serialization
122          */
123         IDENTITY,
124     }
125 
126     /***
127      * Represents whether keys/values are to be stored in the local vm or the Terracotta server
128      *
129      * @author Abhishek Sanoujam
130      */
131     public static enum StorageStrategy {
132         /***
133          * Store the key/values in the local vm
134          */
135         CLASSIC,
136 
137         /***
138          * Store the key/values in the Terracotta Server
139          */
140         DCV2,
141     }
142 
143     private static final Logger LOG = LoggerFactory.getLogger(TerracottaConfiguration.class.getName());
144 
145     private boolean clustered = DEFAULT_CLUSTERED;
146     private ValueMode valueMode = DEFAULT_VALUE_MODE;
147     private boolean coherentReads = DEFAULT_COHERENT_READS;
148     private boolean orphanEviction = DEFAULT_ORPHAN_EVICTION;
149     private int orphanEvictionPeriod = DEFAULT_ORPHAN_EVICTION_PERIOD;
150     private boolean localKeyCache = DEFAULT_LOCAL_KEY_CACHE;
151     private int localKeyCacheSize = DEFAULT_LOCAL_KEY_CACHE_SIZE;
152     private boolean isCopyOnRead = DEFAULT_COPY_ON_READ;
153     private boolean cacheXA = DEFAULT_CACHE_XA;
154     private boolean synchronousWrites = DEFAULT_SYNCHRONOUS_WRITES;
155     private StorageStrategy storageStrategy = DEFAULT_STORAGE_STRATEGY;
156     private int concurrency = DEFAULT_CONCURRENCY;
157     private NonstopConfiguration nonStopConfiguration = DEFAULT_NON_STOP_CONFIGURATION;
158 
159     private boolean copyOnReadSet;
160     private volatile boolean storageStrategySet;
161     private Consistency consistency = DEFAULT_CONSISTENCY_TYPE;
162     private volatile boolean localCacheEnabled = DEFAULT_LOCAL_CACHE_ENABLED;
163 
164     /***
165      * Clones this object, following the usual contract.
166      *
167      * @return a copy, which independent other than configurations than cannot change.
168      */
169     @Override
170     public TerracottaConfiguration clone() {
171         try {
172             TerracottaConfiguration clone = (TerracottaConfiguration) super.clone();
173             if (nonStopConfiguration != null) {
174                 clone.nonstop(this.nonStopConfiguration.clone());
175             }
176             return clone;
177         } catch (CloneNotSupportedException e) {
178             throw new RuntimeException(e);
179         }
180     }
181 
182     /***
183      * Indicates whether to cluster this cache with Terracotta.
184      * <p/>
185      * Defaults to {@value #DEFAULT_CLUSTERED}.
186      *
187      * @param clustered
188      *            {@code true} if the cache should be clustered with Terracotta; {@code false} otherwise
189      */
190     public void setClustered(boolean clustered) {
191         this.clustered = clustered;
192     }
193 
194     /***
195      * @return this configuration instance
196      * @see #setClustered(boolean)
197      */
198     public TerracottaConfiguration clustered(boolean clustered) {
199         setClustered(clustered);
200         return this;
201     }
202 
203     /***
204      * Check whether clustering is enabled
205      */
206     public boolean isClustered() {
207         return this.clustered;
208     }
209 
210     /***
211      * Used by BeanHandler to set the copyOnRead flag during parsing
212      */
213     public void setCopyOnRead(boolean isCopyOnRead) {
214         LOG.warn("copyOnRead is deprecated on the <terracotta /> element, "
215                 + "please use the copyOnRead attribute on <cache /> or <defaultCache />");
216         this.copyOnReadSet = true;
217         this.isCopyOnRead = isCopyOnRead;
218     }
219 
220     /***
221      * Whether the copyOnRead was explicitly set
222      *
223      * @return true if set by config
224      */
225     boolean isCopyOnReadSet() {
226         return copyOnReadSet;
227     }
228 
229     /***
230      * @return this configuration instance
231      * @see #setCopyOnRead(boolean)
232      */
233     public TerracottaConfiguration copyOnRead(boolean isCopyOnRead) {
234         setCopyOnRead(isCopyOnRead);
235         return this;
236     }
237 
238     /***
239      * Check whether the [serialized value] cache is an XA enabled cache
240      */
241     public boolean isCacheXA() {
242         return this.cacheXA;
243     }
244 
245     /***
246      * Used by BeanHandler to set the cacheXA flag during parsing
247      */
248     public void setCacheXA(boolean cacheXA) {
249         this.cacheXA = cacheXA;
250     }
251 
252     /***
253      * @return this configuration instance
254      * @see #setCacheXA(boolean)
255      */
256     public TerracottaConfiguration cacheXA(boolean cacheXA) {
257         setCacheXA(cacheXA);
258         return this;
259     }
260 
261     /***
262      * Check whether the [serialized value] cache should use copy on read semantics
263      */
264     public boolean isCopyOnRead() {
265         return this.isCopyOnRead;
266     }
267 
268     /***
269      * Sets whether this cache should use coherent reads (usually should be {@value #DEFAULT_COHERENT_READS} unless optimizing for
270      * read-only).
271      * <p/>
272      * Defaults to {@value #DEFAULT_COHERENT_READS}.
273      *
274      * @param coherentReads
275      *            {@code true} if coherent reads should be used; {@code false} otherwise
276      */
277     public void setCoherentReads(boolean coherentReads) {
278         LOG.warn("The attribute \"coherentReads\" in \"terracotta\" element is deprecated."
279                 + " Please use the new \"coherent\" attribute instead.");
280         this.coherentReads = coherentReads;
281     }
282 
283     /***
284      * @return this configuration instance
285      * @see #setCoherentReads(boolean)
286      */
287     public TerracottaConfiguration coherentReads(boolean coherentReads) {
288         setCoherentReads(coherentReads);
289         return this;
290     }
291 
292     /***
293      * Check whether coherent reads are enabled
294      */
295     public boolean getCoherentReads() {
296         return this.coherentReads;
297     }
298 
299     /***
300      * Converts the {@code valueMode} string argument to uppercase and looks up enum constant in ValueMode.
301      */
302     public void setValueMode(String valueMode) {
303         if (valueMode == null) {
304             throw new IllegalArgumentException("Value mode must be non-null");
305         }
306         this.valueMode = ValueMode.valueOf(ValueMode.class, valueMode.toUpperCase());
307     }
308 
309     /***
310      * @return this configuration instance
311      * @see #setValueMode(String)
312      */
313     public TerracottaConfiguration valueMode(String valueMode) {
314         setValueMode(valueMode);
315         return this;
316     }
317 
318     /***
319      * @return this configuration instance
320      * @see #setValueMode(String)
321      */
322     public TerracottaConfiguration valueMode(ValueMode valueMode) {
323         if (valueMode == null) {
324             throw new IllegalArgumentException("Value mode must be non-null");
325         }
326         this.valueMode = valueMode;
327         return this;
328     }
329 
330     /***
331      * Get the value mode in terms of the mode enum
332      */
333     public ValueMode getValueMode() {
334         return this.valueMode;
335     }
336 
337     /***
338      * Sets whether this cache should perform orphan eviction (usually should be {@value #DEFAULT_ORPHAN_EVICTION}).
339      * <p/>
340      * Orphans are elements that are not present on any node in the cluster anymore and hence need additional routines to be detected since
341      * they're not locally available anywhere.
342      * <p/>
343      * Defaults to {@value #DEFAULT_ORPHAN_EVICTION}.
344      *
345      * @param orphanEviction
346      *            {@code true} if orphan eviction should be used; {@code false} otherwise
347      */
348     public void setOrphanEviction(boolean orphanEviction) {
349         this.orphanEviction = orphanEviction;
350     }
351 
352     /***
353      * @return this configuration instance
354      * @see #setOrphanEviction(boolean)
355      */
356     public TerracottaConfiguration orphanEviction(boolean orphanEviction) {
357         setOrphanEviction(orphanEviction);
358         return this;
359     }
360 
361     /***
362      * Check whether orphan eviction is enabled
363      */
364     public boolean getOrphanEviction() {
365         return this.orphanEviction;
366     }
367 
368     /***
369      * Set how often this cache should perform orphan eviction (measured in regular eviction periods).
370      * <p/>
371      * Defaults to {@value #DEFAULT_ORPHAN_EVICTION_PERIOD}).
372      *
373      * @param orphanEvictionPeriod
374      *            every how many regular evictions an orphan eviction should occur
375      */
376     public void setOrphanEvictionPeriod(int orphanEvictionPeriod) {
377         this.orphanEvictionPeriod = orphanEvictionPeriod;
378     }
379 
380     /***
381      * @return this configuration instance
382      * @see #setOrphanEvictionPeriod(int)
383      */
384     public TerracottaConfiguration orphanEvictionPeriod(int orphanEvictionPeriod) {
385         setOrphanEvictionPeriod(orphanEvictionPeriod);
386         return this;
387     }
388 
389     /***
390      * Get the number of regular eviction cycles between orphan evictions
391      */
392     public int getOrphanEvictionPeriod() {
393         return this.orphanEvictionPeriod;
394     }
395 
396     /***
397      * Sets whether this cache should use an unclustered local key cache (usually should be {@value #DEFAULT_LOCAL_KEY_CACHE} unless
398      * optimizing for a small read-only cache)
399      * <p/>
400      * Defaults to {@value #DEFAULT_LOCAL_KEY_CACHE}.
401      *
402      * @param localKeyCache
403      *            {@code true} if a local key cache should be used; {@code false} otherwise
404      */
405     public void setLocalKeyCache(boolean localKeyCache) {
406         this.localKeyCache = localKeyCache;
407     }
408 
409     /***
410      * @return this configuration instance
411      * @see #setLocalKeyCache(boolean)
412      */
413     public TerracottaConfiguration localKeyCache(boolean localKeyCache) {
414         setLocalKeyCache(localKeyCache);
415         return this;
416     }
417 
418     /***
419      * Check whether the local key cache is enabled
420      */
421     public boolean getLocalKeyCache() {
422         return this.localKeyCache;
423     }
424 
425     /***
426      * Sets maximum size of the local key cache (usually the size of the key set of the cache or cache partition).
427      * <p/>
428      * Defaults to {@value #DEFAULT_LOCAL_KEY_CACHE_SIZE}.
429      *
430      * @param localKeyCacheSize
431      *            the size of the local key cache in number of keys
432      */
433     public void setLocalKeyCacheSize(int localKeyCacheSize) {
434         this.localKeyCacheSize = localKeyCacheSize;
435     }
436 
437     /***
438      * @return this configuration instance
439      * @see #setLocalKeyCacheSize(int)
440      */
441     public TerracottaConfiguration localKeyCacheSize(int localKeyCacheSize) {
442         setLocalKeyCacheSize(localKeyCacheSize);
443         return this;
444     }
445 
446     /***
447      * Get the size limit of the local key cache (if enabled)
448      */
449     public int getLocalKeyCacheSize() {
450         return this.localKeyCacheSize;
451     }
452 
453     /***
454      * Used by BeanHandler to set the <tt>coherent</tt> during parsing
455      *
456      * @deprecated since 2.4 Use {@link #setConsistency(Consistency)} instead
457      */
458     @Deprecated
459     public void setCoherent(boolean coherent) {
460         Consistency consistencyType = coherent ? Consistency.STRONG : Consistency.EVENTUAL;
461         this.consistency(consistencyType);
462     }
463 
464     /***
465      * @return this configuration instance
466      * @deprecated since 2.4 Use {@link #consistency(Consistency)} instead
467      */
468     @Deprecated
469     public TerracottaConfiguration coherent(boolean coherent) {
470         Consistency consistencyType = coherent ? Consistency.STRONG : Consistency.EVENTUAL;
471         this.consistency(consistencyType);
472         return this;
473     }
474 
475     /***
476      * Is the cache configured for coherent or incoherent mode.
477      *
478      * @return true if configured in coherent mode.
479      * @deprecated since 2.4 Use {@link #getConsistency()} instead to query the {@link Consistency} or Ehcache#isNodeCoherent()
480      *             to query if the node is coherent
481      */
482     @Deprecated
483     public boolean isCoherent() {
484         return consistency == Consistency.STRONG;
485     }
486 
487     /***
488      * Is the cache configured for synchronous-write?
489      *
490      * @return true if configured for synchronouse-write, otherwise false. Default is false
491      */
492     public boolean isSynchronousWrites() {
493         return synchronousWrites;
494     }
495 
496     /***
497      * Set the value for synchronous-write
498      *
499      * @param synchronousWrites
500      *            true for using synchronous-write
501      */
502     public void setSynchronousWrites(boolean synchronousWrites) {
503         this.synchronousWrites = synchronousWrites;
504     }
505 
506     /***
507      * @return this configuration instance
508      * @see #setSynchronousWrites(boolean)
509      */
510     public TerracottaConfiguration synchronousWrites(boolean synchronousWrites) {
511         setSynchronousWrites(synchronousWrites);
512         return this;
513     }
514 
515     /***
516      * Converts the {@code storageStrategy} string argument to uppercase and looks up enum constant in StorageStrategy.
517      */
518     public void setStorageStrategy(String storageStrategy) {
519         if (storageStrategy == null) {
520             throw new IllegalArgumentException("Storage Strategy must be non-null");
521         }
522         this.storageStrategy(StorageStrategy.valueOf(StorageStrategy.class, storageStrategy.toUpperCase()));
523     }
524 
525     /***
526      * @return this configuration instance
527      * @see #setStorageStrategy(String)
528      */
529     public TerracottaConfiguration storageStrategy(String storageStrategy) {
530         setStorageStrategy(storageStrategy);
531         return this;
532     }
533 
534     /***
535      * @return this configuration instance
536      * @see #setStorageStrategy(String)
537      */
538     public TerracottaConfiguration storageStrategy(StorageStrategy storageStrategy) {
539         if (storageStrategy == null) {
540             throw new IllegalArgumentException("Storage Strategy must be non-null");
541         }
542         this.storageStrategy = storageStrategy;
543         this.storageStrategySet = true;
544         return this;
545     }
546 
547     /***
548      * Returns true is storageStrategy is set explicitly
549      *
550      * @return true is storageStrategy is set explicitly
551      */
552     public boolean isStorageStrategySet() {
553         return storageStrategySet;
554     }
555 
556     /***
557      * Get the value mode in terms of the mode enum
558      */
559     public StorageStrategy getStorageStrategy() {
560         return this.storageStrategy;
561     }
562 
563     /***
564      * @return this configuration instance
565      * @see #setConcurrency(int)
566      */
567     public TerracottaConfiguration concurrency(final int concurrency) {
568         setConcurrency(concurrency);
569         return this;
570     }
571 
572     /***
573      * Sets the value of concurrency. Throws {@link IllegalArgumentException} if the value is less than 0.
574      * This value cannot be changed once cache is initialized.
575      */
576     public void setConcurrency(final int concurrency) {
577         if (concurrency < 0) {
578             throw new IllegalArgumentException("Only non-negative integers allowed");
579         }
580         this.concurrency = concurrency;
581     }
582 
583     /***
584      * Get the value of concurrency.
585      * This value cannot be changed once cache is initialized.
586      */
587     public int getConcurrency() {
588         return this.concurrency;
589     }
590 
591     /***
592      * Add the {@link NonstopConfiguration}
593      *
594      * @param nonstopConfiguration
595      */
596     public void addNonstop(NonstopConfiguration nonstopConfiguration) {
597         this.nonStopConfiguration = nonstopConfiguration;
598     }
599 
600     /***
601      * Set the {@link NonstopConfiguration}
602      *
603      * @param nonstopConfiguration
604      * @return this configuration instance
605      */
606     public TerracottaConfiguration nonstop(NonstopConfiguration nonstopConfiguration) {
607         this.addNonstop(nonstopConfiguration);
608         return this;
609     }
610 
611     /***
612      * Get the {@link NonstopConfiguration}, may be null
613      *
614      * @return the {@link NonstopConfiguration}, may be null
615      */
616     public NonstopConfiguration getNonstopConfiguration() {
617         return nonStopConfiguration;
618     }
619 
620     /***
621      * Returns true if nonstop is enabled
622      *
623      * @return true if nonstop is enabled
624      */
625     public boolean isNonstopEnabled() {
626         return nonStopConfiguration != null && nonStopConfiguration.isEnabled();
627     }
628 
629     /***
630      * Setter for consistency, returns this instance
631      *
632      * @param consistency
633      * @return this instance
634      */
635     public TerracottaConfiguration consistency(Consistency consistency) {
636         setConsistency(consistency);
637         return this;
638     }
639 
640     /***
641      * Setter for consistency
642      *
643      * @param consistency
644      */
645     public void setConsistency(Consistency consistency) {
646         this.consistency = consistency;
647     }
648 
649     /***
650      * Setter for consistency
651      *
652      * @param consistency
653      */
654     public void setConsistency(String consistency) {
655         if (consistency == null) {
656             throw new IllegalArgumentException("Consistency cannot be null");
657         }
658         this.setConsistency(Consistency.valueOf(consistency.toUpperCase()));
659     }
660 
661     /***
662      * Getter for consistency
663      *
664      * @return the consistency
665      */
666     public Consistency getConsistency() {
667         return this.consistency;
668     }
669 
670     /***
671      * Returns true if local cache is enabled, otherwise false
672      * @return true if local cache is enabled, otherwise false
673      */
674     public boolean isLocalCacheEnabled() {
675         return localCacheEnabled;
676     }
677 
678     /***
679      * Enable or disable the local cache
680      * @param localCacheEnabled
681      */
682     public void setLocalCacheEnabled(final boolean localCacheEnabled) {
683         this.localCacheEnabled = localCacheEnabled;
684     }
685 
686 
687     /***
688      * Enable or disable the local cache
689      * @param localCacheEnabled
690      * @return this instance
691      */
692     public TerracottaConfiguration localCacheEnabled(final boolean localCacheEnabled) {
693         setLocalCacheEnabled(localCacheEnabled);
694         return this;
695     }
696 
697     /***
698      * Enum for various consistency settings
699      *
700      * @author Abhishek Sanoujam
701      *
702      */
703     public static enum Consistency {
704         /***
705          * Strong consistency
706          */
707         STRONG,
708         /***
709          * Eventual consistency
710          */
711         EVENTUAL;
712     }
713 }