From b57a0d572d1f6ed85ddb1ac04071fa870eaf5c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20J=C3=B6nsson?= Date: Mon, 10 Apr 2017 11:12:25 +0300 Subject: [PATCH] Made it possible to change hazelcast instance factory. Fixes #21. (#25) * Made it possible to change hazelcast instance factory. Fixes #21. This is better because many third-party db libraries assume that properties in Properties are Strings, not objects. --- .../AbstractHazelcastCacheRegionFactory.java | 18 ++++++++++-- .../hazelcast/hibernate/CacheEnvironment.java | 7 +++++ ...a => DefaultHazelcastInstanceFactory.java} | 21 ++++---------- .../instance/HazelcastInstanceLoader.java | 2 +- .../instance/IHazelcastInstanceFactory.java | 28 +++++++++++++++++++ .../hibernate/HibernateTestSupport.java | 6 ++-- .../HazelcastMockInstanceFactory.java | 21 ++++++++++++++ 7 files changed, 83 insertions(+), 20 deletions(-) rename hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/{HazelcastInstanceFactory.java => DefaultHazelcastInstanceFactory.java} (68%) create mode 100644 hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/IHazelcastInstanceFactory.java create mode 100644 hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/instance/HazelcastMockInstanceFactory.java diff --git a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/AbstractHazelcastCacheRegionFactory.java b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/AbstractHazelcastCacheRegionFactory.java index 194661a6..e9905954 100644 --- a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/AbstractHazelcastCacheRegionFactory.java +++ b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/AbstractHazelcastCacheRegionFactory.java @@ -17,7 +17,8 @@ package com.hazelcast.hibernate; import com.hazelcast.core.HazelcastInstance; -import com.hazelcast.hibernate.instance.HazelcastInstanceFactory; +import com.hazelcast.hibernate.instance.DefaultHazelcastInstanceFactory; +import com.hazelcast.hibernate.instance.IHazelcastInstanceFactory; import com.hazelcast.hibernate.instance.IHazelcastInstanceLoader; import com.hazelcast.hibernate.local.CleanupService; import com.hazelcast.hibernate.region.HazelcastQueryResultsRegion; @@ -79,7 +80,20 @@ public long nextTimestamp() { public void start(final SessionFactoryOptions options, final Properties properties) throws CacheException { log.info("Starting up " + getClass().getSimpleName()); if (instance == null || !instance.getLifecycleService().isRunning()) { - instanceLoader = HazelcastInstanceFactory.createInstanceLoader(properties); + String defaultFactory = DefaultHazelcastInstanceFactory.class.getName(); + String factoryName = properties.getProperty(CacheEnvironment.HAZELCAST_FACTORY, defaultFactory); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + try { + Class factory = + (Class) Class.forName(factoryName, true, cl); + instanceLoader = factory.newInstance().createInstanceLoader(properties); + } catch (ClassNotFoundException e) { + throw new CacheException("Failed to set up hazelcast instance factory", e); + } catch (InstantiationException e) { + throw new CacheException("Failed to set up hazelcast instance factory", e); + } catch (IllegalAccessException e) { + throw new CacheException("Failed to set up hazelcast instance factory", e); + } instance = instanceLoader.loadInstance(); } cleanupService = new CleanupService(instance.getName()); diff --git a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/CacheEnvironment.java b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/CacheEnvironment.java index 1cda2e8a..d2ada1ec 100644 --- a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/CacheEnvironment.java +++ b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/CacheEnvironment.java @@ -96,6 +96,13 @@ public final class CacheEnvironment { */ public static final String HAZELCAST_SHUTDOWN_HOOK_ENABLED = "hazelcast.shutdownhook.enabled"; + /** + * Property to configure which {@link com.hazelcast.hibernate.instance.IHazelcastInstanceFactory} + * that shall be used for creating + * {@link com.hazelcast.hibernate.instance.IHazelcastInstanceLoader hazelcast instance loaders}. + */ + public static final String HAZELCAST_FACTORY = "hibernate.cache.hazelcast.factory"; + // milliseconds private static final int MAXIMUM_LOCK_TIMEOUT = 10000; diff --git a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceFactory.java b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/DefaultHazelcastInstanceFactory.java similarity index 68% rename from hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceFactory.java rename to hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/DefaultHazelcastInstanceFactory.java index 261aac8c..41dea776 100644 --- a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceFactory.java +++ b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/DefaultHazelcastInstanceFactory.java @@ -22,27 +22,18 @@ import java.util.Properties; /** - * A factory class to build up implementations of {@link com.hazelcast.hibernate.instance.IHazelcastInstanceLoader} - * that returns a {@link com.hazelcast.core.HazelcastInstance} depending on configuration either backed by Hazelcast + * A factory that returns a {@link com.hazelcast.core.HazelcastInstance} depending on configuration either backed by Hazelcast * client or node implementation. */ -public final class HazelcastInstanceFactory { - +public final class DefaultHazelcastInstanceFactory implements IHazelcastInstanceFactory +{ private static final String HZ_CLIENT_LOADER_CLASSNAME = "com.hazelcast.hibernate.instance.HazelcastClientLoader"; private static final String HZ_INSTANCE_LOADER_CLASSNAME = "com.hazelcast.hibernate.instance.HazelcastInstanceLoader"; - private HazelcastInstanceFactory() { - } - - public static IHazelcastInstanceLoader createInstanceLoader(final Properties props) throws CacheException { + public IHazelcastInstanceLoader createInstanceLoader(final Properties props) throws CacheException { try { - IHazelcastInstanceLoader instanceLoader = (IHazelcastInstanceLoader) props. - get("com.hazelcast.hibernate.instance.loader"); - if (instanceLoader != null) { - return instanceLoader; - } Class loaderClass = getInstanceLoaderClass(props); - instanceLoader = (IHazelcastInstanceLoader) loaderClass.newInstance(); + IHazelcastInstanceLoader instanceLoader = (IHazelcastInstanceLoader) loaderClass.newInstance(); instanceLoader.configure(props); return instanceLoader; } catch (Exception e) { @@ -51,7 +42,7 @@ public static IHazelcastInstanceLoader createInstanceLoader(final Properties pro } private static Class getInstanceLoaderClass(final Properties props) throws ClassNotFoundException { - ClassLoader cl = HazelcastInstanceFactory.class.getClassLoader(); + ClassLoader cl = DefaultHazelcastInstanceFactory.class.getClassLoader(); if (props != null && CacheEnvironment.isNativeClient(props)) { return cl.loadClass(HZ_CLIENT_LOADER_CLASSNAME); } else { diff --git a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceLoader.java b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceLoader.java index 85cec791..977f2a2c 100644 --- a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceLoader.java +++ b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/HazelcastInstanceLoader.java @@ -36,7 +36,7 @@ */ class HazelcastInstanceLoader implements IHazelcastInstanceLoader { - private static final ILogger LOGGER = Logger.getLogger(HazelcastInstanceFactory.class); + private static final ILogger LOGGER = Logger.getLogger(IHazelcastInstanceFactory.class); private HazelcastInstance instance; private Config config; diff --git a/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/IHazelcastInstanceFactory.java b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/IHazelcastInstanceFactory.java new file mode 100644 index 00000000..1233e625 --- /dev/null +++ b/hazelcast-hibernate5/src/main/java/com/hazelcast/hibernate/instance/IHazelcastInstanceFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved. + * + * 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 com.hazelcast.hibernate.instance; + +import org.hibernate.cache.CacheException; + +import java.util.Properties; + +/** + * A hookable factory class to build up implementations of {@link com.hazelcast.hibernate.instance.IHazelcastInstanceLoader} + */ +public interface IHazelcastInstanceFactory { + IHazelcastInstanceLoader createInstanceLoader(final Properties props) throws CacheException; +} diff --git a/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/HibernateTestSupport.java b/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/HibernateTestSupport.java index f63a8b8e..4b75bcfe 100644 --- a/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/HibernateTestSupport.java +++ b/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/HibernateTestSupport.java @@ -20,6 +20,7 @@ import com.hazelcast.core.HazelcastInstance; import com.hazelcast.hibernate.entity.AnnotatedEntity; import com.hazelcast.hibernate.instance.HazelcastAccessor; +import com.hazelcast.hibernate.instance.HazelcastMockInstanceFactory; import com.hazelcast.hibernate.instance.IHazelcastInstanceLoader; import com.hazelcast.logging.ILogger; import com.hazelcast.logging.Logger; @@ -76,10 +77,11 @@ protected SessionFactory createSessionFactory(final Properties props, final IHazelcastInstanceLoader customInstanceLoader) { props.put(CacheEnvironment.EXPLICIT_VERSION_CHECK, "true"); if (customInstanceLoader != null) { - props.put("com.hazelcast.hibernate.instance.loader", customInstanceLoader); + HazelcastMockInstanceFactory.setThreadLocalLoader(customInstanceLoader); + props.setProperty("hibernate.cache.hazelcast.factory", "com.hazelcast.hibernate.instance.HazelcastMockInstanceFactory"); customInstanceLoader.configure(props); } else { - props.remove("com.hazelcast.hibernate.instance.loader"); + props.remove("hibernate.cache.hazelcast.factory"); } final Configuration conf = new Configuration(); diff --git a/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/instance/HazelcastMockInstanceFactory.java b/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/instance/HazelcastMockInstanceFactory.java new file mode 100644 index 00000000..3378f2ee --- /dev/null +++ b/hazelcast-hibernate5/src/test/java/com/hazelcast/hibernate/instance/HazelcastMockInstanceFactory.java @@ -0,0 +1,21 @@ +package com.hazelcast.hibernate.instance; + +import org.hibernate.cache.CacheException; + +import java.util.Properties; + +public class HazelcastMockInstanceFactory implements IHazelcastInstanceFactory +{ + private static ThreadLocal loaders = new ThreadLocal(); + + public static void setThreadLocalLoader(IHazelcastInstanceLoader loader) + { + loaders.set(loader); + } + + @Override + public IHazelcastInstanceLoader createInstanceLoader(Properties props) throws CacheException + { + return loaders.get(); + } +}