diff --git a/core/src/net/oschina/j2cache/J2CacheConfig.java b/core/src/net/oschina/j2cache/J2CacheConfig.java index 7286dc3b9e17fc54c93e472490fdbf31ab219291..246a43430e798062e02e529269ec654cf4534a38 100644 --- a/core/src/net/oschina/j2cache/J2CacheConfig.java +++ b/core/src/net/oschina/j2cache/J2CacheConfig.java @@ -124,18 +124,31 @@ public class J2CacheConfig { /** * get j2cache properties stream + * (issue:https://gitee.com/ld/J2Cache/issues/I5OOTA fix by Mori) + * * * @return config stream */ private static InputStream getConfigStream(String resource) { - InputStream configStream = J2Cache.class.getResourceAsStream(resource); - if (configStream == null) { - configStream = J2Cache.class.getClassLoader().getParent().getResourceAsStream(resource); - } - if (configStream == null) { - throw new CacheException("Cannot find " + resource + " !!!"); + + File resourcePath =new File(resource); + InputStream configStream = null; + try{ + configStream = new FileInputStream(resourcePath); + }catch (FileNotFoundException e){ + if(configStream == null){ + configStream = J2Cache.class.getResourceAsStream(resource); + } + + if (configStream == null) { + configStream = J2Cache.class.getClassLoader().getParent().getResourceAsStream(resource); + } + if (configStream == null) { + throw new CacheException("Cannot find " + resource + " !!!"); + } } return configStream; + } public void dump(PrintStream writer) { diff --git a/core/src/net/oschina/j2cache/caffeine/CaffeineProvider.java b/core/src/net/oschina/j2cache/caffeine/CaffeineProvider.java index f187de84868649eb260246c7706f88cb3b0260bf..d234945fd297c05d723fc3afd6ee18c0538c35c1 100644 --- a/core/src/net/oschina/j2cache/caffeine/CaffeineProvider.java +++ b/core/src/net/oschina/j2cache/caffeine/CaffeineProvider.java @@ -23,8 +23,7 @@ import net.oschina.j2cache.util.PatternMatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.util.Collection; import java.util.ArrayList; import java.util.Map; @@ -158,10 +157,7 @@ public class CaffeineProvider implements CacheProvider { if (propertiesFile != null && propertiesFile.trim().length() > 0) { InputStream stream = null; try { - stream = getClass().getResourceAsStream(propertiesFile); - if (stream == null) { - stream = getClass().getClassLoader().getResourceAsStream(propertiesFile); - } + stream = this.getConfigStream(propertiesFile); Properties regionsProps = new Properties(); regionsProps.load(stream); for (String region : regionsProps.stringPropertyNames()) { @@ -181,6 +177,26 @@ public class CaffeineProvider implements CacheProvider { } } } + /** + * get caffeine properties stream + * (issue:https://gitee.com/ld/J2Cache/issues/I5OOTA fix by Mori) + * **/ + private InputStream getConfigStream(String propertiesFile) { + File resourcePath =new File(propertiesFile); + InputStream configStream = null; + try{ + configStream = new FileInputStream(resourcePath); + }catch (FileNotFoundException e){ + if(configStream == null){ + configStream = getClass().getResourceAsStream(propertiesFile); + } + + if (configStream == null) { + configStream = getClass().getClassLoader().getParent().getResourceAsStream(propertiesFile); + } + } + return configStream; + } private CacheConfig findCacheConfig(String region){ for (Map.Entry entry : cacheConfigs.entrySet()) { diff --git a/core/test/caffeine-test.properties b/core/test/caffeine-test.properties new file mode 100644 index 0000000000000000000000000000000000000000..ab14474ca864b033c4ef05277c28f0e80d3af15c --- /dev/null +++ b/core/test/caffeine-test.properties @@ -0,0 +1,6 @@ +######################################### +# Caffeine configuration +# [name] = size, xxxx[s|m|h|d] +######################################### + +default = 1000, 30m \ No newline at end of file diff --git a/core/test/j2cache-test.properties b/core/test/j2cache-test.properties new file mode 100644 index 0000000000000000000000000000000000000000..c705c838495b7670e9a442b07905fcec7387248d --- /dev/null +++ b/core/test/j2cache-test.properties @@ -0,0 +1,205 @@ +#J2Cache configuration + + +######################################### +# Cache Broadcast Method +# values: +# jgroups -> use jgroups's multicast +# redis -> use redis publish/subscribe mechanism (using jedis) +# lettuce -> use redis publish/subscribe mechanism (using lettuce, Recommend) +# rabbitmq -> use RabbitMQ publisher/consumer mechanism +# rocketmq -> use RocketMQ publisher/consumer mechanism +# none -> don't notify the other nodes in cluster +# xx.xxxx.xxxx.Xxxxx your own cache broadcast policy classname that implement net.oschina.j2cache.cluster.ClusterPolicy +######################################### + +j2cache.broadcast = redis + +# jgroups properties +jgroups.channel.name = j2cache +jgroups.configXml = /network.xml + +# RabbitMQ properties +rabbitmq.exchange = j2cache +rabbitmq.host = localhost +rabbitmq.port = 5672 +rabbitmq.username = guest +rabbitmq.password = guest + +# RocketMQ properties +rocketmq.name = j2cache +rocketmq.topic = j2cache +# use ; to split multi hosts +rocketmq.hosts = 127.0.0.1:9876 + +######################################### +# Level 1&2 provider +# values: +# none -> disable this level cache +# ehcache -> use ehcache2 as level 1 cache +# ehcache3 -> use ehcache3 as level 1 cache +# caffeine -> use caffeine as level 1 cache(only in memory) +# redis -> use redis as level 2 cache (using jedis) +# lettuce -> use redis as level 2 cache (using lettuce) +# readonly-redis -> use redis as level 2 cache ,but never write data to it. if use this provider, you must uncomment `j2cache.L2.config_section` to make the redis configurations available. +# memcached -> use memcached as level 2 cache (xmemcached), +# [classname] -> use custom provider +######################################### + +j2cache.L1.provider_class = caffeine +j2cache.L2.provider_class = redis + +# When L2 provider isn't `redis`, using `L2.config_section = redis` to read redis configurations +# j2cache.L2.config_section = redis + +# Enable/Disable ttl in redis cache data (if disabled, the object in redis will never expire, default:true) +# NOTICE: redis hash mode (redis.storage = hash) do not support this feature) +j2cache.sync_ttl_to_redis = true + +# Whether to cache null objects by default (default false) +j2cache.default_cache_null_object = true + +######################################### +# Cache Serialization Provider +# values: +# fst -> using fast-serialization (recommend) +# kryo -> using kryo serialization +# json -> using fst's json serialization (testing) +# fastjson -> using fastjson serialization (embed non-static class not support) +# java -> java standard +# fse -> using fse serialization +# [classname implements Serializer] +######################################### + +j2cache.serialization = json +#json.map.person = net.oschina.j2cache.demo.Person + +######################################### +# Ehcache configuration +######################################### + +# ehcache.configXml = /ehcache.xml + +# ehcache3.configXml = /ehcache3.xml +# ehcache3.defaultHeapSize = 1000 + +######################################### +# Caffeine configuration +# caffeine.region.[name] = size, xxxx[s|m|h|d] +# +######################################### +caffeine.properties = ${caffeine.path.wait.replace} + +######################################### +# Redis connection configuration +######################################### + +######################################### +# Redis Cluster Mode +# +# single -> single redis server +# sentinel -> master-slaves servers +# cluster -> cluster servers (\u6570\u636e\u5e93\u914d\u7f6e\u65e0\u6548\uff0c\u4f7f\u7528 database = 0\uff09 +# sharded -> sharded servers (\u5bc6\u7801\u3001\u6570\u636e\u5e93\u5fc5\u987b\u5728 hosts \u4e2d\u6307\u5b9a\uff0c\u4e14\u8fde\u63a5\u6c60\u914d\u7f6e\u65e0\u6548 ; redis://user:password@127.0.0.1:6379/0\uff09 +# +######################################### + +redis.mode = single + +#redis storage mode (generic|hash) +redis.storage = generic + +## redis pub/sub channel name +redis.channel = j2cache +## redis pub/sub server (using redis.hosts when empty) +redis.channel.host = + +#cluster name just for sharded +redis.cluster_name = j2cache + +## redis cache namespace optional, default[empty] +redis.namespace = + +## redis command scan parameter count, default[1000] +#redis.scanCount = 1000 + +## connection +# Separate multiple redis nodes with commas, such as 192.168.0.10:6379,192.168.0.11:6379,192.168.0.12:6379 + +redis.hosts = 127.0.0.1:6379 +redis.timeout = 2000 +redis.password = +redis.database = 0 +redis.ssl = false + +## redis pool properties +redis.maxTotal = 100 +redis.maxIdle = 10 +redis.maxWaitMillis = 5000 +redis.minEvictableIdleTimeMillis = 60000 +redis.minIdle = 1 +redis.numTestsPerEvictionRun = 10 +redis.lifo = false +redis.softMinEvictableIdleTimeMillis = 10 +redis.testOnBorrow = true +redis.testOnReturn = false +redis.testWhileIdle = true +redis.timeBetweenEvictionRunsMillis = 300000 +redis.blockWhenExhausted = false +redis.jmxEnabled = false + +######################################### +# Lettuce scheme +# +# redis -> single redis server +# rediss -> single redis server with ssl +# redis-sentinel -> redis sentinel +# redis-cluster -> cluster servers +# +######################################### + +######################################### +# Lettuce Mode +# +# single -> single redis server +# sentinel -> master-slaves servers +# cluster -> cluster servers (\u6570\u636e\u5e93\u914d\u7f6e\u65e0\u6548\uff0c\u4f7f\u7528 database = 0\uff09 +# sharded -> sharded servers (\u5bc6\u7801\u3001\u6570\u636e\u5e93\u5fc5\u987b\u5728 hosts \u4e2d\u6307\u5b9a\uff0c\u4e14\u8fde\u63a5\u6c60\u914d\u7f6e\u65e0\u6548 ; redis://user:password@127.0.0.1:6379/0\uff09 +# +######################################### + +## redis command scan parameter count, default[1000] +#lettuce.scanCount = 1000 +lettuce.mode = single +lettuce.namespace = +lettuce.storage = hash +lettuce.channel = j2cache +lettuce.scheme = redis +lettuce.hosts = 127.0.0.1:6379 +lettuce.password = +lettuce.database = 0 +lettuce.sentinelMasterId = +lettuce.sentinelPassword = +lettuce.maxTotal = 100 +lettuce.maxIdle = 10 +lettuce.minIdle = 10 +# timeout in milliseconds +lettuce.timeout = 10000 +# redis cluster topology refresh interval in milliseconds +lettuce.clusterTopologyRefresh = 3000 + +######################################### +# memcached server configurations +# refer to https://gitee.com/mirrors/XMemcached +######################################### + +memcached.servers = 127.0.0.1:11211 +memcached.username = +memcached.password = +memcached.connectionPoolSize = 10 +memcached.connectTimeout = 1000 +memcached.failureMode = false +memcached.healSessionInterval = 1000 +memcached.maxQueuedNoReplyOperations = 100 +memcached.opTimeout = 100 +memcached.sanitizeKeys = false diff --git a/core/test/net/oschina/j2cache/LoadConfigPropertiesTest.java b/core/test/net/oschina/j2cache/LoadConfigPropertiesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dffa8e4af15190f228ed529fa3c8df0532cecd99 --- /dev/null +++ b/core/test/net/oschina/j2cache/LoadConfigPropertiesTest.java @@ -0,0 +1,80 @@ +package net.oschina.j2cache; + +import org.junit.Assert; +import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; + +import java.io.IOException; + +/** + * issue https://gitee.com/ld/J2Cache/issues/I5OOTA 问题1测试 + * 1.兼容旧的指定相对路径的方式读取配置文件j2cache.properies + * 2.支持优先读取全路径的方式读取配置文件j2cache.properies + * + * **/ +public class LoadConfigPropertiesTest { + + + private final static String CONFIG_FILE_RELATIVE_PATH = "/j2cache.properties"; + + private final static String FULL_FILE_RELATIVE_PATH = LoadConfigPropertiesTest.class.getResource("/").getPath()+"j2cache-test.properties"; + + //switch path to test load properites + private final static boolean FULL_PATH_SWITCH = true; + + private static J2CacheConfig config; + + + private final static String CAFFEINE_FULL_PATH=LoadConfigPropertiesTest.class.getResource("/").getPath()+"caffeine-test.properties"; + + + + static { + try { + + if(FULL_PATH_SWITCH) + { + //init caffeine path + System.out.println("j2cache current full path ="+FULL_FILE_RELATIVE_PATH); + config = J2CacheConfig.initFromConfig(FULL_FILE_RELATIVE_PATH); + }else{ + System.out.println("current path ="+CONFIG_FILE_RELATIVE_PATH); + config = J2CacheConfig.initFromConfig(CONFIG_FILE_RELATIVE_PATH); + } + + } catch (IOException e) { + throw new CacheException("Failed to load j2cache configuration " + CONFIG_FILE_RELATIVE_PATH, e); + } + } + + public static void main(String[] args) { + + System.out.println("------test load j2cache----"); + testLoadJ2Cache(); + System.out.println("------test load caffine----"); + testLoadCaffine(); + } + + + private static void testLoadJ2Cache() { + //test read j2cache + Assert.assertTrue(config!=null); + if(FULL_PATH_SWITCH){ + Assert.assertEquals("${caffeine.path.wait.replace}",config.getProperties().getProperty("caffeine.properties")); + }else{ + Assert.assertEquals("/caffeine.properties",config.getProperties().getProperty("caffeine.properties")); + } + } + + private static void testLoadCaffine() { + + if(FULL_PATH_SWITCH){ + config.getL1CacheProperties().setProperty("properties",CAFFEINE_FULL_PATH); + CacheProviderHolder holder = CacheProviderHolder.init(config,null); + System.out.println(holder.getL1Provider().name()); + }else{ + CacheProviderHolder holder = CacheProviderHolder.init(config,null); + System.out.println(holder.getL1Provider().name()); + } + + } +}