mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged BRANCHES/DEV/mward/cifs_hazelcast_conf to HEAD:
36500: ALF-13821: CIFS and WebDAV should use same Hazelcast configuration mechanism 36507: ALF-13821: CIFS and WebDAV should use same Hazelcast configuration mechanism 36511: ALF-13821: CIFS and WebDAV should use same Hazelcast configuration mechanism 36519: ALF-13821: Extract hazelcastConfig, hazelcastInstanceFactory bean definitions from webdav-context.xml to cluster-context.xml 36553: ALF-13821: CIFS and WebDAV should use same Hazelcast configuration mechanism git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@36581 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -43,6 +43,7 @@
|
|||||||
<import resource="classpath:alfresco/activities/activities-feed-context.xml" />
|
<import resource="classpath:alfresco/activities/activities-feed-context.xml" />
|
||||||
<import resource="classpath:alfresco/tagging-services-context.xml"/>
|
<import resource="classpath:alfresco/tagging-services-context.xml"/>
|
||||||
<import resource="classpath:alfresco/invitation-service-context.xml"/>
|
<import resource="classpath:alfresco/invitation-service-context.xml"/>
|
||||||
|
<import resource="classpath:alfresco/cluster-context.xml"/>
|
||||||
<import resource="classpath:alfresco/webdav-context.xml"/>
|
<import resource="classpath:alfresco/webdav-context.xml"/>
|
||||||
<import resource="classpath*:alfresco/patch/*-context.xml" />
|
<import resource="classpath*:alfresco/patch/*-context.xml" />
|
||||||
</beans>
|
</beans>
|
||||||
|
18
config/alfresco/cluster-context.xml
Normal file
18
config/alfresco/cluster-context.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
<bean id="hazelcastConfig" class="org.alfresco.repo.cluster.HazelcastConfigFactoryBean">
|
||||||
|
<property name="configFile" value="${alfresco.hazelcast.configLocation}"/>
|
||||||
|
<property name="properties">
|
||||||
|
<props>
|
||||||
|
<prop key="alfresco.cluster.name">${alfresco.cluster.name}</prop>
|
||||||
|
<prop key="alfresco.hazelcast.password">${alfresco.hazelcast.password}</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="hazelcastInstanceFactory" class="org.alfresco.repo.cluster.HazelcastInstanceFactory">
|
||||||
|
<property name="config" ref="hazelcastConfig"/>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
@@ -288,15 +288,7 @@
|
|||||||
|
|
||||||
<!-- Cluster Configuration -->
|
<!-- Cluster Configuration -->
|
||||||
<bean id="fileSystemClusterConfig" class="org.alfresco.filesys.config.ClusterConfigBean">
|
<bean id="fileSystemClusterConfig" class="org.alfresco.filesys.config.ClusterConfigBean">
|
||||||
<property name="clusterEnabled">
|
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
|
||||||
<value>${filesystem.cluster.enabled}</value>
|
|
||||||
</property>
|
|
||||||
<property name="clusterName">
|
|
||||||
<value>${filesystem.cluster.name}</value>
|
|
||||||
</property>
|
|
||||||
<property name="configFile">
|
|
||||||
<value>${filesystem.cluster.configFile}</value>
|
|
||||||
</property>
|
|
||||||
<property name="debugFlags">
|
<property name="debugFlags">
|
||||||
<value>${filesystem.cluster.debugFlags}</value>
|
<value>${filesystem.cluster.debugFlags}</value>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -26,22 +26,6 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="webdavLockStoreFactory" class="org.alfresco.repo.webdav.LockStoreFactoryImpl">
|
<bean id="webdavLockStoreFactory" class="org.alfresco.repo.webdav.LockStoreFactoryImpl">
|
||||||
<property name="clusterName" value="${alfresco.cluster.name}"/>
|
|
||||||
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
|
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="hazelcastConfig" class="org.alfresco.repo.cluster.HazelcastConfigFactoryBean">
|
|
||||||
<property name="configFile" value="${alfresco.hazelcast.configLocation}"/>
|
|
||||||
<property name="properties">
|
|
||||||
<props>
|
|
||||||
<prop key="alfresco.cluster.name">${alfresco.cluster.name}</prop>
|
|
||||||
<prop key="alfresco.hazelcast.password">${alfresco.hazelcast.password}</prop>
|
|
||||||
</props>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="hazelcastInstanceFactory" class="org.alfresco.repo.cluster.HazelcastInstanceFactory">
|
|
||||||
<property name="config" ref="hazelcastConfig"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
</beans>
|
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.filesys.config;
|
package org.alfresco.filesys.config;
|
||||||
|
|
||||||
|
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class ClusterConfigBean.
|
* The Class ClusterConfigBean.
|
||||||
*
|
*
|
||||||
@@ -26,40 +28,29 @@ package org.alfresco.filesys.config;
|
|||||||
*/
|
*/
|
||||||
public class ClusterConfigBean
|
public class ClusterConfigBean
|
||||||
{
|
{
|
||||||
private boolean isClusterEnabled = false;
|
private HazelcastInstanceFactory hazelcastInstanceFactory;
|
||||||
private String configFile;
|
|
||||||
private String clusterName;
|
|
||||||
private String debugFlags;
|
private String debugFlags;
|
||||||
private int nearCacheTimeout;
|
private int nearCacheTimeout;
|
||||||
|
|
||||||
public void setClusterEnabled(boolean clusterEnabled)
|
|
||||||
|
public void setHazelcastInstanceFactory(HazelcastInstanceFactory hazelcastInstanceFactory)
|
||||||
{
|
{
|
||||||
this.isClusterEnabled = clusterEnabled;
|
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HazelcastInstanceFactory getHazelcastInstanceFactory()
|
||||||
|
{
|
||||||
|
return this.hazelcastInstanceFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getClusterEnabled()
|
public boolean getClusterEnabled()
|
||||||
{
|
{
|
||||||
return isClusterEnabled;
|
return hazelcastInstanceFactory.isClusteringEnabled();
|
||||||
}
|
|
||||||
|
|
||||||
public void setClusterName(String clusterName)
|
|
||||||
{
|
|
||||||
this.clusterName = clusterName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClusterName()
|
public String getClusterName()
|
||||||
{
|
{
|
||||||
return clusterName;
|
return hazelcastInstanceFactory.getClusterName();
|
||||||
}
|
|
||||||
|
|
||||||
public void setConfigFile(String configFile)
|
|
||||||
{
|
|
||||||
this.configFile = configFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getConfigFile()
|
|
||||||
{
|
|
||||||
return configFile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDebugFlags(String debugFlags)
|
public void setDebugFlags(String debugFlags)
|
||||||
|
@@ -19,7 +19,6 @@
|
|||||||
package org.alfresco.filesys.config;
|
package org.alfresco.filesys.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -83,6 +82,7 @@ import org.alfresco.jlan.util.MemorySize;
|
|||||||
import org.alfresco.jlan.util.Platform;
|
import org.alfresco.jlan.util.Platform;
|
||||||
import org.alfresco.jlan.util.StringList;
|
import org.alfresco.jlan.util.StringList;
|
||||||
import org.alfresco.jlan.util.X64;
|
import org.alfresco.jlan.util.X64;
|
||||||
|
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
|
||||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.extensions.config.element.GenericConfigElement;
|
import org.springframework.extensions.config.element.GenericConfigElement;
|
||||||
@@ -2324,31 +2324,12 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String clusterName = clusterConfigBean.getClusterName();
|
// Create a ClusterConfigSection and attach it to 'this'.
|
||||||
if (clusterName == null || clusterName.length() == 0)
|
ClusterConfigSection clusterConf = new ClusterConfigSection(this);
|
||||||
{
|
HazelcastInstanceFactory hazelcastInstanceFactory = clusterConfigBean.getHazelcastInstanceFactory();
|
||||||
throw new InvalidConfigurationException("Cluster name not specified or invalid");
|
// Clustering is enabled, so we can safely request the hazelcast instance.
|
||||||
}
|
HazelcastInstance hazelcast = hazelcastInstanceFactory.getInstance();
|
||||||
|
clusterConf.setHazelcastInstance(hazelcast);
|
||||||
String clusterFile = clusterConfigBean.getConfigFile();
|
|
||||||
if (clusterFile == null || clusterFile.length() == 0)
|
|
||||||
{
|
|
||||||
throw new InvalidConfigurationException("Cluster config file not specified or invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
// New Hazelcast instance created here within the ClusterConfigSection
|
|
||||||
ClusterConfigSection jlanClusterConfig = new ClusterConfigSection(this);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//TODO replace config XML file with Hazelcast config bean backed by spring.
|
|
||||||
jlanClusterConfig.setConfigFile(clusterFile);
|
|
||||||
HazelcastInstance hazelcastInstance = jlanClusterConfig.getHazelcastInstance();
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException e)
|
|
||||||
{
|
|
||||||
throw new InvalidConfigurationException("Unable to start filsystem cluster", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,34 +18,122 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.cluster;
|
package org.alfresco.repo.cluster;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
|
||||||
import com.hazelcast.config.Config;
|
import com.hazelcast.config.Config;
|
||||||
import com.hazelcast.core.Hazelcast;
|
import com.hazelcast.core.Hazelcast;
|
||||||
import com.hazelcast.core.HazelcastInstance;
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a way of lazily creating HazelcastInstances for a given configuration.
|
* Provides a way of lazily creating HazelcastInstances for a given configuration.
|
||||||
* The HazelcastInstance will not be created until {@link #newInstance()} is called.
|
* The HazelcastInstance will not be created until {@link #getInstance()} is called.
|
||||||
* <p>
|
* <p>
|
||||||
* An intermediary class such as this is required in order to avoid starting
|
* An intermediary class such as this is required in order to avoid starting
|
||||||
* Hazelcast instances when clustering is not configured/required. Otherwise
|
* Hazelcast instances when clustering is not configured/required. Otherwise
|
||||||
* simply by defining a HazelcastInstance bean clustering would spring into life.
|
* simply by defining a HazelcastInstance bean clustering would spring into life.
|
||||||
|
* <p>
|
||||||
|
* Please note this class provides non-static access deliberately, and should be
|
||||||
|
* injected into any clients that require its services.
|
||||||
*
|
*
|
||||||
* @author Matt Ward
|
* @author Matt Ward
|
||||||
*/
|
*/
|
||||||
public class HazelcastInstanceFactory
|
public class HazelcastInstanceFactory
|
||||||
{
|
{
|
||||||
public Config config;
|
private Config config;
|
||||||
|
private HazelcastInstance hazelcastInstance;
|
||||||
|
/** Guards {@link #config} and {@link #hazelcastInstance} */
|
||||||
|
private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
public HazelcastInstance newInstance()
|
public HazelcastInstance getInstance()
|
||||||
{
|
{
|
||||||
return Hazelcast.newHazelcastInstance(config);
|
rwLock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (hazelcastInstance != null)
|
||||||
|
{
|
||||||
|
return hazelcastInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
rwLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// hazelcastInstance is null, so create it.
|
||||||
|
rwLock.writeLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Double check condition hasn't changed in between locks.
|
||||||
|
if (hazelcastInstance == null)
|
||||||
|
{
|
||||||
|
hazelcastInstance = Hazelcast.newHazelcastInstance(config);
|
||||||
|
}
|
||||||
|
return hazelcastInstance;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
rwLock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param config the config to set
|
* Checks whether hazelcast has been given a valid cluster name. If so,
|
||||||
|
* then clustering is considered enabled. This condition should be checked
|
||||||
|
* before calling {@link #getInstance()}.
|
||||||
|
*
|
||||||
|
* @return true if clustering is enabled, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isClusteringEnabled()
|
||||||
|
{
|
||||||
|
rwLock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String clusterName = config.getGroupConfig().getName();
|
||||||
|
return (PropertyCheck.isValidPropertyString(clusterName));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
rwLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the name of the cluster for the configuration used by this factory.
|
||||||
|
*
|
||||||
|
* @return String - the cluster name.
|
||||||
|
*/
|
||||||
|
public String getClusterName()
|
||||||
|
{
|
||||||
|
rwLock.readLock().lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String clusterName = config.getGroupConfig().getName();
|
||||||
|
return clusterName;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
rwLock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Hazelcast configuration that will be used by this factory when
|
||||||
|
* creating the HazelcastInstance.
|
||||||
|
*
|
||||||
|
* @param config Hazelcast configuration
|
||||||
*/
|
*/
|
||||||
public void setConfig(Config config)
|
public void setConfig(Config config)
|
||||||
|
{
|
||||||
|
rwLock.writeLock().lock();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
rwLock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,5 +26,5 @@ package org.alfresco.repo.webdav;
|
|||||||
*/
|
*/
|
||||||
public interface LockStoreFactory
|
public interface LockStoreFactory
|
||||||
{
|
{
|
||||||
LockStore getLockStore();
|
LockStore createLockStore();
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,13 @@ import java.util.concurrent.ConcurrentMap;
|
|||||||
|
|
||||||
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
|
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.util.PropertyCheck;
|
|
||||||
|
|
||||||
import com.hazelcast.core.HazelcastInstance;
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link LockStoreFactory} interface. Creates {@link LockStore}s
|
* Default implementation of the {@link LockStoreFactory} interface. Creates {@link LockStore}s
|
||||||
* backed by a Hazelcast distributed Map if the clusterName property is set,
|
* backed by a Hazelcast distributed Map if clustering is enabled,
|
||||||
* otherwise it creates a non-clustered {@link SimpleLockStore}.
|
* otherwise it creates a non-clustered {@link SimpleLockStore}.
|
||||||
*
|
*
|
||||||
* @see LockStoreFactory
|
* @see LockStoreFactory
|
||||||
@@ -40,22 +39,21 @@ public class LockStoreFactoryImpl implements LockStoreFactory
|
|||||||
{
|
{
|
||||||
private static final String HAZELCAST_MAP_NAME = "webdav-locks";
|
private static final String HAZELCAST_MAP_NAME = "webdav-locks";
|
||||||
private HazelcastInstanceFactory hazelcastInstanceFactory;
|
private HazelcastInstanceFactory hazelcastInstanceFactory;
|
||||||
private String clusterName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should be used sparingly and the created {@link LockStore}s should be
|
* This method should be used sparingly and the created {@link LockStore}s should be
|
||||||
* retained (this factory does not cache instances of them).
|
* retained (this factory does not cache instances of them).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized LockStore getLockStore()
|
public synchronized LockStore createLockStore()
|
||||||
{
|
{
|
||||||
if (!PropertyCheck.isValidPropertyString(clusterName))
|
if (!hazelcastInstanceFactory.isClusteringEnabled())
|
||||||
{
|
{
|
||||||
return new SimpleLockStore();
|
return new SimpleLockStore();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HazelcastInstance instance = hazelcastInstanceFactory.newInstance();
|
HazelcastInstance instance = hazelcastInstanceFactory.getInstance();
|
||||||
ConcurrentMap<NodeRef, LockInfo> map = instance.getMap(HAZELCAST_MAP_NAME);
|
ConcurrentMap<NodeRef, LockInfo> map = instance.getMap(HAZELCAST_MAP_NAME);
|
||||||
return new LockStoreImpl(map);
|
return new LockStoreImpl(map);
|
||||||
}
|
}
|
||||||
@@ -68,12 +66,4 @@ public class LockStoreFactoryImpl implements LockStoreFactory
|
|||||||
{
|
{
|
||||||
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
|
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param clusterName the clusterName to set
|
|
||||||
*/
|
|
||||||
public synchronized void setClusterName(String clusterName)
|
|
||||||
{
|
|
||||||
this.clusterName = clusterName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user