diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java new file mode 100644 index 000000000..070a8b9fc --- /dev/null +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java @@ -0,0 +1,70 @@ +/** + * Copyright 2018 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.hibernate; + +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.hibernate.cache.CacheException; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.internal.util.jndi.JndiHelper; +import org.redisson.api.RedissonClient; + +/** + * Hibernate Cache region factory based on Redisson. + * Uses Redisson instance located in JNDI. + * + * @author Nikita Koksharov + * + */ +public class JndiRedissonRegionFactory extends RedissonRegionFactory { + + private static final long serialVersionUID = -4814502675083325567L; + + public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name"; + + @Override + protected RedissonClient createRedissonClient(Properties properties) { + String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties); + if (jndiName == null) { + throw new CacheException(JNDI_NAME + " property not set"); + } + + Properties jndiProperties = JndiHelper.extractJndiProperties(properties); + InitialContext context = null; + try { + context = new InitialContext(jndiProperties); + return (RedissonClient) context.lookup(jndiName); + } catch (NamingException e) { + throw new CacheException("Unable to locate Redisson instances by " + jndiName, e); + } finally { + if (context != null) { + try { + context.close(); + } catch (NamingException e) { + throw new CacheException("Unable to close JNDI context", e); + } + } + } + } + + @Override + public void stop() { + } + +} diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index 8a007e11f..df893403b 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -46,6 +46,8 @@ import org.redisson.hibernate.region.RedissonQueryRegion; import org.redisson.hibernate.region.RedissonTimestampsRegion; /** + * Hibernate Cache region factory based on Redisson. + * Creates own Redisson instance during region start. * * @author Nikita Koksharov * diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java new file mode 100644 index 000000000..070a8b9fc --- /dev/null +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java @@ -0,0 +1,70 @@ +/** + * Copyright 2018 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.hibernate; + +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.hibernate.cache.CacheException; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.internal.util.jndi.JndiHelper; +import org.redisson.api.RedissonClient; + +/** + * Hibernate Cache region factory based on Redisson. + * Uses Redisson instance located in JNDI. + * + * @author Nikita Koksharov + * + */ +public class JndiRedissonRegionFactory extends RedissonRegionFactory { + + private static final long serialVersionUID = -4814502675083325567L; + + public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name"; + + @Override + protected RedissonClient createRedissonClient(Properties properties) { + String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties); + if (jndiName == null) { + throw new CacheException(JNDI_NAME + " property not set"); + } + + Properties jndiProperties = JndiHelper.extractJndiProperties(properties); + InitialContext context = null; + try { + context = new InitialContext(jndiProperties); + return (RedissonClient) context.lookup(jndiName); + } catch (NamingException e) { + throw new CacheException("Unable to locate Redisson instances by " + jndiName, e); + } finally { + if (context != null) { + try { + context.close(); + } catch (NamingException e) { + throw new CacheException("Unable to close JNDI context", e); + } + } + } + } + + @Override + public void stop() { + } + +} diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index 90325490a..029aefc73 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -47,11 +47,12 @@ import org.redisson.hibernate.region.RedissonQueryRegion; import org.redisson.hibernate.region.RedissonTimestampsRegion; /** + * Hibernate Cache region factory based on Redisson. + * Creates own Redisson instance during region start. * * @author Nikita Koksharov * - */ -public class RedissonRegionFactory implements RegionFactory { + */public class RedissonRegionFactory implements RegionFactory { private static final Logger log = Logger.getLogger( RedissonRegionFactory.class ); diff --git a/redisson-hibernate/redisson-hibernate-52/pom.xml b/redisson-hibernate/redisson-hibernate-52/pom.xml index 6b1512257..012d77438 100644 --- a/redisson-hibernate/redisson-hibernate-52/pom.xml +++ b/redisson-hibernate/redisson-hibernate-52/pom.xml @@ -36,6 +36,14 @@ test + + org.springframework + spring-context + [3.1,5.0) + provided + true + + javax.xml.bind jaxb-api diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java new file mode 100644 index 000000000..070a8b9fc --- /dev/null +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java @@ -0,0 +1,70 @@ +/** + * Copyright 2018 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.hibernate; + +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.hibernate.cache.CacheException; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.internal.util.jndi.JndiHelper; +import org.redisson.api.RedissonClient; + +/** + * Hibernate Cache region factory based on Redisson. + * Uses Redisson instance located in JNDI. + * + * @author Nikita Koksharov + * + */ +public class JndiRedissonRegionFactory extends RedissonRegionFactory { + + private static final long serialVersionUID = -4814502675083325567L; + + public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name"; + + @Override + protected RedissonClient createRedissonClient(Properties properties) { + String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties); + if (jndiName == null) { + throw new CacheException(JNDI_NAME + " property not set"); + } + + Properties jndiProperties = JndiHelper.extractJndiProperties(properties); + InitialContext context = null; + try { + context = new InitialContext(jndiProperties); + return (RedissonClient) context.lookup(jndiName); + } catch (NamingException e) { + throw new CacheException("Unable to locate Redisson instances by " + jndiName, e); + } finally { + if (context != null) { + try { + context.close(); + } catch (NamingException e) { + throw new CacheException("Unable to close JNDI context", e); + } + } + } + } + + @Override + public void stop() { + } + +} diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index a7855b0c7..e0031b265 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -47,6 +47,8 @@ import org.redisson.hibernate.region.RedissonQueryRegion; import org.redisson.hibernate.region.RedissonTimestampsRegion; /** + * Hibernate Cache region factory based on Redisson. + * Creates own Redisson instance during region start. * * @author Nikita Koksharov * diff --git a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java new file mode 100644 index 000000000..84f7bd51c --- /dev/null +++ b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/JndiRedissonRegionFactory.java @@ -0,0 +1,71 @@ +/** + * Copyright 2018 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.hibernate; + +import java.util.Map; +import java.util.Properties; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.hibernate.cache.CacheException; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.internal.util.jndi.JndiHelper; +import org.redisson.api.RedissonClient; + +/** + * Hibernate Cache region factory based on Redisson. + * Uses Redisson instance located in JNDI. + * + * @author Nikita Koksharov + * + */ +public class JndiRedissonRegionFactory extends RedissonRegionFactory { + + private static final long serialVersionUID = -4814502675083325567L; + + public static final String JNDI_NAME = CONFIG_PREFIX + "jndi_name"; + + @Override + protected RedissonClient createRedissonClient(Map properties) { + String jndiName = ConfigurationHelper.getString(JNDI_NAME, properties); + if (jndiName == null) { + throw new CacheException(JNDI_NAME + " property not set"); + } + + Properties jndiProperties = JndiHelper.extractJndiProperties(properties); + InitialContext context = null; + try { + context = new InitialContext(jndiProperties); + return (RedissonClient) context.lookup(jndiName); + } catch (NamingException e) { + throw new CacheException("Unable to locate Redisson instances by " + jndiName, e); + } finally { + if (context != null) { + try { + context.close(); + } catch (NamingException e) { + throw new CacheException("Unable to close JNDI context", e); + } + } + } + } + + @Override + protected void releaseFromUse() { + } + +} diff --git a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index e360f3916..ba93f8f59 100644 --- a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -41,6 +41,8 @@ import org.redisson.client.codec.LongCodec; import org.redisson.config.Config; /** + * Hibernate Cache region factory based on Redisson. + * Creates own Redisson instance during region start. * * @author Nikita Koksharov * diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java index 6286448e3..9476c189a 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java @@ -332,7 +332,7 @@ public class CommandDecoder extends ReplayingDecoder { handleResult(data, parts, result, false, channel); } else if (code == '*') { long size = readLong(in); - final List respParts = new ArrayList(); + final List respParts = new ArrayList(Math.max((int)size, 0)); StateLevel lastLevel = null; if (state().isMakeCheckpoint()) { diff --git a/redisson/src/main/java/org/redisson/command/CommandBatchService.java b/redisson/src/main/java/org/redisson/command/CommandBatchService.java index c5f02724e..9428179d7 100644 --- a/redisson/src/main/java/org/redisson/command/CommandBatchService.java +++ b/redisson/src/main/java/org/redisson/command/CommandBatchService.java @@ -154,9 +154,6 @@ public class CommandBatchService extends CommandAsyncService { @Override public void async(boolean readOnlyMode, NodeSource nodeSource, Codec codec, RedisCommand command, Object[] params, RPromise mainPromise, int attempt, boolean ignoreRedirect) { - if (executed.get()) { - throw new IllegalStateException("Batch already has been executed!"); - } if (nodeSource.getEntry() != null) { Entry entry = commands.get(nodeSource.getEntry()); if (entry == null) { @@ -471,11 +468,10 @@ public class CommandBatchService extends CommandAsyncService { }); } - executed.set(true); - mainPromise.addListener(new FutureListener>>() { @Override public void operationComplete(Future>> future) throws Exception { + executed.set(true); if (!future.isSuccess()) { resultPromise.tryFailure(future.cause()); return; @@ -525,8 +521,6 @@ public class CommandBatchService extends CommandAsyncService { return resultPromise; } - executed.set(true); - if (this.options.getExecutionMode() != ExecutionMode.IN_MEMORY) { for (Entry entry : commands.values()) { BatchCommandData multiCommand = new BatchCommandData(RedisCommands.MULTI, new Object[] {}, index.incrementAndGet()); @@ -560,6 +554,7 @@ public class CommandBatchService extends CommandAsyncService { @Override public void operationComplete(Future future) throws Exception { // commands = null; + executed.set(true); nestedServices.clear(); } }); @@ -569,6 +564,7 @@ public class CommandBatchService extends CommandAsyncService { voidPromise.addListener(new FutureListener() { @Override public void operationComplete(Future future) throws Exception { + executed.set(true); if (!future.isSuccess()) { promise.tryFailure(future.cause()); commands = null; diff --git a/redisson/src/main/java/org/redisson/config/Config.java b/redisson/src/main/java/org/redisson/config/Config.java index af8e505b0..cdf70bd70 100644 --- a/redisson/src/main/java/org/redisson/config/Config.java +++ b/redisson/src/main/java/org/redisson/config/Config.java @@ -111,8 +111,7 @@ public class Config { if (oldConf.getCodec() == null) { // use it by default - oldConf.setCodec(new JsonJacksonCodec()); -// oldConf.setCodec(new FstCodec()); + oldConf.setCodec(new FstCodec()); } setUseScriptCache(oldConf.isUseScriptCache()); @@ -583,6 +582,8 @@ public class Config { *

* This prevents against infinity locked locks due to Redisson client crush or * any other reason when lock can't be released in proper way. + *

+ * Default is 30000 milliseconds * * @param lockWatchdogTimeout timeout in milliseconds * @return config