001package org.avaje.ebean.ignite.config; 002 003import com.avaje.ebean.cache.ServerCacheType; 004import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy; 005import org.apache.ignite.configuration.CacheConfiguration; 006import org.apache.ignite.configuration.NearCacheConfiguration; 007import org.jetbrains.annotations.Nullable; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011import java.util.List; 012 013/** 014 * Determines the cache configuration that should be applied to any given L2 cache. 015 */ 016public class ConfigManager { 017 018 private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class); 019 020 private final L2Configuration configuration; 021 022 private final L2CacheConfig baseQuery; 023 private final L2CacheConfig baseBean; 024 private final L2CacheConfig baseKey; 025 private final L2CacheConfig baseManyIds; 026 027 /** 028 * Create given the configuration. 029 */ 030 public ConfigManager(L2Configuration configuration) { 031 032 this.configuration = configuration; 033 034 L2CacheConfig base = defaultConfig(configuration.getBase()); 035 this.baseQuery = add(base, configuration.getBaseQuery()); 036 this.baseBean = add(base, configuration.getBaseBean()); 037 this.baseKey = add(base, configuration.getBaseKey()); 038 this.baseManyIds = add(base, configuration.getBaseManyIds()); 039 } 040 041 /** 042 * Add the configurations together apply over the top of base. 043 */ 044 private L2CacheConfig add(L2CacheConfig base, L2CacheConfig apply) { 045 return AddL2CacheConfig.add(base, apply); 046 } 047 048 /** 049 * Return the config with an empty default if required. 050 */ 051 private L2CacheConfig defaultConfig(L2CacheConfig base) { 052 return (base != null) ? base : new L2CacheConfig(); 053 } 054 055 /** 056 * Return the config pair for main and near cache given the type and key. 057 */ 058 public ConfigPair getConfig(ServerCacheType type, String key) { 059 060 L2CacheConfig config = getBase(type); 061 062 L2Apply apply = configuration.getApply(); 063 if (apply != null) { 064 List<L2CacheMatch> match = apply.getMatch(); 065 for (L2CacheMatch l2CacheMatch : match) { 066 if (isMatch(type, key, l2CacheMatch)) { 067 logger.debug("match for type[{}] key[{}] to config [{}]", type, key, l2CacheMatch); 068 config = add(config, l2CacheMatch.getConfig()); 069 } 070 } 071 } 072 073 return createPair(type, config); 074 } 075 076 private ConfigPair createPair(ServerCacheType type, L2CacheConfig config) { 077 078 CacheConfiguration main = new CacheConfiguration(); 079 AddL2CacheConfig.apply(main, config); 080 081 NearCacheConfiguration near = getNearCacheConfig(type, config); 082 083 return new ConfigPair(main, near); 084 } 085 086 @Nullable 087 @SuppressWarnings("unchecked") 088 private NearCacheConfiguration getNearCacheConfig(ServerCacheType type, L2CacheConfig config) { 089 090 if (type.equals(ServerCacheType.QUERY) || config.getNearSize() == null) { 091 return null; 092 093 } else { 094 NearCacheConfiguration near = new NearCacheConfiguration(); 095 near.setNearEvictionPolicy(new LruEvictionPolicy(config.getNearSize())); 096 return near; 097 } 098 } 099 100 private boolean isMatch(ServerCacheType type, String key, L2CacheMatch l2CacheMatch) { 101 102 switch (type) { 103 case QUERY: 104 return isMatch(l2CacheMatch.isTypeQuery(), key, l2CacheMatch); 105 case BEAN: 106 return isMatch(l2CacheMatch.isTypeBean(), key, l2CacheMatch); 107 case NATURAL_KEY: 108 return isMatch(l2CacheMatch.isTypeKey(), key, l2CacheMatch); 109 case COLLECTION_IDS: 110 return isMatch(l2CacheMatch.isTypeManyId(), key, l2CacheMatch); 111 default : 112 throw new IllegalStateException("Unknown type "+type); 113 } 114 } 115 116 private boolean isMatch(Boolean typeMatch, String key, L2CacheMatch l2CacheMatch) { 117 return isTrue(typeMatch) && isMatch(key, l2CacheMatch.getMatchClasses()); 118 } 119 120 private boolean isMatch(String key, String matchClasses) { 121 String[] matches = matchClasses.split("[,;]"); 122 for (int i = 0; i < matches.length; i++) { 123 String matcher = matches[i].trim(); 124 if (!matcher.contains(".")) { 125 matcher = "." + matcher; 126 key = key.toLowerCase(); 127 } 128 if (key.contains(matcher)) { 129 return true; 130 } 131 } 132 return false; 133 } 134 135 private boolean isTrue(Boolean typeBean) { 136 return Boolean.TRUE.equals(typeBean); 137 } 138 139 /** 140 * Return the base configuration based on the cache type. 141 */ 142 private L2CacheConfig getBase(ServerCacheType type) { 143 switch (type) { 144 case QUERY: 145 return baseQuery; 146 case BEAN: 147 return baseBean; 148 case NATURAL_KEY: 149 return baseKey; 150 case COLLECTION_IDS: 151 return baseManyIds; 152 default: 153 throw new IllegalStateException("Invalid type " + type); 154 } 155 156 } 157}