1 /* 2 * Copyright (C) 2005-2008 Jive Software. All rights reserved. 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 org.jivesoftware.openfire.container; 18 19 import java.util.ArrayList; 20 import java.util.Collection; 21 import java.util.HashMap; 22 import java.util.List; 23 import java.util.Map; 24 25 import org.jivesoftware.util.JiveConstants; 26 import org.jivesoftware.util.cache.CacheFactory; 27 import org.slf4j.Logger; 28 import org.slf4j.LoggerFactory; 29 30 /** 31 * A simple registry of cache configuration data for plugins. 32 */ 33 public class PluginCacheRegistry { 34 35 private static final Logger Log = LoggerFactory.getLogger(PluginCacheRegistry.class); 36 37 private static final PluginCacheRegistry instance = new PluginCacheRegistry(); 38 39 private Map<String, CacheInfo> extraCacheMappings = new HashMap<>(); 40 private Map<String, List<CacheInfo>> pluginCaches = new HashMap<>(); 41 getInstance()42 public static PluginCacheRegistry getInstance() { 43 return instance; 44 } 45 PluginCacheRegistry()46 private PluginCacheRegistry() { 47 } 48 49 /** 50 * Registers cache configuration data for a give cache and plugin. 51 * 52 * @param pluginName the name of the plugin which will use the cache. 53 * @param info the cache configuration data. 54 */ registerCache(String pluginName, CacheInfo info)55 public void registerCache(String pluginName, CacheInfo info) { 56 extraCacheMappings.put(info.getCacheName(), info); 57 List<CacheInfo> caches = pluginCaches.get(pluginName); 58 59 if (caches == null) { 60 caches = new ArrayList<>(); 61 pluginCaches.put(pluginName, caches); 62 } 63 64 caches.add(info); 65 66 // Set system properties for this cache 67 CacheFactory.setCacheTypeProperty(info.getCacheName(), info.getType().getName()); 68 CacheFactory.setMaxSizeProperty(info.getCacheName(), getMaxSizeFromProperty(info)); 69 CacheFactory.setMaxLifetimeProperty(info.getCacheName(), getMaxLifetimeFromProperty(info)); 70 CacheFactory.setMinCacheSize(info.getCacheName(), getMinSizeFromProperty(info)); 71 } 72 73 /** 74 * Unregisters all caches for the given plugin. 75 * 76 * @param pluginName the name of the plugin whose caches will be unregistered. 77 */ unregisterCaches(String pluginName)78 public void unregisterCaches(String pluginName) { 79 List<CacheInfo> caches = pluginCaches.remove(pluginName); 80 if (caches != null) { 81 for (CacheInfo info : caches) { 82 extraCacheMappings.remove(info.getCacheName()); 83 // Check if other cluster nodes have this plugin installed 84 Collection<Boolean> answers = 85 CacheFactory.doSynchronousClusterTask(new IsPluginInstalledTask(pluginName), false); 86 for (Boolean installed : answers) { 87 if (installed) { 88 return; 89 } 90 } 91 // Destroy cache if we are the last node hosting this plugin 92 try { 93 CacheFactory.destroyCache(info.getCacheName()); 94 } 95 catch (Exception e) { 96 Log.warn(e.getMessage(), e); 97 } 98 } 99 } 100 } 101 getCacheInfo(String name)102 public CacheInfo getCacheInfo(String name) { 103 return extraCacheMappings.get(name); 104 } 105 getMaxSizeFromProperty(CacheInfo cacheInfo)106 private long getMaxSizeFromProperty(CacheInfo cacheInfo) { 107 String sizeProp = cacheInfo.getParams().get("back-size-high"); 108 if (sizeProp != null) { 109 if ("0".equals(sizeProp)) { 110 return -1L; 111 } 112 try { 113 return Integer.parseInt(sizeProp); 114 } 115 catch (NumberFormatException nfe) { 116 Log.warn("Unable to parse back-size-high for cache: " + cacheInfo.getCacheName()); 117 } 118 } 119 // Return default 120 return CacheFactory.DEFAULT_MAX_CACHE_SIZE; 121 } 122 getMaxLifetimeFromProperty(CacheInfo cacheInfo)123 private static long getMaxLifetimeFromProperty(CacheInfo cacheInfo) { 124 String lifetimeProp = cacheInfo.getParams().get("back-expiry"); 125 if (lifetimeProp != null) { 126 if ("0".equals(lifetimeProp)) { 127 return -1L; 128 } 129 long factor = 1; 130 if (lifetimeProp.endsWith("m")) { 131 factor = JiveConstants.MINUTE; 132 } 133 else if (lifetimeProp.endsWith("h")) { 134 factor = JiveConstants.HOUR; 135 } 136 else if (lifetimeProp.endsWith("d")) { 137 factor = JiveConstants.DAY; 138 } 139 try { 140 return Long.parseLong(lifetimeProp.substring(0, lifetimeProp.length()-1)) * factor; 141 } 142 catch (NumberFormatException nfe) { 143 Log.warn("Unable to parse back-expiry for cache: " + cacheInfo.getCacheName()); 144 } 145 } 146 // Return default 147 return CacheFactory.DEFAULT_MAX_CACHE_LIFETIME; 148 } 149 getMinSizeFromProperty(CacheInfo cacheInfo)150 private long getMinSizeFromProperty(CacheInfo cacheInfo) { 151 String sizeProp = cacheInfo.getParams().get("back-size-low"); 152 if (sizeProp != null) { 153 if ("0".equals(sizeProp)) { 154 return -1L; 155 } 156 try { 157 return Integer.parseInt(sizeProp); 158 } 159 catch (NumberFormatException nfe) { 160 Log.warn("Unable to parse back-size-low for cache: " + cacheInfo.getCacheName()); 161 } 162 } 163 // Return default 164 return CacheFactory.DEFAULT_MAX_CACHE_SIZE; 165 } 166 } 167