001
014
015 package com.liferay.portal.cache.ehcache;
016
017 import com.liferay.portal.cache.transactional.TransactionalPortalCache;
018 import com.liferay.portal.kernel.cache.BlockingPortalCache;
019 import com.liferay.portal.kernel.cache.PortalCache;
020 import com.liferay.portal.kernel.cache.PortalCacheManager;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.resiliency.spi.SPIUtil;
024 import com.liferay.portal.kernel.util.CharPool;
025 import com.liferay.portal.kernel.util.ReflectionUtil;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.util.PropsUtil;
029 import com.liferay.portal.util.PropsValues;
030
031 import java.io.Serializable;
032
033 import java.lang.reflect.Field;
034
035 import java.net.URL;
036
037 import java.util.HashMap;
038 import java.util.Map;
039
040 import javax.management.MBeanServer;
041
042 import net.sf.ehcache.Cache;
043 import net.sf.ehcache.CacheManager;
044 import net.sf.ehcache.Ehcache;
045 import net.sf.ehcache.config.CacheConfiguration;
046 import net.sf.ehcache.config.Configuration;
047 import net.sf.ehcache.management.ManagementService;
048 import net.sf.ehcache.util.FailSafeTimer;
049
050
057 public class EhcachePortalCacheManager<K extends Serializable, V>
058 implements PortalCacheManager<K, V> {
059
060 public void afterPropertiesSet() {
061 if ((_cacheManager != null) || (_mpiOnly && SPIUtil.isSPI())) {
062 return;
063 }
064
065 String configurationPath = PropsUtil.get(_configPropertyKey);
066
067 if (Validator.isNull(configurationPath)) {
068 configurationPath = _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE;
069 }
070
071 _usingDefault = configurationPath.equals(
072 _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE);
073
074 Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
075 configurationPath, _clusterAware, _usingDefault);
076
077 _cacheManager = CacheManagerUtil.createCacheManager(configuration);
078
079 FailSafeTimer failSafeTimer = _cacheManager.getTimer();
080
081 failSafeTimer.cancel();
082
083 try {
084 Field cacheManagerTimerField = ReflectionUtil.getDeclaredField(
085 CacheManager.class, "cacheManagerTimer");
086
087 cacheManagerTimerField.set(_cacheManager, null);
088 }
089 catch (Exception e) {
090 throw new RuntimeException(e);
091 }
092
093 if (PropsValues.EHCACHE_PORTAL_CACHE_MANAGER_JMX_ENABLED) {
094 _managementService = new ManagementService(
095 _cacheManager, _mBeanServer, _registerCacheManager,
096 _registerCaches, _registerCacheConfigurations,
097 _registerCacheStatistics);
098
099 _managementService.init();
100 }
101 }
102
103 @Override
104 public void clearAll() {
105 _cacheManager.clearAll();
106 }
107
108 public void destroy() throws Exception {
109 try {
110 _ehcachePortalCaches.clear();
111 _portalCaches.clear();
112
113 _cacheManager.shutdown();
114 }
115 finally {
116 if (_managementService != null) {
117 _managementService.dispose();
118 }
119 }
120 }
121
122 @Override
123 public PortalCache<K, V> getCache(String name) {
124 return getCache(name, false);
125 }
126
127 @Override
128 public PortalCache<K, V> getCache(String name, boolean blocking) {
129 PortalCache<K, V> portalCache = _portalCaches.get(name);
130
131 if (portalCache == null) {
132 synchronized (_cacheManager) {
133 portalCache = _portalCaches.get(name);
134
135 if (portalCache == null) {
136 portalCache = addCache(name, null);
137
138 if (PropsValues.TRANSACTIONAL_CACHE_ENABLED &&
139 isTransactionalPortalCache(name)) {
140
141 portalCache = new TransactionalPortalCache<K, V>(
142 portalCache);
143 }
144
145 if (PropsValues.EHCACHE_BLOCKING_CACHE_ALLOWED &&
146 blocking) {
147
148 portalCache = new BlockingPortalCache<K, V>(
149 portalCache);
150 }
151
152 _portalCaches.put(name, portalCache);
153 }
154 }
155 }
156
157 return portalCache;
158 }
159
160 public CacheManager getEhcacheManager() {
161 return _cacheManager;
162 }
163
164 @Override
165 public void reconfigureCaches(URL configurationURL) {
166 Configuration configuration = EhcacheConfigurationUtil.getConfiguration(
167 configurationURL, _clusterAware, _usingDefault);
168
169 Map<String, CacheConfiguration> cacheConfigurations =
170 configuration.getCacheConfigurations();
171
172 for (CacheConfiguration cacheConfiguration :
173 cacheConfigurations.values()) {
174
175 Cache cache = new Cache(cacheConfiguration);
176
177 PortalCache<K, V> portalCache = addCache(cache.getName(), cache);
178
179 if (portalCache == null) {
180 _log.error(
181 "Failed to override cache " + cacheConfiguration.getName());
182 }
183 }
184 }
185
186 @Override
187 public void removeCache(String name) {
188 _cacheManager.removeCache(name);
189 _ehcachePortalCaches.remove(name);
190 _portalCaches.remove(name);
191 }
192
193 public void setClusterAware(boolean clusterAware) {
194 _clusterAware = clusterAware;
195 }
196
197 public void setConfigPropertyKey(String configPropertyKey) {
198 _configPropertyKey = configPropertyKey;
199 }
200
201 public void setMBeanServer(MBeanServer mBeanServer) {
202 _mBeanServer = mBeanServer;
203 }
204
205 public void setMpiOnly(boolean mpiOnly) {
206 _mpiOnly = mpiOnly;
207 }
208
209 public void setRegisterCacheConfigurations(
210 boolean registerCacheConfigurations) {
211
212 _registerCacheConfigurations = registerCacheConfigurations;
213 }
214
215 public void setRegisterCacheManager(boolean registerCacheManager) {
216 _registerCacheManager = registerCacheManager;
217 }
218
219 public void setRegisterCaches(boolean registerCaches) {
220 _registerCaches = registerCaches;
221 }
222
223 public void setRegisterCacheStatistics(boolean registerCacheStatistics) {
224 _registerCacheStatistics = registerCacheStatistics;
225 }
226
227 protected PortalCache<K, V> addCache(String name, Cache cache) {
228 EhcachePortalCache<K, V> ehcachePortalCache = null;
229
230 synchronized (_cacheManager) {
231 if ((cache != null) && _cacheManager.cacheExists(name)) {
232 if (_log.isInfoEnabled()) {
233 _log.info("Overriding existing cache " + name);
234 }
235
236 _cacheManager.removeCache(name);
237 }
238
239 if (cache == null) {
240 if (!_cacheManager.cacheExists(name)) {
241 _cacheManager.addCache(name);
242 }
243 }
244 else {
245 _cacheManager.addCache(cache);
246 }
247
248 Ehcache ehcache = _cacheManager.getEhcache(name);
249
250 if (ehcache == null) {
251 return null;
252 }
253
254 ehcachePortalCache = _ehcachePortalCaches.get(name);
255
256 if (ehcachePortalCache == null) {
257 ehcachePortalCache = new EhcachePortalCache<K, V>(ehcache);
258
259 _ehcachePortalCaches.put(name, ehcachePortalCache);
260 }
261 else {
262 ehcachePortalCache.setEhcache(ehcache);
263 }
264 }
265
266 return ehcachePortalCache;
267 }
268
269 protected boolean isTransactionalPortalCache(String name) {
270 for (String namePattern : PropsValues.TRANSACTIONAL_CACHE_NAMES) {
271 if (StringUtil.wildcardMatches(
272 name, namePattern, CharPool.QUESTION, CharPool.STAR,
273 CharPool.PERCENT, true)) {
274
275 return true;
276 }
277 }
278
279 return false;
280 }
281
282 private static final String _DEFAULT_CLUSTERED_EHCACHE_CONFIG_FILE =
283 "/ehcache/liferay-multi-vm-clustered.xml";
284
285 private static Log _log = LogFactoryUtil.getLog(
286 EhcachePortalCacheManager.class);
287
288 private CacheManager _cacheManager;
289 private boolean _clusterAware;
290 private String _configPropertyKey;
291 private Map<String, EhcachePortalCache<K, V>> _ehcachePortalCaches =
292 new HashMap<String, EhcachePortalCache<K, V>>();
293 private ManagementService _managementService;
294 private MBeanServer _mBeanServer;
295 private boolean _mpiOnly;
296 private Map<String, PortalCache<K, V>> _portalCaches =
297 new HashMap<String, PortalCache<K, V>>();
298 private boolean _registerCacheConfigurations = true;
299 private boolean _registerCacheManager = true;
300 private boolean _registerCaches = true;
301 private boolean _registerCacheStatistics = true;
302 private boolean _usingDefault;
303
304 }