Merged BRANCHES/DEV/mward/clustering_p1 to HEAD:

41454: ALF-15881: Disabling clustering in community
   41500: ALF-15883: Move configuration files
   41503: ALF-15884: Move cluster package to enterprise repository project
   41504: ALF-15884: Move cluster package to enterprise repository project
   41519: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41523: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41525: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41527: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41530: ALF-15886: remove import for class no longer in project.
   41532: ALF-15887: LockStoreFactoryImpl must be separated into community and enterprise versions
   41535: ALF-15883: Move configuration files
   41561: ALF-15886: factory class to create key fileserver config beans.
   41578: ALF-15888: separate transactional and shared cache bean definitions.
   41623: ALF-15888: first pass at DefaultSimpleCache implementation.
   41646: ALF-15888: move ehcache-default.xml
   41651: ALF-15888: update javadoc to reflect changes
   41762: ALF-15888: improve cache test to prove that null values are stored correctly.
   41812: ALF-15888: added new cache provider for use by hibernate: DefaultCacheProvider.
   41830: ALF-15888: make DefaultSimpleCache BeanNameAware to help with debugging etc.
   41831: ALF-15888: missing file from commit - adds enterprise override capability for hibernate-cfg.properties
   41850: ALF-15888: move tickets cache to cache-context.xml
   41857: ALF-15888: make RemoteAlfrescoTicketServiceImpl cache implementation agnostic.
   41866: ALF-15888: extract caches from fileservers and web-client and provide enterprise overrides
   41881: ALF-15888: replace use of EhCacheAdapter with DefaultSimpleCache and SimpleCache interface.
   41884: ALF-15888: added DefaultSimpleCache configuration to CachingContentStore sample XML.
   41885: ALF-15888: move EhCacheAdapter to new package.
   41886: ALF-15888: correct absolute class names in config for EhCacheAdapter.
   41892: ALF-15888: fix CachingContentStore tests.
   41897: ALF-15888: move CacheTest and config to new package.
   41898: ALF-15888: remove redundant directory
   41899: ALF-15889: move EhCacheManagerFactoryBean to new package.
   41902: ALF-15889: moved EhCacheTracerJob to new package.
   41913: ALF-15889: move InternalEhCacheManagerFactoryBean to new package.
   41916: ALF-15889: move AlfrescoCacheManagerPeerProviderFactory to new package.
   41937: ALF-15889: decouple TransactionalCache from EhCache
   41966: ALF-15889: decouple RetryingTransactionHelper from ehcache.
   41989: ALF-15889: added ContextListener test.
   41996: ALF-15889: moved cache test to its own class.
   41998: ALF-15889: move ehcache jars.
   41999: ALF-15889: modify .classpath to reflect jar moves.
   42037: ALF-15889: update poms to reflect lib moves.
   42038: ALF-15889: add eclipse library reference to enterprise projects.
   42093: ALF-15916: moved core properties to enterprise
   42114: ALF-15888: externalized cache sizes to repository.properties.
   42127: ALF-16136: move re-indexing configuration
   42140: ALF-16136: move cluster check property.
   42186: ALF-15889: removing seemingly redundant test config file.
   42187: ALF-15888: tidy up config changes.
   42189: ALF-15888: cleanup config
   42190: ALF-15888: config cleanup
   42191: ALF-15888: config cleanup
   42198: ALF-16136: restored lost property



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42210 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Matt Ward
2012-10-01 12:17:53 +00:00
parent 131080b564
commit 511af90d5c
79 changed files with 1471 additions and 7954 deletions

View File

@@ -4,6 +4,7 @@
<!-- These are the XML files of the "core" of the context -->
<!-- This includes bootstrap-context.xml, so subsystems are "core" too -->
<beans>
<import resource="classpath:alfresco/tx-cache-context.xml" />
<import resource="classpath:alfresco/cache-context.xml" />
<import resource="classpath:alfresco/st-context.xml"/>
<import resource="classpath*:alfresco/extension/mt/mt-context.xml"/>
@@ -43,7 +44,6 @@
<import resource="classpath:alfresco/activities/activities-feed-context.xml" />
<import resource="classpath:alfresco/tagging-services-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/patch/*-context.xml" />
</beans>

View File

@@ -177,23 +177,6 @@
</property>
</bean>
<bean id="messengerFactory" class="org.alfresco.repo.cluster.HazelcastMessengerFactory">
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
</bean>
<!-- Set up this class for static access, don't use this for DI - use messengerFactory instead -->
<bean id="staticMessengerFactoryProvider" class="org.alfresco.repo.cluster.MessengerFactoryProvider">
<property name="instance" ref="messengerFactory"/>
</bean>
<bean id="clusterChecker" class="org.alfresco.repo.cluster.ClusterChecker" init-method="init" destroy-method="shutdown">
<property name="authenticationService" ref="authenticationService"/>
<property name="jobLockService" ref="jobLockService"/>
<property name="transactionService" ref="transactionService"/>
<property name="messengerFactory" ref="messengerFactory"/>
<property name="timeout" value="${alfresco.clusterCheck.timeout}"/>
</bean>
<bean id="encryptionChecker" class="org.alfresco.encryption.EncryptionChecker">
<property name="transactionService" ref="transactionService"/>
<property name="keyStoreChecker" ref="keyStoreChecker"/>
@@ -831,6 +814,8 @@
</property>
</bean>
<bean id="fileServerConfigurationFactory" class="org.alfresco.filesys.config.FileServerConfigurationFactory"/>
<!-- Startup Message -->
<bean id="startupLog" class="org.alfresco.repo.descriptor.DescriptorStartupLog">

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
<?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>
<!-- Common options -->
<prop key="alfresco.cluster.name">${alfresco.cluster.name}</prop>
<prop key="alfresco.hazelcast.password">${alfresco.hazelcast.password}</prop>
<prop key="alfresco.hazelcast.specify.interface">${alfresco.hazelcast.specify.interface}</prop>
<prop key="alfresco.hazelcast.bind.interface">${alfresco.hazelcast.bind.interface}</prop>
<!-- TCP/IP discovery options -->
<prop key="alfresco.hazelcast.tcp.config">${alfresco.hazelcast.tcp.config}</prop>
<!-- AWS discovery options -->
<prop key="alfresco.hazelcast.ec2.accesskey">${alfresco.hazelcast.ec2.accesskey}</prop>
<prop key="alfresco.hazelcast.ec2.secretkey">${alfresco.hazelcast.ec2.secretkey}</prop>
<prop key="alfresco.hazelcast.ec2.region">${alfresco.hazelcast.ec2.region}</prop>
<prop key="alfresco.hazelcast.ec2.securitygroup">${alfresco.hazelcast.ec2.securitygroup}</prop>
<prop key="alfresco.hazelcast.ec2.tagkey">${alfresco.hazelcast.ec2.tagkey}</prop>
<prop key="alfresco.hazelcast.ec2.tagvalue">${alfresco.hazelcast.ec2.tagvalue}</prop>
</props>
</property>
</bean>
<bean id="hazelcastInstanceFactory" class="org.alfresco.repo.cluster.HazelcastInstanceFactory">
<property name="config" ref="hazelcastConfig"/>
</bean>
</beans>

View File

@@ -127,43 +127,6 @@
</property>
</bean>
<bean id="clusterPropertySetter" class="org.alfresco.config.SystemPropertiesSetterBean" init-method="init">
<property name="propertyMap">
<map>
<entry key="alfresco.ehcache.rmi.hostname">
<value>${alfresco.ehcache.rmi.hostname}</value>
</entry>
<entry key="alfresco.ehcache.rmi.remoteObjectPort">
<value>${alfresco.ehcache.rmi.remoteObjectPort}</value>
</entry>
<entry key="alfresco.ehcache.rmi.port">
<value>${alfresco.ehcache.rmi.port}</value>
</entry>
<entry key="alfresco.ehcache.rmi.socketTimeoutMillis">
<value>${alfresco.ehcache.rmi.socketTimeoutMillis}</value>
</entry>
<entry key="alfresco.tcp.start_port">
<value>${alfresco.tcp.start_port}</value>
</entry>
<entry key="alfresco.tcp.initial_hosts">
<value>${alfresco.tcp.initial_hosts}</value>
</entry>
<entry key="alfresco.tcp.port_range">
<value>${alfresco.tcp.port_range}</value>
</entry>
<entry key="alfresco.udp.mcast_addr">
<value>${alfresco.udp.mcast_addr}</value>
</entry>
<entry key="alfresco.udp.mcast_port">
<value>${alfresco.udp.mcast_port}</value>
</entry>
<entry key="alfresco.fping.shared.dir">
<value>${alfresco.fping.shared.dir}</value>
</entry>
</map>
</property>
</bean>
<!-- Custom MBeanServer -->
<bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="${mbean.server.locateExistingServerIfPossible}" />

View File

@@ -11,7 +11,7 @@ hibernate.jdbc.use_streams_for_binary=true
hibernate.show_sql=false
hibernate.cache.use_query_cache=false
hibernate.max_fetch_depth=10
hibernate.cache.provider_class=org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean
hibernate.cache.provider_class=org.alfresco.repo.cache.DefaultCacheProvider
hibernate.cache.use_second_level_cache=true
hibernate.default_batch_fetch_size=1
hibernate.jdbc.batch_size=32

View File

@@ -1,413 +0,0 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!-- Schema http://ehcache.org/ehcache.xsd -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ehcache.org/ehcache.xsd" >
<!-- defaults -->
<diskStore
path="java.io.tmpdir"
/>
<defaultCache
maxElementsInMemory="5000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
</defaultCache>
<!-- Hibernate usage -->
<cache
name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="50"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- approx 0.4MB memory required -->
<cache
name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Node caches -->
<cache
name="org.alfresco.cache.node.rootNodesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.node.allRootNodesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.node.nodesCache"
maxElementsInMemory="250000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.node.aspectsCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.node.propertiesCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.node.childByNameCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- AVM caches -->
<cache
name="org.alfresco.cache.avm.avmEntityCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.avm.avmVersionRootEntityCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.avm.avmNodeCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.avm.avmStoreCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.avm.avmNodeAspectsCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Internally used caches -->
<cache
name="org.alfresco.repo.webservices.querySessionSharedCache"
maxElementsInMemory="1000"
eternal="false"
timeToLiveSeconds="300"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.propertyValueCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.contentDataCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.immutableEntityCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.userToAuthorityCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.authorityToChildAuthorityCache"
maxElementsInMemory="40000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.zoneToAuthorityCache"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.authenticationCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.authorityCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.permissionsAccessCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.readersCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
/>
<cache
name="org.alfresco.cache.readersDeniedCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
/>
<cache
name="org.alfresco.cache.nodeOwnerCache"
maxElementsInMemory="40000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.personCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.ticketsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="true"
statistics="false"
/>
<!-- ACL caches -->
<cache
name="org.alfresco.cache.aclCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.permissions.aclEntityCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.permissions.authorityEntityCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.permissions.permissionEntityCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Web Client Config (tenant-based) -->
<cache
name="org.alfresco.cache.globalConfigCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Messages I18N (tenant-based) -->
<cache
name="org.alfresco.cache.resourceBundleBaseNamesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.loadedResourceBundlesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="org.alfresco.cache.messagesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Dictionary / Namespace (tenant-based) -->
<!-- dictionary models -->
<cache
name="org.alfresco.cache.compiledModelsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- dictionary namespaces -->
<cache
name="org.alfresco.cache.prefixesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Tenants Cache -->
<cache
name="org.alfresco.cache.tenantEntityCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Tenant-based Routing File Content Store -->
<cache
name="org.alfresco.cache.tenantFileStoresCache"
maxElementsInMemory="100"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Web Scripts Registry (tenant-based) -->
<cache
name="org.alfresco.cache.webScriptsRegistryCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Routing Content Store -->
<cache
name="org.alfresco.cache.routingContentStoreCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Executing Actions -->
<cache
name="org.alfresco.cache.executingActionsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Tagscope Summary Properties -->
<cache
name="org.alfresco.cache.tagscopeSummaryCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- Imap Messages -->
<cache
name="org.alfresco.cache.imapMessageCache"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<!-- CIFS Filesystem path to fileInfo -->
<cache
name="org.alfresco.cache.filesys.fileInfo"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
timeToLiveSeconds="60"
/>
<!-- Immutable (tenant-aware) Singletons -->
<cache
name="org.alfresco.cache.immutableSingletonCache"
maxElementsInMemory="12000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
</ehcache>

View File

@@ -62,25 +62,7 @@
<bean id="unlimitedQuotaManager" class="org.alfresco.repo.content.caching.quota.UnlimitedQuotaStrategy"/>
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.cachingContentStoreCache</value>
</property>
<property name="eternal" value="false"/>
<property name="timeToLive" value="${system.content.caching.timeToLiveSeconds}"/>
<property name="timeToIdle" value="${system.content.caching.timeToIdleSeconds}"/>
<property name="maxElementsInMemory" value="${system.content.caching.maxElementsInMemory}"/>
<property name="maxElementsOnDisk" value="${system.content.caching.maxElementsOnDisk}"/>
<property name="overflowToDisk" value="true"/>
<property name="diskPersistent" value="true"/>
</bean>
</property>
</bean>
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.DefaultSimpleCache"/>
<bean id="cachingContentStoreCleanerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">

View File

@@ -1,771 +0,0 @@
<ehcache>
<diskStore
path="java.io.tmpdir"/>
<!--
The 'heartbeatInterval' property is the only one used for the Hazelcast-enabled implementation
-->
<cacheManagerPeerProviderFactory
class="org.alfresco.repo.cache.AlfrescoCacheManagerPeerProviderFactory"
properties="heartbeatInterval=5000,
peerDiscovery=automatic,
multicastGroupAddress=230.0.0.1,
multicastGroupPort=4446"
/>
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="socketTimeoutMillis=10000"
/>
<!--
To control the cache peer URLs, replace the 'cacheManagerPeerListenerFactory' with the following
and set the properties statically, in alfresco-global.properties or via java -D options.
Only the hostName needs to be set as the others have sensible defaults.
-->
<!--
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=${alfresco.ehcache.rmi.hostname},
port=${alfresco.ehcache.rmi.port},
remoteObjectPort=${alfresco.ehcache.rmi.remoteObjectPort},
socketTimeoutMillis=${alfresco.ehcache.rmi.socketTimeoutMillis}"
/>
-->
<defaultCache
maxElementsInMemory="5000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</defaultCache>
<cache
name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="50"
eternal="true"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.node.rootNodesCache"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.node.allRootNodesCache"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.node.nodesCache"
maxElementsInMemory="250000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.node.aspectsCache"
maxElementsInMemory="130000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<!-- We are intentionally not replicating this secondary cache and validating in the code -->
</cache>
<cache
name="org.alfresco.cache.node.propertiesCache"
maxElementsInMemory="130000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
<!-- We are intentionally not replicating this secondary cache and validating in the code -->
</cache>
<cache
name="org.alfresco.cache.node.childByNameCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<!-- Not clustered -->
</cache>
<cache
name="org.alfresco.cache.avm.avmEntityCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.avm.avmVersionRootEntityCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.avm.avmNodeCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.avm.avmStoreCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.avm.avmNodeAspectsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.repo.webservices.querySessionSharedCache"
maxElementsInMemory="1000"
eternal="false"
timeToLiveSeconds="300"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = true,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = true,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.propertyValueCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.contentDataCache"
maxElementsInMemory="130000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.immutableEntityCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.userToAuthorityCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.authorityToChildAuthorityCache"
maxElementsInMemory="40000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.zoneToAuthorityCache"
maxElementsInMemory="500"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.authenticationCache"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.authorityCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.permissionsAccessCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.readersCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.nodeOwnerCache"
maxElementsInMemory="40000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.personCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.ticketsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="true"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = true,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = true,
replicateAsynchronously = false"/>
</cache>
<!-- ACL caches -->
<cache
name="org.alfresco.cache.aclCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.permissions.aclEntityCache"
maxElementsInMemory="50000"
eternal="true"
overflowToDisk="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Web Client Config (tenant-based) -->
<cache
name="org.alfresco.cache.globalConfigCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Messages I18N (tenant-based) -->
<cache
name="org.alfresco.cache.resourceBundleBaseNamesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.loadedResourceBundlesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.messagesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Dictionary / Namespace (tenant-based) -->
<cache
name="org.alfresco.cache.compiledModelsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<cache
name="org.alfresco.cache.prefixesCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Tenants Cache -->
<cache
name="org.alfresco.cache.tenantsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Web Scripts Registry -->
<cache
name="org.alfresco.cache.webScriptsRegistryCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = false,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Routing Content Store -->
<cache
name="org.alfresco.cache.routingContentStoreCache"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Executing Actions -->
<cache
name="org.alfresco.cache.executingActionsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = true,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = true,
replicateAsynchronously = false"/>
</cache>
<!-- Tagscope Summary Properties -->
<cache
name="org.alfresco.cache.tagscopeSummaryCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = false,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = false,
replicateAsynchronously = false"/>
</cache>
<!-- Imap Messages -->
<cache
name="org.alfresco.cache.imapMessageCache"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="false"
statistics="false"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts = true,
replicateUpdates = true,
replicateRemovals = true,
replicateUpdatesViaCopy = true,
replicateAsynchronously = false"/>
</cache>
</ehcache>

View File

@@ -1,169 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<name>${alfresco.cluster.name}</name>
<password>${alfresco.hazelcast.password}</password>
</group>
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="false">
<interface>127.0.0.1</interface>
</tcp-ip>
<aws enabled="true">
<access-key>${alfresco.hazelcast.ec2.accesskey}</access-key>
<secret-key>${alfresco.hazelcast.ec2.secretkey}</secret-key>
<!--optional, default is us-east-1 -->
<region>${alfresco.hazelcast.ec2.region}</region>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-name>${alfresco.hazelcast.ec2.securitygroup}</security-group-name>
<tag-key>${alfresco.hazelcast.ec2.tagkey}</tag-key>
<tag-value>${alfresco.hazelcast.ec2.tagvalue}</tag-value>
</aws>
</join>
<interfaces enabled="${alfresco.hazelcast.specify.interface}">
<interface>${alfresco.hazelcast.bind.interface}</interface>
</interfaces>
<symmetric-encryption enabled="false">
<!--
encryption algorithm such as
DES/ECB/PKCS5Padding,
PBEWithMD5AndDES,
AES/CBC/PKCS5Padding,
Blowfish,
DESede
-->
<algorithm>PBEWithMD5AndDES</algorithm>
<!-- salt value to use when generating the secret key -->
<salt>thesalt</salt>
<!-- pass phrase to use when generating the secret key -->
<password>thepass</password>
<!-- iteration count to use when generating the secret key -->
<iteration-count>19</iteration-count>
</symmetric-encryption>
<asymmetric-encryption enabled="false">
<!-- encryption algorithm -->
<algorithm>RSA/NONE/PKCS1PADDING</algorithm>
<!-- private key password -->
<keyPassword>thekeypass</keyPassword>
<!-- private key alias -->
<keyAlias>local</keyAlias>
<!-- key store type -->
<storeType>JKS</storeType>
<!-- key store password -->
<storePassword>thestorepass</storePassword>
<!-- path to the key store -->
<storePath>keystore</storePath>
</asymmetric-encryption>
</network>
<executor-service>
<core-pool-size>16</core-pool-size>
<max-pool-size>64</max-pool-size>
<keep-alive-seconds>60</keep-alive-seconds>
</executor-service>
<queue name="default">
<!--
Maximum size of the queue. When a JVM's local queue size reaches the maximum,
all put/offer operations will get blocked until the queue size
of the JVM goes down below the maximum.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size-per-jvm>0</max-size-per-jvm>
<!--
Name of the map configuration that will be used for the backing distributed
map for this queue.
-->
<backing-map-ref>default</backing-map-ref>
</queue>
<map name="default">
<!--
Number of backups. If 1 is set as the backup-count for example,
then all entries of the map will be copied to another JVM for
fail-safety. 0 means no backup.
-->
<backup-count>1</backup-count>
<!--
Maximum number of seconds for each entry to stay in the map. Entries that are
older than <time-to-live-seconds> and not updated for <time-to-live-seconds>
will get automatically evicted from the map.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<time-to-live-seconds>0</time-to-live-seconds>
<!--
Maximum number of seconds for each entry to stay idle in the map. Entries that are
idle(not touched) for more than <max-idle-seconds> will get
automatically evicted from the map. Entry is touched if get, put or containsKey is called.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<max-idle-seconds>0</max-idle-seconds>
<!--
Valid values are:
NONE (no eviction),
LRU (Least Recently Used),
LFU (Least Frequently Used).
NONE is the default.
-->
<eviction-policy>NONE</eviction-policy>
<!--
Maximum size of the map. When max size is reached,
map is evicted based on the policy defined.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size policy="cluster_wide_map_size">0</max-size>
<!--
When max. size is reached, specified percentage of
the map will be evicted. Any integer between 0 and 100.
If 25 is set for example, 25% of the entries will
get evicted.
-->
<eviction-percentage>25</eviction-percentage>
<!--
While recovering from split-brain (network partitioning),
map entries in the small cluster will merge into the bigger cluster
based on the policy set here. When an entry merge into the
cluster, there might an existing entry with the same key already.
Values of these entries might be different for that same key.
Which value should be set for the key? Conflict is resolved by
the policy set here. Default policy is hz.ADD_NEW_ENTRY
There are built-in merge policies such as
hz.NO_MERGE ; no entry will merge.
hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
doesn't exist in the cluster.
hz.HIGHER_HITS ; entry with the higher hits wins.
hz.LATEST_UPDATE ; entry with the latest update wins.
-->
<merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
</map>
<!-- Add your own semaphore configurations here:
<semaphore name="default">
<initial-permits>10</initial-permits>
<semaphore-factory enabled="true">
<class-name>com.acme.MySemaphoreFactory</class-name>
</semaphore-factory>
</semaphore>
-->
<!-- Add your own map merge policy implementations here:
<merge-policies>
<map-merge-policy name="MY_MERGE_POLICY">
<class-name>com.acme.MyOwnMergePolicy</class-name>
</map-merge-policy>
</merge-policies>
-->
<properties>
<property name="hazelcast.logging.type">log4j</property>
<property name="hazelcast.mancenter.enabled">false</property>
<property name="hazelcast.rest.enabled">false</property>
<property name="hazelcast.memcache.enabled">false</property>
</properties>
</hazelcast>

View File

@@ -1,169 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<name>${alfresco.cluster.name}</name>
<password>${alfresco.hazelcast.password}</password>
</group>
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="true">
${alfresco.hazelcast.tcp.config}
</tcp-ip>
<aws enabled="false">
<access-key>my-access-key</access-key>
<secret-key>my-secret-key</secret-key>
<!--optional, default is us-east-1 -->
<region>us-west-1</region>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-name>hazelcast-sg</security-group-name>
<tag-key>type</tag-key>
<tag-value>hz-nodes</tag-value>
</aws>
</join>
<interfaces enabled="${alfresco.hazelcast.specify.interface}">
<interface>${alfresco.hazelcast.bind.interface}</interface>
</interfaces>
<symmetric-encryption enabled="false">
<!--
encryption algorithm such as
DES/ECB/PKCS5Padding,
PBEWithMD5AndDES,
AES/CBC/PKCS5Padding,
Blowfish,
DESede
-->
<algorithm>PBEWithMD5AndDES</algorithm>
<!-- salt value to use when generating the secret key -->
<salt>thesalt</salt>
<!-- pass phrase to use when generating the secret key -->
<password>thepass</password>
<!-- iteration count to use when generating the secret key -->
<iteration-count>19</iteration-count>
</symmetric-encryption>
<asymmetric-encryption enabled="false">
<!-- encryption algorithm -->
<algorithm>RSA/NONE/PKCS1PADDING</algorithm>
<!-- private key password -->
<keyPassword>thekeypass</keyPassword>
<!-- private key alias -->
<keyAlias>local</keyAlias>
<!-- key store type -->
<storeType>JKS</storeType>
<!-- key store password -->
<storePassword>thestorepass</storePassword>
<!-- path to the key store -->
<storePath>keystore</storePath>
</asymmetric-encryption>
</network>
<executor-service>
<core-pool-size>16</core-pool-size>
<max-pool-size>64</max-pool-size>
<keep-alive-seconds>60</keep-alive-seconds>
</executor-service>
<queue name="default">
<!--
Maximum size of the queue. When a JVM's local queue size reaches the maximum,
all put/offer operations will get blocked until the queue size
of the JVM goes down below the maximum.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size-per-jvm>0</max-size-per-jvm>
<!--
Name of the map configuration that will be used for the backing distributed
map for this queue.
-->
<backing-map-ref>default</backing-map-ref>
</queue>
<map name="default">
<!--
Number of backups. If 1 is set as the backup-count for example,
then all entries of the map will be copied to another JVM for
fail-safety. 0 means no backup.
-->
<backup-count>1</backup-count>
<!--
Maximum number of seconds for each entry to stay in the map. Entries that are
older than <time-to-live-seconds> and not updated for <time-to-live-seconds>
will get automatically evicted from the map.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<time-to-live-seconds>0</time-to-live-seconds>
<!--
Maximum number of seconds for each entry to stay idle in the map. Entries that are
idle(not touched) for more than <max-idle-seconds> will get
automatically evicted from the map. Entry is touched if get, put or containsKey is called.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<max-idle-seconds>0</max-idle-seconds>
<!--
Valid values are:
NONE (no eviction),
LRU (Least Recently Used),
LFU (Least Frequently Used).
NONE is the default.
-->
<eviction-policy>NONE</eviction-policy>
<!--
Maximum size of the map. When max size is reached,
map is evicted based on the policy defined.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size policy="cluster_wide_map_size">0</max-size>
<!--
When max. size is reached, specified percentage of
the map will be evicted. Any integer between 0 and 100.
If 25 is set for example, 25% of the entries will
get evicted.
-->
<eviction-percentage>25</eviction-percentage>
<!--
While recovering from split-brain (network partitioning),
map entries in the small cluster will merge into the bigger cluster
based on the policy set here. When an entry merge into the
cluster, there might an existing entry with the same key already.
Values of these entries might be different for that same key.
Which value should be set for the key? Conflict is resolved by
the policy set here. Default policy is hz.ADD_NEW_ENTRY
There are built-in merge policies such as
hz.NO_MERGE ; no entry will merge.
hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
doesn't exist in the cluster.
hz.HIGHER_HITS ; entry with the higher hits wins.
hz.LATEST_UPDATE ; entry with the latest update wins.
-->
<merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
</map>
<!-- Add your own semaphore configurations here:
<semaphore name="default">
<initial-permits>10</initial-permits>
<semaphore-factory enabled="true">
<class-name>com.acme.MySemaphoreFactory</class-name>
</semaphore-factory>
</semaphore>
-->
<!-- Add your own map merge policy implementations here:
<merge-policies>
<map-merge-policy name="MY_MERGE_POLICY">
<class-name>com.acme.MyOwnMergePolicy</class-name>
</map-merge-policy>
</merge-policies>
-->
<properties>
<property name="hazelcast.logging.type">log4j</property>
<property name="hazelcast.mancenter.enabled">false</property>
<property name="hazelcast.rest.enabled">false</property>
<property name="hazelcast.memcache.enabled">false</property>
</properties>
</hazelcast>

View File

@@ -1,169 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<name>${alfresco.cluster.name}</name>
<password>${alfresco.hazelcast.password}</password>
</group>
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="false">
<interface>127.0.0.1</interface>
</tcp-ip>
<aws enabled="false">
<access-key>my-access-key</access-key>
<secret-key>my-secret-key</secret-key>
<!--optional, default is us-east-1 -->
<region>us-west-1</region>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-name>hazelcast-sg</security-group-name>
<tag-key>type</tag-key>
<tag-value>hz-nodes</tag-value>
</aws>
</join>
<interfaces enabled="${alfresco.hazelcast.specify.interface}">
<interface>${alfresco.hazelcast.bind.interface}</interface>
</interfaces>
<symmetric-encryption enabled="false">
<!--
encryption algorithm such as
DES/ECB/PKCS5Padding,
PBEWithMD5AndDES,
AES/CBC/PKCS5Padding,
Blowfish,
DESede
-->
<algorithm>PBEWithMD5AndDES</algorithm>
<!-- salt value to use when generating the secret key -->
<salt>thesalt</salt>
<!-- pass phrase to use when generating the secret key -->
<password>thepass</password>
<!-- iteration count to use when generating the secret key -->
<iteration-count>19</iteration-count>
</symmetric-encryption>
<asymmetric-encryption enabled="false">
<!-- encryption algorithm -->
<algorithm>RSA/NONE/PKCS1PADDING</algorithm>
<!-- private key password -->
<keyPassword>thekeypass</keyPassword>
<!-- private key alias -->
<keyAlias>local</keyAlias>
<!-- key store type -->
<storeType>JKS</storeType>
<!-- key store password -->
<storePassword>thestorepass</storePassword>
<!-- path to the key store -->
<storePath>keystore</storePath>
</asymmetric-encryption>
</network>
<executor-service>
<core-pool-size>16</core-pool-size>
<max-pool-size>64</max-pool-size>
<keep-alive-seconds>60</keep-alive-seconds>
</executor-service>
<queue name="default">
<!--
Maximum size of the queue. When a JVM's local queue size reaches the maximum,
all put/offer operations will get blocked until the queue size
of the JVM goes down below the maximum.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size-per-jvm>0</max-size-per-jvm>
<!--
Name of the map configuration that will be used for the backing distributed
map for this queue.
-->
<backing-map-ref>default</backing-map-ref>
</queue>
<map name="default">
<!--
Number of backups. If 1 is set as the backup-count for example,
then all entries of the map will be copied to another JVM for
fail-safety. 0 means no backup.
-->
<backup-count>1</backup-count>
<!--
Maximum number of seconds for each entry to stay in the map. Entries that are
older than <time-to-live-seconds> and not updated for <time-to-live-seconds>
will get automatically evicted from the map.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<time-to-live-seconds>0</time-to-live-seconds>
<!--
Maximum number of seconds for each entry to stay idle in the map. Entries that are
idle(not touched) for more than <max-idle-seconds> will get
automatically evicted from the map. Entry is touched if get, put or containsKey is called.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<max-idle-seconds>0</max-idle-seconds>
<!--
Valid values are:
NONE (no eviction),
LRU (Least Recently Used),
LFU (Least Frequently Used).
NONE is the default.
-->
<eviction-policy>NONE</eviction-policy>
<!--
Maximum size of the map. When max size is reached,
map is evicted based on the policy defined.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size policy="cluster_wide_map_size">0</max-size>
<!--
When max. size is reached, specified percentage of
the map will be evicted. Any integer between 0 and 100.
If 25 is set for example, 25% of the entries will
get evicted.
-->
<eviction-percentage>25</eviction-percentage>
<!--
While recovering from split-brain (network partitioning),
map entries in the small cluster will merge into the bigger cluster
based on the policy set here. When an entry merge into the
cluster, there might an existing entry with the same key already.
Values of these entries might be different for that same key.
Which value should be set for the key? Conflict is resolved by
the policy set here. Default policy is hz.ADD_NEW_ENTRY
There are built-in merge policies such as
hz.NO_MERGE ; no entry will merge.
hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
doesn't exist in the cluster.
hz.HIGHER_HITS ; entry with the higher hits wins.
hz.LATEST_UPDATE ; entry with the latest update wins.
-->
<merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
</map>
<!-- Add your own semaphore configurations here:
<semaphore name="default">
<initial-permits>10</initial-permits>
<semaphore-factory enabled="true">
<class-name>com.acme.MySemaphoreFactory</class-name>
</semaphore-factory>
</semaphore>
-->
<!-- Add your own map merge policy implementations here:
<merge-policies>
<map-merge-policy name="MY_MERGE_POLICY">
<class-name>com.acme.MyOwnMergePolicy</class-name>
</map-merge-policy>
</merge-policies>
-->
<properties>
<property name="hazelcast.logging.type">log4j</property>
<property name="hazelcast.mancenter.enabled">false</property>
<property name="hazelcast.rest.enabled">false</property>
<property name="hazelcast.memcache.enabled">false</property>
</properties>
</hazelcast>

View File

@@ -9,6 +9,7 @@
<property name="locations">
<list>
<value>classpath:alfresco/domain/hibernate-cfg.properties</value>
<value>classpath*:alfresco/enterprise/cache/hibernate-cfg.properties</value>
</list>
</property>
<!-- Allow global properties to override default settings -->

View File

@@ -86,20 +86,4 @@
<property name="remoteConnectorService" ref="RemoteConnectorService" />
<property name="ticketsCache" ref="remoteAlfrescoTicketService.ticketsCache" />
</bean>
<!-- Remote Alfresco Ticket Cache, cross-transaction shared cache -->
<bean name="remoteAlfrescoTicketService.ticketsCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.remote.auth.ticketCache</value>
</property>
</bean>
</property>
</bean>
</beans>

View File

@@ -121,46 +121,6 @@ index.reindexMissingContent.cronExpression=* * * * * ? 2099
# Change the failure behaviour of the configuration checker
system.bootstrap.config_check.strict=true
# The name of the cluster
# Leave this empty to disable cluster entry
alfresco.cluster.name=
# Time to wait for a cluster node ping before marking the node as not alive (ms)
alfresco.clusterCheck.timeout=4000
# Hazelcast clustering configuration
# Password to join the cluster
alfresco.hazelcast.password=alfrescocluster
# Protocol used for member discovery (tcp, ec2, udp)
alfresco.hazelcast.protocol=tcp
# Location of the Hazelcast configuration file
alfresco.hazelcast.configLocation=classpath:alfresco/hazelcast/hazelcast-${alfresco.hazelcast.protocol}.xml
# XML elements to incorporate into Hazelcast config, in particular
# hostnames/IP addresses to use for membership discovery
alfresco.hazelcast.tcp.config=<members></members>
# Whether to bind to a specific host interface
alfresco.hazelcast.specify.interface=false
# The interface to bind to, if enabled above.
alfresco.hazelcast.bind.interface=
# Amazon Web Services - EC2 discovery
alfresco.hazelcast.ec2.accesskey=my-access-key
alfresco.hazelcast.ec2.secretkey=my-secret-key
alfresco.hazelcast.ec2.region=us-east-1
# Only instances belonging to this group will be discovered, default will try all running instances
alfresco.hazelcast.ec2.securitygroup=
alfresco.hazelcast.ec2.tagkey=type
alfresco.hazelcast.ec2.tagvalue=hz-nodes
# The EHCache RMI peer URL addresses to set in the ehcache-custom.xml file
# Use this property to set the hostname of the current server.
# This is only necessary if the cache peer URLs are generated with an invalid IP address for the local server.
alfresco.ehcache.rmi.hostname=
# Use this property to set the cache peer URL port.
alfresco.ehcache.rmi.remoteObjectPort=0
alfresco.ehcache.rmi.port=0
alfresco.ehcache.rmi.socketTimeoutMillis=5000
#
# How long should shutdown wait to complete normally before
# taking stronger action and calling System.exit()
@@ -998,10 +958,6 @@ system.content.caching.cacheOnInbound=true
system.content.caching.maxDeleteWatchCount=1
# Clean up every day at 3 am
system.content.caching.contentCleanup.cronExpression=0 0 3 * * ?
system.content.caching.timeToLiveSeconds=0
system.content.caching.timeToIdleSeconds=86400
system.content.caching.maxElementsInMemory=5000
system.content.caching.maxElementsOnDisk=10000
system.content.caching.minFileAgeMillis=60000
system.content.caching.maxUsageMB=4096
# maxFileSizeMB - 0 means no max file size.
@@ -1029,7 +985,55 @@ download.cleaner.maxAgeMins=60
# enable QuickShare - if false then the QuickShare-specific REST APIs will return 403 Forbidden
system.quickshare.enabled=true
#
# Cache configuration
#
cache.propertyValueCache.maxItems=10000
cache.contentDataSharedCache.maxItems=130000
cache.immutableEntitySharedCache.maxItems=50000
cache.node.rootNodesSharedCache.maxItems=1000
cache.node.allRootNodesSharedCache.maxItems=1000
cache.node.nodesSharedCache.maxItems=250000
cache.node.aspectsSharedCache.maxItems=130000
cache.node.propertiesSharedCache.maxItems=130000
cache.node.parentAssocsSharedCache.maxItems=130000
cache.node.childByNameSharedCache.maxItems=130000
cache.userToAuthoritySharedCache.maxItems=5000
cache.authenticationSharedCache.maxItems=5000
cache.authoritySharedCache.maxItems=10000
cache.authorityToChildAuthoritySharedCache.maxItems=40000
cache.zoneToAuthoritySharedCache.maxItems=500
cache.permissionsAccessSharedCache.maxItems=50000
cache.readersSharedCache.maxItems=10000
cache.readersDeniedSharedCache.maxItems=10000
cache.nodeOwnerSharedCache.maxItems=40000
cache.personSharedCache.maxItems=1000
cache.ticketsCache.maxItems=1000
cache.avmEntitySharedCache.maxItems=5000
cache.avmVersionRootEntitySharedCache.maxItems=1000
cache.avmNodeSharedCache.maxItems=5000
cache.avmNodeAspectsSharedCache.maxItems=5000
cache.webServicesQuerySessionSharedCache.maxItems=1000
cache.aclSharedCache.maxItems=50000
cache.aclEntitySharedCache.maxItems=50000
cache.resourceBundleBaseNamesSharedCache.maxItems=1000
cache.loadedResourceBundlesSharedCache.maxItems=1000
cache.messagesSharedCache.maxItems=1000
cache.compiledModelsSharedCache.maxItems=1000
cache.prefixesSharedCache.maxItems=1000
cache.webScriptsRegistrySharedCache.maxItems=1000
cache.routingContentStoreSharedCache.maxItems=10000
cache.executingActionsCache.maxItems=1000
cache.tagscopeSummarySharedCache.maxItems=1000
cache.imapMessageSharedCache.maxItems=2000
cache.tenantEntitySharedCache.maxItems=1000
cache.immutableSingletonSharedCache.maxItems=12000
cache.remoteAlfrescoTicketService.ticketsCache.maxItems=1000
cache.contentDiskDriver.fileInfoCache.maxItems=1000
cache.globalConfigSharedCache.maxItems=1000
#
# Download Service Limits, in bytes
#
download.maxContentSize=2152852358

View File

@@ -105,29 +105,6 @@
</property>
</bean>
<!-- enable DEBUG for 'org.alfresco.repo.cache.EhCacheTracerJob' and enable scheduler property to activate -->
<bean id="ehCacheTracerJob" class="org.alfresco.util.TriggerBean">
<property name="jobDetail">
<bean id="ehCacheTracerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.cache.EhCacheTracerJob</value>
</property>
</bean>
</property>
<!-- enable this to activate bean
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
-->
<!-- start after an hour and repeat hourly -->
<property name="startDelayMinutes">
<value>60</value>
</property>
<property name="repeatIntervalMinutes">
<value>60</value>
</property>
</bean>
<!-- enable scheduler property to activate -->
<bean id="userUsageCollapseJob" class="org.alfresco.util.TriggerBean">
<property name="jobDetail">

View File

@@ -123,10 +123,7 @@
</property>
</bean>
<!-- Schedule index tracking for ADM -->
<bean id="search.admIndexTrackerTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailBean">
<bean id="search.baseAdmIndexJobDetail" abstract="true" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.node.index.IndexRecoveryJob</value>
</property>
@@ -135,13 +132,14 @@
<entry key="indexRecoveryComponent">
<ref bean="search.admIndexTrackerComponent" />
</entry>
<entry key="clusterName">
<value>${alfresco.cluster.name}</value>
</entry>
</map>
</property>
</bean>
</property>
<bean id="search.admIndexJobDetail" parent="search.baseAdmIndexJobDetail"/>
<!-- Schedule index tracking for ADM -->
<bean id="search.admIndexTrackerTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail" ref="search.admIndexJobDetail"/>
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
@@ -166,10 +164,7 @@
</property>
</bean>
<!-- Schedule index tracking for AVM -->
<bean id="search.avmIndexTrackerTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailBean">
<bean id="search.baseAvmIndexJobDetail" abstract="true" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.node.index.IndexRecoveryJob</value>
</property>
@@ -178,13 +173,14 @@
<entry key="indexRecoveryComponent">
<ref bean="search.avmIndexTrackerComponent" />
</entry>
<entry key="clusterName">
<value>${alfresco.cluster.name}</value>
</entry>
</map>
</property>
</bean>
</property>
<bean id="search.avmIndexJobDetail" parent="search.baseAvmIndexJobDetail"/>
<!-- Schedule index tracking for AVM -->
<bean id="search.avmIndexTrackerTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail" ref="search.avmIndexJobDetail"/>
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
@@ -207,12 +203,7 @@
</bean>
<!-- This JobDetail and its associated Trigger bean will in practice not be run due to the cron
expression used. In order to activate the missing content reindexing, the cron expression
can be changed in the properties file or via JMX (Enterprise-only) -->
<bean id="search.missingFullTextReindexTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.JobDetailBean">
<bean id="search.baseMissingFullTextReindexJobDetail" abstract="true" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.node.index.IndexRecoveryJob</value>
</property>
@@ -221,13 +212,16 @@
<entry key="indexRecoveryComponent">
<ref bean="search.missingFullTextReindexComponent" />
</entry>
<entry key="clusterName">
<value>${alfresco.cluster.name}</value>
</entry>
</map>
</property>
</bean>
</property>
<bean id="search.missingFullTextReindexJobDetail" parent="search.baseMissingFullTextReindexJobDetail"/>
<!-- This JobDetail and its associated Trigger bean will in practice not be run due to the cron
expression used. In order to activate the missing content reindexing, the cron expression
can be changed in the properties file or via JMX (Enterprise-only) -->
<bean id="search.missingFullTextReindexTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail" ref="search.missingFullTextReindexJobDetail"/>
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
@@ -235,4 +229,7 @@
<value>${index.reindexMissingContent.cronExpression}</value>
</property>
</bean>
<!-- Add enterprise clustering configuration when available. -->
<import resource="classpath*:alfresco/enterprise/cluster/index-recovery-overrides.xml"/>
</beans>

View File

@@ -3,7 +3,10 @@
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="fileServerConfiguration" class="org.alfresco.filesys.config.ServerConfigurationBean" parent="fileServerConfigurationBase">
<bean id="fileServerConfiguration"
parent="fileServerConfigurationBase"
factory-bean="fileServerConfigurationFactory"
factory-method="createFileServerConfiguration">
<property name="cifsConfigBean">
<ref bean="cifsServerConfig" />
</property>
@@ -287,8 +290,7 @@
</bean>
<!-- Cluster Configuration -->
<bean id="fileSystemClusterConfig" class="org.alfresco.filesys.config.ClusterConfigBean">
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
<bean id="fileSystemClusterConfig" factory-bean="fileServerConfigurationFactory" factory-method="createClusterConfigBean">
<property name="debugFlags">
<value>${filesystem.cluster.debugFlags}</value>
</property>

View File

@@ -111,20 +111,10 @@
</property>
</bean>
<bean name="contentDiskDriver.fileInfoCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.filesys.fileInfo</value>
</property>
</bean>
</property>
</bean>
<!--
TODO: contentDiskDriver.fileInfoCache bean definition moved from here into cache-context.xml files,
come up with a better scheme for configuring subsystem caches.
-->
<!-- Buffered Content Disk Driver - adds performance buffering -->
<bean id="contentDiskDriver" class="org.alfresco.filesys.repo.BufferedContentDiskDriver"

View File

@@ -0,0 +1,629 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- The transactional cache for Encoding entities -->
<bean name="propertyValueCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="propertyValueSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.propertyValueTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for ContentData -->
<bean name="contentDataCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="contentDataSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.contentDataTransactionalCache</value>
</property>
<property name="maxCacheSize" value="65000" />
<property name="mutable" value="true" />
<property name="allowEqualsChecks" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for immutable entities -->
<bean name="immutableEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="immutableEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.immutableEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="mutable" value="true" /><!-- Null value markers are allowed -->
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Root Nodes -->
<bean name="node.rootNodesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.rootNodesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.rootNodesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
<property name="tenantAware" value="false" />
</bean>
<!-- The transactional cache for Root Nodes -->
<bean name="node.allRootNodesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.allRootNodesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.allRootNodesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="500" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Nodes -->
<bean name="node.nodesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.nodesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.nodesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="125000" />
<property name="mutable" value="true" />
<property name="allowEqualsChecks" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Node Aspects -->
<bean name="node.aspectsCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.aspectsSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.aspectsTransactionalCache</value>
</property>
<property name="maxCacheSize" value="65000" />
<property name="mutable" value="false" />
<property name="disableSharedCache" value="${system.cache.disableImmutableSharedCaches}" />
</bean>
<!-- The transactional cache for Node Properties -->
<bean name="node.propertiesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.propertiesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.propertiesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="65000" />
<property name="mutable" value="false" />
<property name="disableSharedCache" value="${system.cache.disableImmutableSharedCaches}" />
</bean>
<!-- The transactional cache for Child-by-name -->
<bean name="node.childByNameCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="node.childByNameSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.node.childByNameTransactionalCache</value>
</property>
<property name="maxCacheSize" value="65000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Node Rules (shared cache must be null - ie. do not share across txns) -->
<bean name="nodeRulesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="nodeRulesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.nodeRulesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="2000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for User Authorities -->
<bean name="userToAuthorityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="userToAuthoritySharedCache" />
</property>
<property name="name">
<value>org.alfresco.userToAuthorityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="100" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for User Authentication -->
<bean name="authenticationCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="authenticationSharedCache" />
</property>
<property name="name">
<value>org.alfresco.authenticationTransactionalCache</value>
</property>
<property name="maxCacheSize">
<value>100</value>
</property>
</bean>
<!-- The transactional cache for authority containers -->
<bean name="authorityLookupCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="authoritySharedCache" />
</property>
<property name="name">
<value>org.alfresco.authorityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="allowEqualsChecks" value="true" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for authority containers -->
<bean name="authorityToChildAuthorityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="authorityToChildAuthoritySharedCache" />
</property>
<property name="name">
<value>org.alfresco.authorityToChildAuthorityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="40000" />
<property name="mutable" value="true" />
<property name="allowEqualsChecks" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for authority containers -->
<bean name="zoneToAuthorityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="zoneToAuthoritySharedCache" />
</property>
<property name="name">
<value>org.alfresco.zoneToAuthorityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="500" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Permissions -->
<bean name="permissionsAccessCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="permissionsAccessSharedCache" />
</property>
<property name="name">
<value>org.alfresco.permissionsAccessTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for ACL readers -->
<bean name="readersCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="readersSharedCache" />
</property>
<property name="name">
<value>org.alfresco.readersTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for ACL denied readers -->
<bean name="readersDeniedCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="readersDeniedSharedCache" />
</property>
<property name="name">
<value>org.alfresco.readersDeniedTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Node Ownership -->
<bean name="nodeOwnerCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="nodeOwnerSharedCache" />
</property>
<property name="name">
<value>org.alfresco.nodeOwnerTransactionalCache</value>
</property>
<property name="maxCacheSize" value="20000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Person -->
<bean name="personCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="personSharedCache" />
</property>
<property name="name">
<value>org.alfresco.personTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AVM Store entities -->
<bean name="avmStoreCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="avmStoreSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.avmStoreTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AVM entities (various - using cache region) -->
<bean name="avmEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="avmEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.avmEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="5000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AVM VersionRoot entities -->
<bean name="avmVersionRootEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="avmVersionRootEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.avmVersionRootEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="100" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AVM Node entities -->
<bean name="avmNodeCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="avmNodeSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.avmNodeTransactionalCache</value>
</property>
<property name="maxCacheSize" value="5000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AVM Node Aspects entities -->
<bean name="avmNodeAspectsCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="avmNodeAspectsSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.avmNodeAspectsTransactionalCache</value>
</property>
<property name="maxCacheSize" value="5000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- Transactional cache for WebService query sessions -->
<bean name="webServicesQuerySessionCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="webServicesQuerySessionSharedCache"/>
</property>
<property name="name">
<value>org.alfresco.repo.webservices.querySessionTransactionalCache</value>
</property>
<property name="maxCacheSize" value="50" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Node Ownership -->
<bean name="aclCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="aclSharedCache" />
</property>
<property name="name">
<value>org.alfresco.aclTransactionalCache</value>
</property>
<property name="maxCacheSize" value="20000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for ACL entities -->
<bean name="aclEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="aclEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.aclEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="50000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Authority entities -->
<bean name="authorityEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="authorityEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.authorityEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="50000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Permission entities -->
<bean name="permissionEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="permissionEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.permissionEntityTransactionalCache</value>
</property>
<property name="maxCacheSize" value="50000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for In-Memory ResourceBundleBaseNames -->
<bean name="resourceBundleBaseNamesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="resourceBundleBaseNamesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.resourceBundleBaseNamesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for In-Memory LoadedResourceBundles -->
<bean name="loadedResourceBundlesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="loadedResourceBundlesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.loadedResourceBundlesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for In-Memory Messages -->
<bean name="messagesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="messagesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.messagesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Dictionary Models -->
<bean name="compiledModelsCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="compiledModelsSharedCache" />
</property>
<property name="name">
<value>org.alfresco.compiledModelsTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for Dictionary Namespaces -->
<bean name="prefixesCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="prefixesSharedCache" />
</property>
<property name="name">
<value>org.alfresco.prefixesTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for In-Memory WebScripts Registry -->
<bean name="webScriptsRegistryCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="webScriptsRegistrySharedCache" />
</property>
<property name="name">
<value>org.alfresco.webScriptsRegistryTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for AbstractRoutingContentStore -->
<bean name="routingContentStoreCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="routingContentStoreSharedCache" />
</property>
<property name="name">
<value>org.alfresco.routingContentStoreTransactionalCache</value>
</property>
<property name="maxCacheSize" value="10000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for tagscope summary properties -->
<bean name="tagscopeSummaryCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="tagscopeSummarySharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.tagscopeSummaryTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
</bean>
<!-- The transactional cache for IMAP messages -->
<bean name="imapMessageCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="imapMessageSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.imapMessageTransactionalCache</value>
</property>
<property name="maxCacheSize" value="1000" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableImmutableSharedCaches}" />
</bean>
<!-- The transactional cache for in-memory Tenants -->
<bean name="tenantEntityCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="tenantEntitySharedCache" />
</property>
<property name="name">
<value>org.alfresco.tenantsTransactionalCache</value>
</property>
<property name="maxCacheSize" value="100" />
<property name="mutable" value="true" />
<property name="disableSharedCache" value="${system.cache.disableMutableSharedCaches}" />
<property name="tenantAware" value="false" />
</bean>
<!-- The transactional cache for immutable (tenant-aware) singletons -->
<bean name="immutableSingletonCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache">
<ref bean="immutableSingletonSharedCache" />
</property>
<property name="name">
<value>org.alfresco.cache.immutableSingletonTransactionalCache</value>
</property>
<property name="maxCacheSize" value="12000" />
<property name="mutable" value="false" />
<property name="disableSharedCache" value="${system.cache.disableImmutableSharedCaches}" />
</bean>
</beans>

View File

@@ -25,9 +25,7 @@
<property name="activitiesEnabled" value="${system.webdav.activities.enabled}"/>
</bean>
<bean id="webdavLockStoreFactory" class="org.alfresco.repo.webdav.LockStoreFactoryImpl">
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
</bean>
<bean id="webdavLockStoreFactory" class="org.alfresco.repo.webdav.SimpleLockStoreFactory"/>
<!-- Configure remote-api source related beans in remote-api-context.xml to ensure no dependency problems -->
</beans>

View File

@@ -11,7 +11,7 @@ hibernate.jdbc.use_streams_for_binary=true
hibernate.show_sql=false
hibernate.cache.use_query_cache=false
hibernate.max_fetch_depth=10
hibernate.cache.provider_class=org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean
hibernate.cache.provider_class=org.alfresco.repo.cache.DefaultCacheProvider
hibernate.cache.use_second_level_cache=true
hibernate.default_batch_fetch_size=1
hibernate.jdbc.batch_size=32

View File

@@ -269,11 +269,6 @@
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.11</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>

View File

@@ -20,8 +20,6 @@ package org.alfresco;
import java.lang.reflect.Field;
import net.sf.ehcache.CacheManager;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
@@ -82,17 +80,6 @@ public class RepositoryStartStopTest extends TestCase
);
}
/**
* Checks that all our EHCache instances have been shutdown
*/
public static void assertAllCachesShutdown() throws Exception {
assertEquals(
"All Caches should have been shut down, but some remained",
0,
CacheManager.ALL_CACHE_MANAGERS.size()
);
}
private ApplicationContext getMinimalContext() {
ApplicationContextHelper.setUseLazyLoading(false);
ApplicationContextHelper.setNoAutoStart(true);
@@ -124,7 +111,6 @@ public class RepositoryStartStopTest extends TestCase
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
}
/**
@@ -145,7 +131,6 @@ public class RepositoryStartStopTest extends TestCase
// Close it down
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
// Re-open it, we get a fresh copy
ApplicationContext ctx2 = getMinimalContext();
@@ -160,7 +145,6 @@ public class RepositoryStartStopTest extends TestCase
// And finally close it
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
}
/**
@@ -181,7 +165,6 @@ public class RepositoryStartStopTest extends TestCase
// Close it down
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
// Re-open it, we get a fresh copy
ApplicationContext ctx2 = getFullContext();
@@ -198,7 +181,6 @@ public class RepositoryStartStopTest extends TestCase
// And finally close it
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
}
/**
@@ -219,7 +201,6 @@ public class RepositoryStartStopTest extends TestCase
// Close
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
// Now open the full one
@@ -235,7 +216,6 @@ public class RepositoryStartStopTest extends TestCase
// Close it
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
// Back to the minimal one
@@ -246,7 +226,6 @@ public class RepositoryStartStopTest extends TestCase
// Close
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
// And finally we want the full one again
@@ -257,7 +236,6 @@ public class RepositoryStartStopTest extends TestCase
// Close and we're done
ApplicationContextHelper.closeApplicationContext();
assertNoCachedApplicationContext();
assertAllCachesShutdown();
}
public void doTestBasicWriteOperations(ApplicationContext ctx) throws Exception

View File

@@ -18,8 +18,6 @@
*/
package org.alfresco.filesys.config;
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
/**
* The Class ClusterConfigBean.
*
@@ -28,29 +26,19 @@ import org.alfresco.repo.cluster.HazelcastInstanceFactory;
*/
public class ClusterConfigBean
{
private HazelcastInstanceFactory hazelcastInstanceFactory;
private String debugFlags;
private int nearCacheTimeout;
public void setHazelcastInstanceFactory(HazelcastInstanceFactory hazelcastInstanceFactory)
{
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
}
public HazelcastInstanceFactory getHazelcastInstanceFactory()
{
return this.hazelcastInstanceFactory;
}
public boolean getClusterEnabled()
{
return hazelcastInstanceFactory.isClusteringEnabled();
// No clustering support in community edition.
return false;
}
public String getClusterName()
{
return hazelcastInstanceFactory.getClusterName();
// No clustering support in community edition.
return null;
}
public void setDebugFlags(String debugFlags)

View File

@@ -16,19 +16,22 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
package org.alfresco.filesys.config;
/**
* Thrown when unable to send a message using a {@link Messenger}.
* Factory to provide community versions of key fileserver configuration beans.
*
* @author Matt Ward
*/
public class MessageSendingException extends RuntimeException
public class FileServerConfigurationFactory
{
private static final long serialVersionUID = 1L;
public ServerConfigurationBean createFileServerConfiguration()
{
return new ServerConfigurationBean();
}
public MessageSendingException(Throwable e)
public ClusterConfigBean createClusterConfigBean()
{
super("Unable to send message", e);
return new ClusterConfigBean();
}
}

View File

@@ -82,12 +82,10 @@ import org.alfresco.jlan.util.MemorySize;
import org.alfresco.jlan.util.Platform;
import org.alfresco.jlan.util.StringList;
import org.alfresco.jlan.util.X64;
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
import org.alfresco.repo.management.subsystems.ActivateableBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.extensions.config.element.GenericConfigElement;
import com.hazelcast.core.HazelcastInstance;
/**
* Alfresco File Server Configuration Bean Class
@@ -112,7 +110,7 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
private CoreServerConfigBean coreServerConfigBean;
private ThreadRequestPool threadPool;
private ClusterConfigBean clusterConfigBean;
protected ClusterConfigBean clusterConfigBean;
/**
* Default constructor
@@ -2321,10 +2319,6 @@ public class ServerConfigurationBean extends AbstractServerConfigurationBean imp
// Create a ClusterConfigSection and attach it to 'this'.
ClusterConfigSection clusterConf = new ClusterConfigSection(this);
HazelcastInstanceFactory hazelcastInstanceFactory = clusterConfigBean.getHazelcastInstanceFactory();
// Clustering is enabled, so we can safely request the hazelcast instance.
HazelcastInstance hazelcast = hazelcastInstanceFactory.getInstance();
clusterConf.setHazelcastInstance(hazelcast);
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.util.Properties;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.distribution.CacheManagerPeerProvider;
import net.sf.ehcache.distribution.CacheManagerPeerProviderFactory;
import net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Alfresco's <tt>CacheManagerPeerProviderFactory</tt> that defers to the community or
* enterprise factories.
*
* @author Derek Hulley
* @since 3.1
*/
public class AlfrescoCacheManagerPeerProviderFactory extends CacheManagerPeerProviderFactory
{
private static Log logger = LogFactory.getLog(AlfrescoCacheManagerPeerProviderFactory.class);
@Override
public CacheManagerPeerProvider createCachePeerProvider(CacheManager cacheManager, Properties properties)
{
CacheManagerPeerProviderFactory factory = null;
try
{
@SuppressWarnings("unchecked")
Class clazz = Class.forName("org.alfresco.enterprise.repo.cache.cluster.RMICacheManagerPeerProvider$Factory");
factory = (CacheManagerPeerProviderFactory) clazz.newInstance();
}
catch (ClassNotFoundException e)
{
// Entirely expected if the Enterprise-level code is not present
}
catch (Throwable e)
{
logger.error("Failed to instantiate RMICacheManagerPeerProvider factory.", e);
}
finally
{
if (factory == null)
{
// Use EHCache's default implementation
factory = new RMICacheManagerPeerProviderFactory();
}
}
if (logger.isDebugEnabled())
{
logger.debug("Using peer provider factory: " + factory.getClass().getName());
}
return factory.createCachePeerProvider(cacheManager, properties);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.Serializable;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CacheProvider;
import org.hibernate.cache.Timestamper;
/**
* A simple {@link CacheProvider} that allows Hibernate to create {@link DefaultSimpleCache}
* based caches.
*
* @author Matt Ward
*/
public class DefaultCacheProvider implements CacheProvider
{
private final static Log log = LogFactory.getLog(DefaultCacheProvider.class);
// TODO: setup in spring (SystemPropertiesSetterBean)
private int defaultMaxItems = 500;
@Override
public Cache buildCache(String regionName, Properties properties) throws CacheException
{
if (log.isDebugEnabled())
{
log.debug("building cache for regionName=" + regionName + ", with properties: " + properties);
}
DefaultSimpleCache<Serializable, Object> cache = new DefaultSimpleCache<Serializable, Object>();
cache.setMaxItems(defaultMaxItems);
Cache hibCache = new HibernateSimpleCacheAdapter(cache, regionName);
return hibCache;
}
@Override
public long nextTimestamp()
{
return Timestamper.next();
}
@Override
public void start(Properties properties) throws CacheException
{
}
@Override
public void stop()
{
}
@Override
public boolean isMinimalPutsEnabledByDefault()
{
return false;
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.beans.factory.BeanNameAware;
/**
* {@link SimpleCache} implementation backed by a {@link LinkedHashMap}.
*
* @author Matt Ward
*/
public final class DefaultSimpleCache<K extends Serializable, V extends Object>
implements SimpleCache<K, V>, BeanNameAware
{
private final Map<K, V> map;
private int maxItems = 0;
private String cacheName;
public DefaultSimpleCache()
{
// Create a LinkedHashMap with accessOrder true, i.e. iteration order
// will be least recently accessed first. Eviction policy will therefore be LRU.
// The map will have a bounded size determined by the maxItems member variable.
map = (Map<K, V>) Collections.synchronizedMap(new LinkedHashMap<K, V>(16, 0.75f, true) {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(Entry<K, V> eldest)
{
return maxItems > 0 && size() > maxItems;
}
});
}
@Override
public boolean contains(K key)
{
return map.containsKey(key);
}
@Override
public Collection<K> getKeys()
{
return map.keySet();
}
@Override
public V get(K key)
{
return map.get(key);
}
@Override
public void put(K key, V value)
{
map.put(key, value);
}
@Override
public void remove(K key)
{
map.remove(key);
}
@Override
public void clear()
{
map.clear();
}
@Override
public String toString()
{
return "DefaultSimpleCache[maxItems=" + maxItems + ", cacheName=" + cacheName + "]";
}
/**
* Sets the maximum number of items that the cache will hold. Setting
* this value will cause the cache to be emptied. A value of zero
* will allow the cache to grow unbounded.
*
* @param maxItems
*/
public void setMaxItems(int maxItems)
{
synchronized(map)
{
map.clear();
this.maxItems = maxItems;
}
}
/**
* Since there are many cache instances, it is useful to be able to associate
* a name with each one.
*
* @param cacheName Set automatically by Spring, but can be set manually if required.
*/
@Override
public void setBeanName(String cacheName)
{
this.cacheName = cacheName;
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
/**
* Tests for the DefaultSimpleCache class.
*
* @author Matt Ward
*/
public class DefaultSimpleCacheTest
{
private DefaultSimpleCache<Integer, String> cache;
@Before
public void setUp()
{
cache = new DefaultSimpleCache<Integer, String>();
}
@Test
public void unboundedSizeCache()
{
cache.put(1, "1");
cache.put(2, "2");
cache.put(3, "3");
cache.put(4, "4");
cache.put(5, "5");
assertEquals("1", cache.get(1));
assertEquals("2", cache.get(2));
assertEquals("3", cache.get(3));
assertEquals("4", cache.get(4));
assertEquals("5", cache.get(5));
}
@Test
public void boundedSizeCache()
{
// We'll only keep the LAST 3 items
cache.setMaxItems(3);
cache.put(1, "1");
cache.put(2, "2");
cache.put(3, "3");
cache.put(4, "4");
cache.put(5, "5");
// Lost the first item
assertNull(cache.get(1));
assertFalse(cache.contains(1));
// Lost the second item
assertNull(cache.get(2));
assertFalse(cache.contains(2));
// Last three are still present
assertEquals("3", cache.get(3));
assertEquals("4", cache.get(4));
assertEquals("5", cache.get(5));
}
@Test
public void canStoreNullValues()
{
cache.put(2, null);
assertEquals(null, cache.get(2));
// Check that the key has an entry against it.
assertTrue(cache.contains(2));
// Ensure that a key that has not been assigned is discernable
// from a key that has been assigned a null value.
assertEquals(null, cache.get(4));
assertFalse(cache.contains(4));
}
@Test
public void canRemoveItems()
{
cache.put(1, "hello");
cache.put(2, "world");
assertEquals("hello", cache.get(1));
assertEquals("world", cache.get(2));
cache.remove(2);
assertEquals("hello", cache.get(1));
assertEquals(null, cache.get(2));
assertEquals(false, cache.contains(2));
}
@Test
public void canClearItems()
{
cache.put(1, "hello");
cache.put(2, "world");
assertEquals("hello", cache.get(1));
assertEquals("world", cache.get(2));
cache.clear();
assertEquals(null, cache.get(1));
assertEquals(false, cache.contains(1));
assertEquals(null, cache.get(2));
assertEquals(false, cache.contains(2));
}
@Test
public void canGetKeys()
{
cache.put(3, "blue");
cache.put(12, "red");
cache.put(43, "olive");
Iterator<Integer> it = cache.getKeys().iterator();
assertEquals(3, it.next().intValue());
assertEquals(12, it.next().intValue());
assertEquals(43, it.next().intValue());
assertFalse("There should be no more keys.", it.hasNext());
}
@Test
public void clearUponSetMaxItems()
{
cache.put(1, "1");
assertTrue(cache.contains(1));
cache.setMaxItems(10);
// The item should have gone.
assertFalse(cache.contains(1));
}
}

View File

@@ -1,121 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.Serializable;
import java.util.Collection;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Element;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* A thin adapter for <b>Ehcache</b> support.
* <p>
* Thread-safety is taken care of by the underlying <b>Ehcache</b>
* instance.
*
* @see org.springframework.cache.ehcache.EhCacheFactoryBean
* @see org.springframework.cache.ehcache.EhCacheManagerFactoryBean
*
* @author Derek Hulley
*/
public class EhCacheAdapter<K extends Serializable, V extends Object>
implements SimpleCache<K, V>
{
private net.sf.ehcache.Cache cache;
public EhCacheAdapter()
{
}
/**
* @param cache the backing Ehcache instance
*/
public void setCache(Cache cache)
{
this.cache = cache;
}
public boolean contains(K key)
{
try
{
return (cache.getQuiet(key) != null);
}
catch (CacheException e)
{
throw new AlfrescoRuntimeException("contains failed", e);
}
}
@SuppressWarnings("unchecked")
public Collection<K> getKeys()
{
return cache.getKeys();
}
@SuppressWarnings("unchecked")
public V get(K key)
{
try
{
Element element = cache.get(key);
if (element != null)
{
return (V) element.getObjectValue();
}
else
{
return null;
}
}
catch (IllegalStateException ie)
{
throw new AlfrescoRuntimeException("Failed to get from EhCache as state invalid: \n" +
" state: " + cache.getStatus() + "\n" +
" key: " + key,
ie);
}
catch (CacheException e)
{
throw new AlfrescoRuntimeException("Failed to get from EhCache: \n" +
" key: " + key,
e);
}
}
public void put(K key, V value)
{
Element element = new Element(key, value);
cache.put(element);
}
public void remove(K key)
{
cache.remove(key);
}
public void clear()
{
cache.removeAll();
}
}

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.IOException;
import java.net.URL;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
/**
* This is virtually a copy of the Springframework version, with the exception
* that it uses the newer constructors for the <code>EHCacheManager</code>
* instances.
*
* @author Derek Hulley
*/
public class EhCacheManagerFactoryBean implements FactoryBean, InitializingBean, DisposableBean
{
static
{
// https://jira.terracotta.org/jira/browse/EHC-652
// Force old-style LruMemoryStore
// System.setProperty("net.sf.ehcache.use.classic.lru", "true");
}
protected final Log logger = LogFactory.getLog(EhCacheManagerFactoryBean.class);
private Resource configLocation;
private CacheManager cacheManager;
/**
*
* @param configLocation a resource location using the <b>file:</b> or <b>classpath:</b> prefix
*/
public void setConfigLocation(Resource configLocation)
{
this.configLocation = configLocation;
}
public void afterPropertiesSet() throws IOException, CacheException
{
PropertyCheck.mandatory(this, "configLocation", configLocation);
// Double-check the config location or EHCache will throw an NPE
try
{
URL configUrl = this.configLocation.getURL();
logger.info("Initializing EHCache CacheManager using URL: " + configLocation);
this.cacheManager = new CacheManager(configUrl);
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("Unabled to read EHCache configuration file at " + configLocation, e);
}
}
public Object getObject()
{
return this.cacheManager;
}
@SuppressWarnings("unchecked")
public Class getObjectType()
{
return (this.cacheManager != null ? this.cacheManager.getClass() : CacheManager.class);
}
public boolean isSingleton()
{
return true;
}
public void destroy()
{
logger.info("Shutting down EHCache CacheManager");
if(logger.isDebugEnabled()) {
String[] caches = this.cacheManager.getCacheNames();
for(String cache : caches) {
logger.debug("Shutting down EHCache instance " + cache);
}
}
this.cacheManager.shutdown();
}
}

View File

@@ -1,250 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.List;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.Status;
import net.sf.ehcache.statistics.LiveCacheStatistics;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* Analyzes the size of EHCache caches used.
* <p>
* To activate this class, call the {@link #init()} method.
*
* @author Derek Hulley
*/
public class EhCacheTracerJob implements Job
{
private static Log logger = LogFactory.getLog(EhCacheTracerJob.class);
private CacheManager cacheManager;
/**
* Set the cache manager to analyze. The default cache manager will be analyzed
* if this property is not set.
*
* @param cacheManager optional cache manager to analyze
*/
public void setCacheManager(CacheManager cacheManager)
{
this.cacheManager = cacheManager;
}
public void execute(JobExecutionContext context) throws JobExecutionException
{
try
{
execute();
}
catch (Throwable e)
{
logger.error("Exception during execution of job", e);
}
}
private void execute() throws Exception
{
if (cacheManager == null)
{
cacheManager = InternalEhCacheManagerFactoryBean.getInstance();
}
long maxHeapSize = Runtime.getRuntime().maxMemory();
long allCachesTotalSize = 0L;
double estimatedMaxSize = 0L;
// get all the caches
String[] cacheNames = cacheManager.getCacheNames();
logger.debug("Dumping EHCache info:");
boolean analyzeAll = true;
for (String cacheName : cacheNames)
{
Cache cache = cacheManager.getCache(cacheName);
//cache.getCacheEventNotificationService().
// cache.registerCacheUsageListener(cacheUsageListener)
if (cache == null) // perhaps a temporary cache
{
continue;
}
Log cacheLogger = LogFactory.getLog(this.getClass().getName() + "." + cacheName);
// log each cache to its own logger
// dump
if (cacheLogger.isDebugEnabled())
{
CacheAnalysis analysis = new CacheAnalysis(cache);
cacheLogger.debug(analysis);
// get the size
allCachesTotalSize += analysis.getSize();
double cacheEstimatedMaxSize = analysis.getEstimatedMaxSize();
estimatedMaxSize += (Double.isNaN(cacheEstimatedMaxSize) || Double.isInfinite(cacheEstimatedMaxSize))
? 0.0
: cacheEstimatedMaxSize;
}
else
{
analyzeAll = false;
}
}
if (analyzeAll)
{
// check the size
double sizePercentage = (double)allCachesTotalSize / (double)maxHeapSize * 100.0;
double maxSizePercentage = estimatedMaxSize / (double)maxHeapSize * 100.0;
String msg = String.format(
"EHCaches currently consume %5.2f MB or %3.2f percent of system VM size. \n" +
"The estimated maximum size is %5.2f MB or %3.2f percent of system VM size.",
(double)allCachesTotalSize / 1024.0 / 1024.0,
sizePercentage,
estimatedMaxSize / 1024.0 / 1024.0,
maxSizePercentage);
logger.debug(msg);
}
}
private static class CacheAnalysis
{
private Cache cache;
private long size = 0L;
double sizeMB;
long maxSize;
long currentSize;
long hitCount;
long missCount;
double percentageFull;
double estMaxSize;
public CacheAnalysis(Cache cache) throws CacheException
{
this.cache = cache;
if (this.cache.getStatus().equals(Status.STATUS_ALIVE))
{
try
{
calculateSize();
}
catch (Throwable e)
{
// just ignore
}
}
}
public synchronized long getSize()
{
return size;
}
public synchronized double getEstimatedMaxSize()
{
return estMaxSize;
}
@SuppressWarnings("unchecked")
private synchronized void calculateSize() throws CacheException
{
// calculate the cache deep size - EHCache 1.1 is always returning 0L
List<Serializable> keys = cache.getKeys();
// only count a maximum of 1000 entities
int count = 0;
for (Serializable key : keys)
{
Element element = cache.get(key);
size += getSize(element);
count++;
if (count >= 50)
{
break;
}
}
// the size must be multiplied by the ratio of the count to actual size
size = count > 0 ? (long) ((double)size * ((double)keys.size()/(double)count)) : 0L;
sizeMB = (double)size/1024.0/1024.0;
LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
maxSize = cache.getCacheConfiguration().getMaxElementsInMemory();
currentSize = cache.getMemoryStoreSize();
hitCount = statistics.getCacheHitCount();
missCount = statistics.getCacheMissCount();
percentageFull = (double)currentSize / (double)maxSize * 100.0;
estMaxSize = size / (double) currentSize * (double) maxSize;
}
private long getSize(Serializable obj)
{
ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
ObjectOutputStream oos = null;
try
{
oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
return bout.size();
}
catch (IOException e)
{
logger.warn("Deep size calculation failed for cache: \n" + cache);
return 0L;
}
finally
{
try { oos.close(); } catch (IOException e) {}
}
}
public String toString()
{
double sizeMB = (double)getSize()/1024.0/1024.0;
LiveCacheStatistics statistics = cache.getLiveCacheStatistics();
long maxSize = cache.getCacheConfiguration().getMaxElementsInMemory();
long currentSize = cache.getMemoryStoreSize();
long hitCount = statistics.getCacheHitCount();
long totalMissCount = statistics.getCacheMissCount() + statistics.getCacheMissCountExpired();
double hitRatio = (double)hitCount / (double)(totalMissCount + hitCount) * 100.0;
double percentageFull = (double)currentSize / (double)maxSize * 100.0;
double estMaxSize = sizeMB / (double) currentSize * (double) maxSize;
StringBuilder sb = new StringBuilder(512);
sb.append("\n")
.append("===> EHCache: ").append(cache).append("\n")
.append(" Hit Ratio: ").append(String.format("%10.2f percent ", hitRatio ))
.append(" | Hit Count: ").append(String.format("%10d hits ", hitCount ))
.append(" | Miss Count: ").append(String.format("%10d misses ", totalMissCount )).append("\n")
.append(" Deep Size: ").append(String.format("%10.2f MB ", sizeMB ))
.append(" | Current Count: ").append(String.format("%10d entries ", currentSize )).append("\n")
.append(" Percentage used: ").append(String.format("%10.2f percent", percentageFull))
.append(" | Max Count: ").append(String.format("%10d entries ", maxSize )).append("\n")
.append(" Estimated maximum size: ").append(String.format("%10.2f MB ", estMaxSize ));
return sb.toString();
}
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.Serializable;
import java.util.Map;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.Timestamper;
/**
* Adapts a {@link SimpleCache} instance for use as a Hibernate {@link Cache}.
*
* @author Matt Ward
*/
public class HibernateSimpleCacheAdapter implements Cache
{
private final SimpleCache<Serializable, Object> cache;
private final String regionName;
/**
* Adapt a
* @param cache
* @param regionName
*/
public HibernateSimpleCacheAdapter(SimpleCache<Serializable, Object> cache, String regionName)
{
this.cache = cache;
this.regionName = regionName;
}
@Override
public Object read(Object key) throws CacheException
{
return cache.get(serializable(key));
}
@Override
public Object get(Object key) throws CacheException
{
return cache.get(serializable(key));
}
@Override
public void put(Object key, Object value) throws CacheException
{
cache.put(serializable(key), value);
}
@Override
public void update(Object key, Object value) throws CacheException
{
cache.put(serializable(key), value);
}
@Override
public void remove(Object key) throws CacheException
{
cache.remove(serializable(key));
}
@Override
public void clear() throws CacheException
{
cache.clear();
}
@Override
public void destroy() throws CacheException
{
// NoOp
}
@Override
public void lock(Object key) throws CacheException
{
// NoOp
}
@Override
public void unlock(Object key) throws CacheException
{
// NoOp
}
@Override
public long nextTimestamp()
{
return Timestamper.next();
}
@Override
public int getTimeout()
{
return Timestamper.ONE_MS * 60000; // 1 minute
}
@Override
public String getRegionName()
{
return regionName;
}
@Override
public long getSizeInMemory()
{
return -1;
}
@Override
public long getElementCountInMemory()
{
return -1;
}
@Override
public long getElementCountOnDisk()
{
return 0;
}
@Override
public Map toMap()
{
throw new UnsupportedOperationException();
}
private Serializable serializable(Object obj)
{
if (!(obj instanceof Serializable))
{
throw new IllegalArgumentException("Object is not Serializable, class=" + obj.getClass().getName());
}
return (Serializable) obj;
}
}

View File

@@ -1,250 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cache;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.Properties;
import net.sf.ehcache.CacheManager;
import org.alfresco.error.AlfrescoRuntimeException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cache.Cache;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.CacheProvider;
import org.hibernate.cache.EhCache;
import org.hibernate.cache.EhCacheProvider;
import org.hibernate.cache.Timestamper;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.ResourceUtils;
/**
* Alfresco-specific cache manager factory.
* <p>
* The purpose of this bean is to provide a common point from which the system-wide
* EHCache <code>CacheManager</code> singleton is created. Hibernate and Spring
* will all pick up the same <code>CacheManager</code> instance. It then becomes
* possible to initialise this instance in whichever way we require, provided it
* is done in a well-known (non-configurable) way.
* <p>
* For Alfresco purposes, there are two files that are looked for:
* <ul>
* <li><b>classpath:alfresco/extension/ehcache-custom.xml</b>, which will take precedence</li>
* <li><b>classpath:alfresco/ehcache-default.xml</b>, which is the default shipped with Alfresco</li>
* </ul>
* <p>
* The EHCache static singleton instance is used but ensuring that all access to the
* instance goes through the required initialization code first.
* <p>
* TODO: Provide mixing of config so that cache definitions in the custom file override
* those in the default file
*
* @see #getInstance()
*
* @author Derek Hulley
*/
public class InternalEhCacheManagerFactoryBean implements FactoryBean<CacheManager>, CacheProvider
{
static
{
// https://jira.terracotta.org/jira/browse/EHC-652
// Force old-style LruMemoryStore
// System.setProperty("net.sf.ehcache.use.classic.lru", "true");
}
public static final String CUSTOM_CONFIGURATION_FILE = "classpath:alfresco/extension/ehcache-custom.xml";
public static final String DEFAULT_CONFIGURATION_FILE = "classpath:alfresco/ehcache-default.xml";
private static Log logger = LogFactory.getLog(InternalEhCacheManagerFactoryBean.class);
/** keep track of the singleton status to avoid work */
private static boolean initialized;
/** the <code>CacheManager</code> */
private static CacheManager cacheManager;
/** used to ensure that the existing Hibernate logic is maintained */
private static EhCacheProvider hibernateEhCacheProvider = new EhCacheProvider();
/**
* Default constructor required by Hibernate. In fact, we anticipate several
* instances of this class to be created.
*/
public InternalEhCacheManagerFactoryBean()
{
}
/**
* News up the singleton cache manager according to the rules set out
* in the class comments.
*/
private static synchronized void initCacheManager()
{
if (initialized)
{
return;
}
try
{
boolean defaultLocation = false;
try
{
URL configUrl = ResourceUtils.getURL(CUSTOM_CONFIGURATION_FILE);
InternalEhCacheManagerFactoryBean.cacheManager = CacheManager.create(configUrl);
}
catch (FileNotFoundException e)
{
// try the alfresco default
URL configUrl = ResourceUtils.getURL(DEFAULT_CONFIGURATION_FILE);
if (configUrl == null)
{
throw new AlfrescoRuntimeException("Missing default cache config: " + DEFAULT_CONFIGURATION_FILE);
}
InternalEhCacheManagerFactoryBean.cacheManager = new CacheManager(configUrl);
defaultLocation = true;
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Created EHCache CacheManager instance: \n" +
" configuration: " + (defaultLocation ? DEFAULT_CONFIGURATION_FILE : CUSTOM_CONFIGURATION_FILE));
}
initialized = true;
}
catch (Throwable e)
{
throw new AlfrescoRuntimeException("EHCache configuration failed", e);
}
}
/**
* @return Returns the properly initialized instance for Alfresco internal use
*
* @see #initCacheManager()
*/
public static CacheManager getInstance()
{
if (!InternalEhCacheManagerFactoryBean.initialized)
{
InternalEhCacheManagerFactoryBean.initCacheManager();
}
return InternalEhCacheManagerFactoryBean.cacheManager;
}
public Cache buildCache(String regionName, Properties properties) throws CacheException
{
CacheManager manager = InternalEhCacheManagerFactoryBean.getInstance();
try
{
net.sf.ehcache.Cache cache = manager.getCache(regionName);
if (cache == null)
{
logger.info("Using default cache configuration: " + regionName);
manager.addCache(regionName);
cache = manager.getCache(regionName);
logger.debug("Started EHCache region: " + regionName);
}
return new EhCache(cache);
}
catch (net.sf.ehcache.CacheException e)
{
throw new CacheException(e);
}
}
/**
* @see #hibernateEhCacheProvider
*/
public boolean isMinimalPutsEnabledByDefault()
{
return false;
}
/**
* @see #hibernateEhCacheProvider
*/
public long nextTimestamp()
{
return Timestamper.next();
}
/**
* @see #initCacheManager()
*/
public void start(Properties properties) throws CacheException
{
InternalEhCacheManagerFactoryBean.initCacheManager();
}
/**
* @see #initCacheManager()
*/
public void stop()
{
// TODO: Does this port over different Locales?
// Better to override DbPersistenceServiceFactory#close to put a marker on the thread.
if (Thread.currentThread().getName().contains("Finalizer"))
{
// Probably JBPM's finalizer code ... we rely on Spring context calls rather
return;
}
synchronized (getClass())
{
if(logger.isDebugEnabled()) {
String[] caches = InternalEhCacheManagerFactoryBean.getInstance().getCacheNames();
for(String regionName : caches) {
logger.debug("Stopped EHCache region: " + regionName);
}
}
if (initialized) // Avoid re-initialization if it has already been shut down
{
InternalEhCacheManagerFactoryBean.getInstance().shutdown();
initialized = false;
}
}
}
/**
* @return Returns the singleton cache manager
*
* @see #initCacheManager()
*/
public CacheManager getObject() throws Exception
{
return InternalEhCacheManagerFactoryBean.getInstance();
}
/**
* @return Returns the singleton cache manager type
*/
public Class<CacheManager> getObjectType()
{
return CacheManager.class;
}
/**
* @return Returns true always
*/
public boolean isSingleton()
{
return true;
}
}

View File

@@ -25,8 +25,6 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import net.sf.ehcache.CacheException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.tenant.TenantUtil;
@@ -734,7 +732,7 @@ public class TransactionalCache<K extends Serializable, V extends Object>
logger.debug("Pre-commit called for " + keys.size() + " values.");
}
}
catch (CacheException e)
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Failed to transfer updates to shared cache", e);
}
@@ -795,7 +793,7 @@ public class TransactionalCache<K extends Serializable, V extends Object>
logger.debug("Post-commit called for " + keys.size() + " values.");
}
}
catch (CacheException e)
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Failed to transfer updates to shared cache", e);
}
@@ -837,7 +835,7 @@ public class TransactionalCache<K extends Serializable, V extends Object>
}
}
}
catch (CacheException e)
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Failed to transfer updates to shared cache", e);
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
/**
* Test suite for org.alfresco.repo.cluster tests, but <strong>excluding</strong>
* tests which are known to fail in the CI environment (Bamboo).
* <p>
* These tests are still useful in the desktop development environment however,
* so are kept for this reason. {@link ClusterTestSuite} runs all the tests in this
* suite, plus the offending tests.
*
* @author Matt Ward
*/
@RunWith(Suite.class)
@SuiteClasses({
org.alfresco.repo.cluster.HazelcastConfigFactoryBeanTest.class,
org.alfresco.repo.cluster.HazelcastMessengerFactoryTest.class,
org.alfresco.repo.cluster.HazelcastMessengerTest.class
})
public class BuildSafeTestSuite
{
// Annotations specify the suite.
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterCheckEvent extends ClusterMessageEvent
{
private static final long serialVersionUID = -4633842466757526069L;
public ClusterCheckEvent(ClusterChecker clusterChecker, String sourceId, String targetId)
{
super(clusterChecker, sourceId, targetId);
}
}

View File

@@ -1,759 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import org.alfresco.repo.lock.JobLockService;
import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
/**
* Checks that the cluster is working.
*
* @since Odin
*
*/
public class ClusterChecker implements MessageReceiver<ClusterMessageEvent>, ApplicationContextAware
{
private static final Log logger = LogFactory.getLog(ClusterChecker.class);
private static final String TmpFile = ".clusterChecker";
private static final QName LOCK = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "ClusterChecker");
/*
* WORKING: is synced with other nodes in the cluster
* NOTWORKING: is alive but not synced with other nodes in the cluster
* UNKNOWN: status is unknown (could be in the middle of checking)
* CHECKING: still waiting for cluster check response
*/
public static enum NodeStatus
{
WORKING, NOTWORKING, TIMEOUT, UNKNOWN;
};
// time to wait for a cluster node to respond
private int timeout = 4000; // ms
private ApplicationContext applicationContext;
private AuthenticationService authenticationService;
private TransactionService transactionService;
private MessengerFactory messengerFactory;
private JobLockService jobLockService;
private Messenger<ClusterMessageEvent> messenger;
private Timer timer = new Timer();
// cluster nodes that this node knows about
private Map<String, NodeInfo> nodeInfo = new ConcurrentHashMap<String, NodeInfo>();
// unique id for this cluster node
private String id = null;
public ClusterChecker() throws FileNotFoundException, IOException, ClassNotFoundException
{
this.id = buildId();
}
private String buildId() throws FileNotFoundException, IOException, ClassNotFoundException
{
// we need an immutable unique id for the cluster node
String guid = null;
File systemTmpDir = TempFileProvider.getSystemTempDir();
File tmpFile = new File(systemTmpDir, TmpFile);
// persist the id locally
if(!tmpFile.exists())
{
guid = GUID.generate();
tmpFile.createNewFile();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(tmpFile));
out.writeObject(guid);
out.close();
}
else
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(tmpFile));
guid = (String)in.readObject();
in.close();
}
return guid;
}
/**
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
*
* @return Returns the lock token or <tt>null</tt>
*/
private String getLock(long time)
{
try
{
return jobLockService.getLock(LOCK, time);
}
catch (LockAcquisitionException e)
{
return null;
}
}
public void init()
{
this.messenger = messengerFactory.createMessenger(getClass().getName(), true);
messenger.setReceiver(this);
}
public void shutdown()
{
cancelTimer();
}
public void setTimeout(int timeout)
{
this.timeout = timeout;
}
public void setJobLockService(JobLockService jobLockService)
{
this.jobLockService = jobLockService;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
public void setMessengerFactory(MessengerFactory messengerFactory)
{
this.messengerFactory = messengerFactory;
}
private void cancelTimer()
{
timer.cancel();
}
private NodeInfo registerNode(String id)
{
NodeInfo info = new NodeInfo(id);
nodeInfo.put(id, info);
return info;
}
private void checkCluster()
{
// set the status of any currently tracked to 'checking'
for(NodeInfo info : nodeInfo.values())
{
info.setChecking(true);
}
// Authenticate and get a ticket. This will be used to validate that the other nodes in the cluster are
// 'working' i.e. their caches are updating in the cluster.
try
{
AuthenticationUtil.pushAuthentication();
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
String ticket = authenticationService.getCurrentTicket();
messenger.send(new ClusterValidateEvent(this, ticket, id, null));
}
catch(AuthenticationException e)
{
logger.warn("Unable to check cluster, authentication failed", e);
return;
}
finally
{
AuthenticationUtil.popAuthentication();
}
// A timer to mark nodes still in the checking state as not alive after a timeout.
timer.schedule(new TimerTask()
{
@Override
public void run()
{
for(NodeInfo info : nodeInfo.values())
{
List<String> timedOut = info.timeoutNodes();
for(String nodeId : timedOut)
{
nodePairStatusChange(info.getId(), nodeId, NodeStatus.TIMEOUT);
}
}
}
}, timeout);
}
private void nodePairStatusChange(String sourceNodeId, String targetNodeId, NodeStatus status)
{
publishEvent(new ClusterNodePairStatusEvent(this, sourceNodeId, targetNodeId, status));
}
private void nodeFound(String nodeId)
{
publishEvent(new ClusterNodeExistsEvent(this, nodeId));
}
private String getAddress()
{
try
{
return InetAddress.getLocalHost().getHostName();
}
catch(UnknownHostException e)
{
return "Unknown";
}
}
private void publishEvent(ApplicationEvent event)
{
applicationContext.publishEvent(event);
}
private void handleValidationEvent(ClusterValidateEvent validateEvent)
{
String sourceId = validateEvent.getSourceId();
String ticket = validateEvent.getTicket();
// try to validate the ticket generated by the source node
boolean ticketValid = true;
try
{
AuthenticationUtil.pushAuthentication();
authenticationService.validate(ticket);
if(!authenticationService.getCurrentUserName().equals(AuthenticationUtil.getAdminUserName()))
{
ticketValid = false;
}
}
catch(AuthenticationException e)
{
ticketValid = false;
}
finally
{
AuthenticationUtil.popAuthentication();
}
messenger.send(new ClusterValidateResponseEvent(this, getAddress(), sourceId, id, ticketValid));
}
private void handleValidationResponse(ClusterValidateResponseEvent validateResponseEvent)
{
String sourceId = validateResponseEvent.getSourceId();
String targetId = validateResponseEvent.getTargetId();
String address = validateResponseEvent.getAddress(); // target address
NodeInfo source = getNodeInfo(sourceId);
boolean newSourceNode = false;
if(source == null)
{
source = registerNode(sourceId);
newSourceNode = true;
}
// update the target's address, if it isn't known already
boolean newTargetNode = false;
NodeInfo remote = getNodeInfo(targetId);
if(remote == null)
{
remote = registerNode(targetId);
newTargetNode = true;
}
remote.setAddress(address);
// update source node's view of the target's status
boolean ticketValid = validateResponseEvent.isTicketValid();
NodeStatus newTargetStatus = ticketValid ? NodeStatus.WORKING : NodeStatus.NOTWORKING;
source.setStatus(targetId, newTargetStatus);
if(newSourceNode)
{
nodeFound(sourceId);
}
if(newTargetNode)
{
nodeFound(targetId);
}
if(!sourceId.equals(targetId) && newTargetStatus != NodeStatus.UNKNOWN)
{
nodePairStatusChange(sourceId, targetId, newTargetStatus);
}
}
public boolean isConnected()
{
return messenger.isConnected();
}
public boolean isClusterActive()
{
return messengerFactory.isClusterActive();
}
public Map<String, NodeInfo> getNodeInfo()
{
return Collections.unmodifiableMap(nodeInfo);
}
public NodeInfo getNodeInfo(String nodeId)
{
return nodeInfo.get(nodeId);
}
public String getId()
{
return id;
}
public void check()
{
// Take out a lock to prevent more than one check at a time
RetryingTransactionCallback<String> txnWork = new RetryingTransactionCallback<String>()
{
public String execute() throws Exception
{
String lockToken = getLock(timeout + 1000);
return lockToken;
}
};
final String lockToken = transactionService.getRetryingTransactionHelper().doInTransaction(txnWork, false, true);
if(lockToken == null)
{
logger.warn("Can't get lock. Assume multiple cluster checkers ...");
return;
}
// Kick off the check by broadcasting the initiating event to each node in the cluster
if (messenger.isConnected())
{
messenger.send(new ClusterCheckEvent(this, id, null));
}
// A timer to release the lock after a timeout
timer.schedule(new TimerTask()
{
@Override
public void run()
{
jobLockService.releaseLock(lockToken, LOCK);
}
}, timeout);
}
public List<PeerNodeInfo> getPeers(String nodeId)
{
NodeInfo nodeInfo = getNodeInfo(nodeId);
Map<String, PeerStatus> peersInfo = nodeInfo.getPeersInfo();
List<PeerNodeInfo> ret = new ArrayList<PeerNodeInfo>();
for(String peerId : peersInfo.keySet())
{
if(peerId.equals(nodeId))
{
continue;
}
NodeInfo peerInfo = getNodeInfo(peerId);
NodeStatus peerStatus = peersInfo.get(peerId).getNodeStatus();
String peerAddress = peerInfo.getAddress();
ret.add(new PeerNodeInfo(peerId, peerAddress, peerStatus));
}
return ret;
}
public void stopChecking(String nodeId)
{
if(nodeInfo.containsKey(nodeId))
{
nodeInfo.remove(nodeId);
}
for(NodeInfo node : nodeInfo.values())
{
node.stopChecking(nodeId);
}
publishEvent(new ClusterNodeStopTrackingEvent(this, nodeId));
}
@Override
public void onReceive(ClusterMessageEvent event)
{
if (event == null)
{
return;
}
if(event instanceof ClusterCheckEvent)
{
checkCluster();
}
else if(event instanceof ClusterValidateEvent)
{
// handle validation request from another node
handleValidationEvent((ClusterValidateEvent)event);
}
else if(event instanceof ClusterValidateResponseEvent)
{
// handle response to a validation request
handleValidationResponse((ClusterValidateResponseEvent)event);
}
}
public Set<UnorderedPair<String>> getNonWorkingNodePairs()
{
Set<UnorderedPair<String>> nonWorkingPairs = new HashSet<UnorderedPair<String>>();
for(NodeInfo node : nodeInfo.values())
{
// a cluster node is regarded as working only if every other node agrees
// notes that for a 2 node cluster with one node down, the other node will still be regarded
// as not working because there are no other nodes to counter the non-working node.
nonWorkingPairs.addAll(node.getNonWorkingPeers());
}
return nonWorkingPairs;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
// Records information on a peer i.e. whether it is being checked and its status
private static class PeerStatus
{
private boolean checking;
private NodeStatus nodeStatus;
public PeerStatus()
{
this.checking = false;
this.nodeStatus = NodeStatus.UNKNOWN;
}
public boolean isChecking()
{
return checking;
}
void setChecking(boolean checking)
{
this.checking = checking;
}
public NodeStatus getNodeStatus()
{
return nodeStatus;
}
void setNodeStatus(NodeStatus nodeStatus)
{
this.nodeStatus = nodeStatus;
}
}
public static class PeerNodeInfo
{
private String peerId;
private String peerAddress;
private NodeStatus peerStatus;
public PeerNodeInfo(String peerId, String peerAddress, NodeStatus peerStatus) {
super();
this.peerId = peerId;
this.peerAddress = peerAddress;
this.peerStatus = peerStatus;
}
public String getPeerId()
{
return peerId;
}
public String getPeerAddress()
{
return peerAddress;
}
public NodeStatus getPeerStatus()
{
return peerStatus;
}
}
// Information pertaining to a cluster node and its peers
public static class NodeInfo
{
private String id;
private String address;
private Map<String, PeerStatus> nodeInfos = new ConcurrentHashMap<String, PeerStatus>(5);
public NodeInfo(String id)
{
super();
this.id = id;
}
public String getId()
{
return id;
}
public String getAddress()
{
return address;
}
void setAddress(String address)
{
this.address = address;
}
void setStatus(String targetId, NodeStatus status)
{
PeerStatus peerStatus = getStatus(targetId, true);
peerStatus.setChecking(false);
peerStatus.setNodeStatus(status);
}
void stopChecking(String nodeId)
{
nodeInfos.remove(nodeId);
}
public Map<String, PeerStatus> getPeersInfo()
{
return Collections.unmodifiableMap(nodeInfos);
}
public PeerStatus getStatus(String nodeId)
{
return getStatus(nodeId, false);
}
public PeerStatus getStatus(String nodeId, boolean create)
{
PeerStatus peerStatus = nodeInfos.get(nodeId);
if(peerStatus == null)
{
peerStatus = new PeerStatus();
nodeInfos.put(nodeId, peerStatus);
}
return peerStatus;
}
void setChecking(boolean checking)
{
for(String nodeId : nodeInfos.keySet())
{
setChecking(nodeId, checking);
}
}
void setChecking(String nodeId, boolean checking)
{
PeerStatus status = getStatus(nodeId, true);
status.setChecking(checking);
}
void setStatuses(NodeStatus status)
{
for(String nodeId : nodeInfos.keySet())
{
setStatus(nodeId, status);
}
}
List<String> timeoutNodes()
{
List<String> timedOut = new ArrayList<String>();
for(String nodeId : nodeInfos.keySet())
{
if(getStatus(nodeId).isChecking())
{
setStatus(nodeId, NodeStatus.TIMEOUT);
timedOut.add(nodeId);
}
}
return timedOut;
}
public Set<UnorderedPair<String>> getNonWorkingPeers()
{
Set<UnorderedPair<String>> nonWorkingPeers = new HashSet<UnorderedPair<String>>();
for(String nodeId : nodeInfos.keySet())
{
if(!getId().equals(nodeId) && getStatus(nodeId).getNodeStatus() != NodeStatus.WORKING)
{
nonWorkingPeers.add(new UnorderedPair<String>(getId(), nodeId));
}
}
return nonWorkingPeers;
}
public boolean equals(Object other)
{
if (this == other)
{
return true;
}
if(!(other instanceof NodeInfo))
{
return false;
}
NodeInfo nodeInfo = (NodeInfo)other;
return EqualsHelper.nullSafeEquals(getId(), nodeInfo.getId());
}
}
public static class UnorderedPair<T> implements Serializable
{
private static final long serialVersionUID = -8947346745086237616L;
@SuppressWarnings({ "unchecked", "rawtypes" })
public static final UnorderedPair NULL_PAIR = new UnorderedPair(null, null);
@SuppressWarnings("unchecked")
public static final <X> UnorderedPair<X> nullPair()
{
return NULL_PAIR;
}
/**
* The first member of the pair.
*/
private T first;
/**
* The second member of the pair.
*/
private T second;
/**
* Make a new one.
*
* @param first The first member.
* @param second The second member.
*/
public UnorderedPair(T first, T second)
{
this.first = first;
this.second = second;
}
/**
* Get the first member of the tuple.
* @return The first member.
*/
public final T getFirst()
{
return first;
}
/**
* Get the second member of the tuple.
* @return The second member.
*/
public final T getSecond()
{
return second;
}
@Override
public boolean equals(Object other)
{
if (this == other)
{
return true;
}
if (other == null || !(other instanceof UnorderedPair<?>))
{
return false;
}
UnorderedPair<?> o = (UnorderedPair<?>)other;
return EqualsHelper.nullSafeEquals(this.first, o.first) &&
EqualsHelper.nullSafeEquals(this.second, o.second) ||
EqualsHelper.nullSafeEquals(this.first, o.second) &&
EqualsHelper.nullSafeEquals(this.second, o.first);
}
@Override
public int hashCode()
{
return (first == null ? 0 : first.hashCode()) + (second == null ? 0 : second.hashCode());
}
@Override
public String toString()
{
return "(" + first + ", " + second + ")";
}
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import org.springframework.context.ApplicationEvent;
/**
*
* @since Odin
*
*/
public class ClusterEvent extends ApplicationEvent
{
private static final long serialVersionUID = 7481373845772903712L;
public ClusterEvent(ClusterChecker clusterChecker)
{
super(clusterChecker);
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterMessageEvent extends ClusterEvent
{
private static final long serialVersionUID = -8677530378696271077L;
private String sourceId;
private String targetId;
public ClusterMessageEvent(ClusterChecker clusterChecker, String sourceId, String targetId)
{
super(clusterChecker);
this.sourceId = sourceId;
this.targetId = targetId;
}
public String getSourceId()
{
return sourceId;
}
public String getTargetId()
{
return targetId;
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterNodeExistsEvent extends ClusterEvent
{
private static final long serialVersionUID = -9060051914186153663L;
public static final String NOTIFICATION_TYPE = "Cluster Node Found";
private String nodeId;
public ClusterNodeExistsEvent(ClusterChecker clusterChecker, String nodeId)
{
super(clusterChecker);
this.nodeId = nodeId;
}
public String getNodeId()
{
return nodeId;
}
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import org.alfresco.repo.cluster.ClusterChecker.NodeStatus;
/**
*
* @Odin
*
*/
public class ClusterNodePairStatusEvent extends ClusterEvent
{
private static final long serialVersionUID = -4045195741687097066L;
public static final String NOTIFICATION_TYPE = "Cluster Node Pair Status";
private String sourceNodeId;
private String targetNodeId;
private NodeStatus status;
public ClusterNodePairStatusEvent(ClusterChecker clusterChecker, String sourceNodeId, String targetNodeId, NodeStatus status)
{
super(clusterChecker);
this.sourceNodeId = sourceNodeId;
this.targetNodeId = targetNodeId;
this.status = status;
}
public String getSourceNodeId()
{
return sourceNodeId;
}
public String getTargetNodeId()
{
return targetNodeId;
}
public NodeStatus getStatus()
{
return status;
}
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterNodeStopTrackingEvent extends ClusterEvent
{
private static final long serialVersionUID = -116885933025872510L;
public static final String NOTIFICATION_TYPE = "Cluster Node Stop Tracking";
private String nodeId;
public ClusterNodeStopTrackingEvent(ClusterChecker clusterChecker, String nodeId)
{
super(clusterChecker);
this.nodeId = nodeId;
}
public String getNodeId()
{
return nodeId;
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
/**
* Test suite for the org.alfresco.repo.cluster package.
* <p>
* This includes tests which will <strong>fail</strong> on the build servers -
* do not include this suite in the CI build targets.
*
* @author Matt Ward
*/
@RunWith(Suite.class)
@SuiteClasses({
// Run the standard tests
org.alfresco.repo.cluster.BuildSafeTestSuite.class,
// Additionally run these tests that cannot be run on the build servers.
org.alfresco.repo.cluster.HazelcastTest.class
})
public class ClusterTestSuite
{
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterValidateEvent extends ClusterMessageEvent
{
private static final long serialVersionUID = -8091460189522981871L;
private String ticket;
public ClusterValidateEvent(ClusterChecker clusterChecker, String ticket, String sourceId, String targetId)
{
super(clusterChecker, sourceId, targetId);
this.ticket = ticket;
}
public String getTicket()
{
return ticket;
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
*
* @since Odin
*
*/
public class ClusterValidateResponseEvent extends ClusterMessageEvent
{
private static final long serialVersionUID = -813956714769487998L;
private String address;
private boolean ticketValid;
public ClusterValidateResponseEvent(ClusterChecker clusterChecker, String address, String sourceId, String targetId, boolean ticketValid)
{
super(clusterChecker, sourceId, targetId);
this.address = address;
this.ticketValid = ticketValid;
}
public String getAddress()
{
return address;
}
public boolean isTicketValid()
{
return ticketValid;
}
}

View File

@@ -1,172 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Properties;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import com.hazelcast.config.Config;
import com.hazelcast.config.InMemoryXmlConfig;
/**
* FactoryBean used to create Hazelcast {@link Config} objects. A configuration file is supplied
* in the form of a Spring {@link Resource} and a set of {@link Properties} can also be provided. The
* XML file is processed so that property placeholders of the form ${property.name} are substitued for
* the corresponding property value before the XML is parsed into the Hazelcast configuration object.
*
* @author Matt Ward
*/
public class HazelcastConfigFactoryBean implements InitializingBean, FactoryBean<Config>
{
private static final String PLACEHOLDER_END = "}";
private static final String PLACEHOLDER_START = "${";
private Resource configFile;
private Config config;
private Properties properties;
/**
* Set the Hazelcast XML configuration file to use. This will be merged with the supplied
* Properties and parsed to produce a final {@link Config} object.
* @param configFile the configFile to set
*/
public void setConfigFile(Resource configFile)
{
this.configFile = configFile;
}
/**
* Used to supply the set of Properties that the configuration file can reference.
*
* @param properties the properties to set
*/
public void setProperties(Properties properties)
{
this.properties = properties;
}
/**
* Spring {@link InitializingBean} lifecycle method. Substitutes property placeholders for their
* corresponding values and creates a {@link Config Hazelcast configuration} with the post-processed
* XML file - ready for the {@link #getObject()} factory method to be used to retrieve it.
*/
@Override
public void afterPropertiesSet() throws Exception
{
if (configFile == null)
{
throw new IllegalArgumentException("No configuration file specified.");
}
if (properties == null)
{
properties = new Properties();
}
// These configXML strings will be large and are therefore intended
// to be thrown away. We only want to keep the final Config object.
String rawConfigXML = getConfigFileContents();
String configXML = substituteProperties(rawConfigXML);
config = new InMemoryXmlConfig(configXML);
}
/**
* For the method parameter <code>text</code>, replaces all occurrences of placeholders having
* the form ${property.name} with the value of the property having the key "property.name". The
* properties are supplied using {@link #setProperties(Properties)}.
*
* @param text The String to apply property substitutions to.
* @return String after substitutions have been applied.
*/
private String substituteProperties(String text)
{
for (String propName : properties.stringPropertyNames())
{
String propValue = properties.getProperty(propName);
String quotedPropName = Pattern.quote(PLACEHOLDER_START + propName + PLACEHOLDER_END);
text = text.replaceAll(quotedPropName, propValue);
}
return text;
}
/**
* Opens the configFile {@link Resource} and reads the contents into a String.
*
* @return the contents of the configFile resource.
*/
private String getConfigFileContents()
{
StringWriter writer = new StringWriter();
InputStream inputStream = null;
try
{
inputStream = configFile.getInputStream();
IOUtils.copy(inputStream, writer, "UTF-8");
return writer.toString();
}
catch (IOException e)
{
throw new RuntimeException("Couldn't read configuration: " + configFile, e);
}
finally
{
try
{
if (inputStream != null)
{
inputStream.close();
}
}
catch (IOException e)
{
throw new RuntimeException("Couldn't close stream", e);
}
}
}
/**
* FactoryBean's factory method. Returns the config with the property key/value
* substitutions in place.
*/
@Override
public Config getObject() throws Exception
{
return config;
}
@Override
public Class<?> getObjectType()
{
return Config.class;
}
@Override
public boolean isSingleton()
{
return true;
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import static org.junit.Assert.assertEquals;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import com.hazelcast.config.Config;
/**
* Tests for the HazelcastConfigFactoryBean class.
*
* @author Matt Ward
*/
public class HazelcastConfigFactoryBeanTest
{
private HazelcastConfigFactoryBean configFactory;
private Resource resource;
private Properties properties;
@Before
public void setUp() throws Exception
{
configFactory = new HazelcastConfigFactoryBean();
resource = new ClassPathResource("cluster-test/placeholder-test.xml");
configFactory.setConfigFile(resource);
properties = new Properties();
properties.setProperty("alfresco.hazelcast.password", "let-me-in");
properties.setProperty("alfresco.cluster.name", "cluster-name");
configFactory.setProperties(properties);
// Trigger the spring post-bean creation lifecycle method
configFactory.afterPropertiesSet();
}
@Test
public void testConfigHasNewPropertyValues() throws Exception
{
// Invoke the factory method.
Config config = configFactory.getObject();
assertEquals("let-me-in", config.getGroupConfig().getPassword());
assertEquals("cluster-name", config.getGroupConfig().getName());
}
}

View File

@@ -1,139 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.alfresco.util.PropertyCheck;
import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
/**
* Provides a way of lazily creating HazelcastInstances for a given configuration.
* The HazelcastInstance will not be created until {@link #getInstance()} is called.
* <p>
* An intermediary class such as this is required in order to avoid starting
* Hazelcast instances when clustering is not configured/required. Otherwise
* 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
*/
public class HazelcastInstanceFactory
{
private Config config;
private HazelcastInstance hazelcastInstance;
/** Guards {@link #config} and {@link #hazelcastInstance} */
private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public HazelcastInstance getInstance()
{
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();
}
}
/**
* 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)
{
rwLock.writeLock().lock();
try
{
this.config = config;
}
finally
{
rwLock.writeLock().unlock();
}
}
}

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.MessageListener;
/**
* Hazelcast-based implementation of the {@link Messenger} interface.
*
* @see HazelcastMessengerFactory
* @author Matt Ward
*/
public class HazelcastMessenger<T extends Serializable> implements Messenger<T>, MessageListener<T>
{
private ITopic<T> topic;
private MessageReceiver<T> receiverDelegate;
private String address;
private final static Log logger = LogFactory.getLog(HazelcastMessenger.class);
/**
* @param topic
*/
public HazelcastMessenger(ITopic<T> topic, String address)
{
this.topic = topic;
this.address = address;
}
@Override
public void send(T message)
{
if (logger.isTraceEnabled())
{
String digest = StringUtils.abbreviate(message.toString(), 50);
logger.trace("Sending [source: " + address + "]: " + digest);
}
topic.publish(message);
}
@Override
public void setReceiver(MessageReceiver<T> receiver)
{
// Install a delegate to ready to handle incoming messages.
receiverDelegate = receiver;
// Start receiving messages.
topic.addMessageListener(this);
}
@Override
public void onMessage(T message)
{
if (logger.isTraceEnabled())
{
String digest = StringUtils.abbreviate(message.toString(), 50);
logger.trace("Received [destination: " + address + "] (delegating to receiver): " + digest);
}
receiverDelegate.onReceive(message);
}
@Override
public boolean isConnected()
{
return true;
}
protected ITopic<T> getTopic()
{
return topic;
}
@Override
public String getAddress()
{
return address;
}
@Override
public String toString()
{
return "HazelcastMessenger[connected=" + isConnected() +
", topic=" + getTopic() +
", address=" + getAddress() + "]";
}
}

View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
import java.util.Set;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Member;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
/**
* Hazelcast-based implementation of the {@link MessengerFactory} interface.
* The factory must be configured with a {@link HazelcastInstance} - which
* is the underlying factory for {@link ITopic} creation.
*
* @author Matt Ward
*/
public class HazelcastMessengerFactory implements MessengerFactory
{
private HazelcastInstanceFactory hazelcastInstanceFactory;
@Override
public <T extends Serializable> Messenger<T> createMessenger(String appRegion)
{
return createMessenger(appRegion, false);
}
@Override
public <T extends Serializable> Messenger<T> createMessenger(String appRegion, boolean acceptLocalMessages)
{
if (!isClusterActive())
{
return new NullMessenger<T>();
}
// Clustering is enabled, create a messenger.
HazelcastInstance hazelcast = hazelcastInstanceFactory.getInstance();
ITopic<T> topic = hazelcast.getTopic(appRegion);
String address = hazelcast.getCluster().getLocalMember().getInetSocketAddress().toString();
return new HazelcastMessenger<T>(topic, address);
}
/**
* Provide the messenger factory with a means to obtain a HazelcastInstance.
*
* @param hazelcastInstanceFactory
*/
public void setHazelcastInstanceFactory(HazelcastInstanceFactory hazelcastInstanceFactory)
{
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
}
@Override
public boolean isClusterActive()
{
return hazelcastInstanceFactory.isClusteringEnabled();
}
@Override
public void addMembershipListener(final ClusterMembershipListener listener)
{
if (isClusterActive())
{
HazelcastInstance hazelcast = hazelcastInstanceFactory.getInstance();
hazelcast.getCluster().addMembershipListener(new MembershipListener()
{
@Override
public void memberRemoved(MembershipEvent e)
{
listener.memberLeft(member(e), cluster(e));
}
@Override
public void memberAdded(MembershipEvent e)
{
listener.memberJoined(member(e), cluster(e));
}
private String member(MembershipEvent e)
{
return e.getMember().getInetSocketAddress().toString();
}
private String[] cluster(MembershipEvent e)
{
Set<Member> members = e.getCluster().getMembers();
String[] cluster = new String[members.size()];
int i = 0;
for (Member m : members)
{
cluster[i++] = m.getInetSocketAddress().toString();
}
return cluster;
}
});
}
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.when;
import java.net.InetSocketAddress;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.hazelcast.core.Cluster;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Member;
/**
* Tests for the HazelcastMessengerFactory class.
*
* @author Matt Ward
*/
@RunWith(MockitoJUnitRunner.class)
public class HazelcastMessengerFactoryTest
{
private HazelcastMessengerFactory factory;
private @Mock HazelcastInstance hazelcast;
private @Mock Member member;
private @Mock Cluster cluster;
private @Mock ITopic<String> topic;
private @Mock HazelcastInstanceFactory hazelcastInstanceFactory;
@Before
public void setUp()
{
factory = new HazelcastMessengerFactory();
factory.setHazelcastInstanceFactory(hazelcastInstanceFactory);
when(hazelcastInstanceFactory.isClusteringEnabled()).thenReturn(true);
when(hazelcastInstanceFactory.getInstance()).thenReturn(hazelcast);
}
@Test
public void topicWrappedInMessenger()
{
when(hazelcast.<String>getTopic("app-region")).thenReturn(topic);
when(hazelcast.getCluster()).thenReturn(cluster);
when(cluster.getLocalMember()).thenReturn(member);
when(member.getInetSocketAddress()).thenReturn(InetSocketAddress.createUnresolved("a-host-name", 1234));
Messenger<String> messenger = factory.createMessenger("app-region");
assertSame(topic, ((HazelcastMessenger<String>) messenger).getTopic());
assertEquals("a-host-name:1234", messenger.getAddress());
}
@Test
public void canCheckClusterIsActive()
{
assertEquals(true, factory.isClusterActive());
when(hazelcastInstanceFactory.isClusteringEnabled()).thenReturn(false);
assertEquals(false, factory.isClusterActive());
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.hazelcast.core.ITopic;
/**
* Tests for the HazelcastMessenger class.
*
* @author Matt Ward
*/
@RunWith(MockitoJUnitRunner.class)
public class HazelcastMessengerTest
{
private @Mock ITopic<String> topic;
private HazelcastMessenger<String> messenger;
private String receivedMsg;
@Before
public void setUp()
{
messenger = new HazelcastMessenger<String>(topic, "address");
receivedMsg = null;
}
@Test
public void canSendMessage()
{
messenger.send("Test string");
verify(topic).publish("Test string");
}
@Test
public void canReceiveMessage()
{
messenger.setReceiver(new MessageReceiver<String>()
{
@Override
public void onReceive(String message)
{
receivedMsg = new String(message);
}
});
// Hazelcast will call the onMessage method...
messenger.onMessage("Hazelcast is sending a message.");
// setReceiver() should have resulted in a listener being registered with the topic.
verify(topic).addMessageListener(messenger);
assertEquals("Hazelcast is sending a message.", receivedMsg);
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import org.alfresco.repo.cluster.MessengerTestHelper.TestMessageReceiver;
import org.alfresco.util.ApplicationContextHelper;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.MessageListener;
/**
* Tests for Hazelcast implementations of {@link Messenger} and related classes.
* These are integration tests and configured through a Spring test context file.
*
* @author Matt Ward
*/
public class HazelcastTest implements MessageListener<String>
{
private static ApplicationContext ctx;
private MessengerTestHelper helper;
private HazelcastInstanceFactory hiFactory;
private HazelcastInstance hi;
@BeforeClass
public static void setUpClass()
{
ctx = ApplicationContextHelper.
getApplicationContext(new String[] { "cluster-test/hazelcast-messenger-test.xml" });
}
@AfterClass
public static void tearDownClass()
{
ApplicationContextHelper.closeApplicationContext();
Hazelcast.shutdownAll();
}
@Before
public void setUp()
{
helper = new MessengerTestHelper();
hiFactory = ctx.getBean(HazelcastInstanceFactory.class);
hi = hiFactory.getInstance();
}
@Test
public void canSendWithHazelcastMessengerFactory() throws InterruptedException
{
ITopic<String> topic = hi.getTopic("testregion");
topic.addMessageListener(this);
MessengerFactory messengerFactory = (MessengerFactory) ctx.getBean("messengerFactory");
Messenger<String> messenger = messengerFactory.createMessenger("testregion");
messenger.send("Full test including spring.");
helper.checkMessageReceivedWas("Full test including spring.");
}
@Ignore("Behaviour not yet implemented.")
@Test
public void messengerWillNotReceiveMessagesFromSelf() throws InterruptedException
{
MessengerFactory messengerFactory = (MessengerFactory) ctx.getBean("messengerFactory");
Messenger<String> m1 = messengerFactory.createMessenger("testregion");
TestMessageReceiver r1 = new TestMessageReceiver();
m1.setReceiver(r1);
ITopic<String> topic2 = hi.getTopic("testregion");
String address2 = hi.getCluster().getLocalMember().getInetSocketAddress().toString();
Messenger<String> m2 = new HazelcastMessenger<String>(topic2, address2);
TestMessageReceiver r2 = new TestMessageReceiver();
m2.setReceiver(r2);
m1.send("This should be received by r2 but not r1");
r2.helper.checkMessageReceivedWas("This should be received by r2 but not r1");
r1.helper.checkNoMessageReceived();
}
@Override
public void onMessage(String message)
{
helper.setReceivedMsg(message);
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
/**
* Implement this interface and supply to a {@link Messenger} using
* {@link Messenger#setReceiver(MessageReceiver)} in order to receive
* messages from other {@link Messenger}s.
*
* @author Matt Ward
*/
public interface MessageReceiver<T extends Serializable>
{
void onReceive(T message);
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
/**
* Provides facilities for peer-to-peer messaging within a cluster. This interface
* is intended to act as a facade, allowing the actual implementation (e.g. Hazelcast)
* to be decoupled as much as possible from the Alfresco code base.
* <p>
* Instances of this class are parameterised with the type of message payload
* to send and receive.
*
* @author Matt Ward
*/
public interface Messenger<T extends Serializable>
{
void send(T message);
void setReceiver(MessageReceiver<T> receiver);
boolean isConnected();
String getAddress();
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
/**
* Factory class responsible for creating instances of {@link Messenger} class.
*
* @author Matt Ward
*/
public interface MessengerFactory
{
/** A catch-all for unknown application regions. */
public static final String APP_REGION_DEFAULT = "DEFAULT";
/** The application region used by the EHCache heartbeat implementation. */
public static final String APP_REGION_EHCACHE_HEARTBEAT = "EHCACHE_HEARTBEAT";
<T extends Serializable> Messenger<T> createMessenger(String appRegion);
<T extends Serializable> Messenger<T> createMessenger(String appRegion, boolean acceptLocalMessages);
boolean isClusterActive();
void addMembershipListener(ClusterMembershipListener membershipListener);
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
/**
* Static container for MessengerFactory. This allows code to obtain the correct
* {@link MessengerFactory} implementation where dependency injection is not available.
*
* @author Matt Ward
*/
public class MessengerFactoryProvider
{
private static MessengerFactory instance;
public void setInstance(MessengerFactory messengerFactory)
{
instance = messengerFactory;
}
public static MessengerFactory getInstance()
{
if (instance == null)
{
throw new IllegalStateException("MessengerFactory instance not configured yet.");
}
return instance;
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
/**
* Helper class for testing Messenger related code.
*
* @author Matt Ward
*/
public class MessengerTestHelper
{
private String receivedMsg;
private final static int SLEEP_MILLIS = 50;
private static final int MAX_TRIES = 30;
public MessengerTestHelper()
{
setReceivedMsg(null);
}
/**
* Try to avoid intermitten test failures by trying multiple times. Hopefully the messge
* will have been received after the very first sleep, but in a slow environment it may take longer.
* This also allows the sleep time to be lower - rather than waiting for say 50 ms, we can try 10 times
* at 5 ms - with a chance that we can return after the initial 5 ms.
*
* @param expectedMsg
* @throws InterruptedException
*/
public void checkMessageReceivedWas(String expectedMsg)
{
int tries = 0;
while (tries < MAX_TRIES)
{
try
{
Thread.sleep(SLEEP_MILLIS);
}
catch (InterruptedException e)
{
// Carry on
e.printStackTrace();
}
if (getReceivedMsg() != null)
{
assertEquals(expectedMsg, getReceivedMsg());
return;
}
tries++;
}
fail("No message received, tried " + tries +
" times, sleeping " + SLEEP_MILLIS + "ms each time.");
}
/**
* Assert that no message was received in the given period.
*/
public void checkNoMessageReceived()
{
int tries = 0;
while (tries < MAX_TRIES)
{
try
{
Thread.sleep(SLEEP_MILLIS);
}
catch (InterruptedException e)
{
// Carry on
e.printStackTrace();
}
if (getReceivedMsg() != null)
{
fail("Message received but should NOT have been. Message was: " + getReceivedMsg());
}
tries++;
}
}
/**
* @return the receivedMsg
*/
public String getReceivedMsg()
{
return this.receivedMsg;
}
/**
* @param receivedMsg the receivedMsg to set
*/
public void setReceivedMsg(String receivedMsg)
{
this.receivedMsg = receivedMsg;
}
public static class TestMessageReceiver implements MessageReceiver<String>
{
MessengerTestHelper helper = new MessengerTestHelper();
@Override
public void onReceive(String message)
{
helper.setReceivedMsg(message);
}
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A do-nothing implementation of the {@link Messenger} interface.
*
* @author Matt Ward
*/
public class NullMessenger<T extends Serializable> implements Messenger<T>
{
private static final Log logger = LogFactory.getLog(NullMessenger.class);
@Override
public void send(T message)
{
if (logger.isDebugEnabled())
{
logger.debug("Throwing away message: " + message);
}
}
@Override
public void setReceiver(MessageReceiver<T> receiver)
{
if (logger.isDebugEnabled())
{
logger.debug("Throwing away receiver: " + receiver);
}
}
@Override
public boolean isConnected()
{
return false;
}
@Override
public String getAddress()
{
if (logger.isDebugEnabled())
{
logger.debug("getAddress() always returns loopback address: 127.0.0.1");
}
return "127.0.0.1";
}
}

View File

@@ -24,10 +24,8 @@ import java.util.Collections;
import java.util.Date;
import java.util.List;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -158,11 +156,7 @@ public class RoutingContentStoreTest extends AbstractWritableContentStoreTest
{
this.stores.add(store);
}
Cache ehCache = new Cache("RandomRoutingContentStore", 50, false, true, 0L, 0L);
CacheManager cacheManager = new CacheManager();
cacheManager.addCache(ehCache);
EhCacheAdapter<Pair<String,String>, ContentStore> cache = new EhCacheAdapter<Pair<String,String>, ContentStore>();
cache.setCache(ehCache);
SimpleCache<Pair<String,String>, ContentStore> cache = new DefaultSimpleCache<Pair<String,String>, ContentStore>();
super.setStoresCache(cache);
}

View File

@@ -20,9 +20,8 @@ package org.alfresco.repo.content.caching;
import java.io.File;
import net.sf.ehcache.CacheManager;
import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.content.AbstractWritableContentStoreTest;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore;
@@ -42,8 +41,6 @@ import org.junit.runner.RunWith;
@RunWith(JUnit38ClassRunner.class)
public class CachingContentStoreSpringTest extends AbstractWritableContentStoreTest
{
private static final String EHCACHE_NAME = "cache.test.cachingContentStoreCache";
private static final int T24_HOURS = 86400;
private CachingContentStore store;
private FileContentStore backingStore;
private ContentCacheImpl cache;
@@ -67,22 +64,9 @@ public class CachingContentStoreSpringTest extends AbstractWritableContentStoreT
store = new CachingContentStore(backingStore, cache, false);
}
private EhCacheAdapter<Key, String> createMemoryStore()
private SimpleCache<Key, String> createMemoryStore()
{
CacheManager manager = CacheManager.getInstance();
// Create the cache if it hasn't already been created.
if (!manager.cacheExists(EHCACHE_NAME))
{
net.sf.ehcache.Cache memoryOnlyCache =
new net.sf.ehcache.Cache(EHCACHE_NAME, 50, false, false, T24_HOURS, T24_HOURS);
manager.addCache(memoryOnlyCache);
}
EhCacheAdapter<Key, String> memoryStore = new EhCacheAdapter<Key, String>();
memoryStore.setCache(manager.getCache(EHCACHE_NAME));
SimpleCache<Key, String> memoryStore = new DefaultSimpleCache<Key, String>();
return memoryStore;
}

View File

@@ -28,11 +28,11 @@ import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.NullCache;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.dictionary.DictionaryDAOImpl.DictionaryRegistry;
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceRegistry;
import org.alfresco.repo.dictionary.constraint.AbstractConstraint;
@@ -116,25 +116,13 @@ public class RepoDictionaryDAOTest extends TestCase
private void initDictionaryCaches(DictionaryDAOImpl dictionaryDAO)
{
CacheManager cacheManager = new CacheManager();
Cache dictionaryEhCache = new Cache("dictionaryCache", 50, false, true, 0L, 0L);
cacheManager.addCache(dictionaryEhCache);
EhCacheAdapter<String, DictionaryRegistry> dictionaryCache = new EhCacheAdapter<String, DictionaryRegistry>();
dictionaryCache.setCache(dictionaryEhCache);
SimpleCache<String,DictionaryRegistry> dictionaryCache = new DefaultSimpleCache<String, DictionaryRegistry>();
dictionaryDAO.setDictionaryRegistryCache(dictionaryCache);
}
private void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
{
CacheManager cacheManager = new CacheManager();
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
cacheManager.addCache(namespaceEhCache);
EhCacheAdapter<String, NamespaceRegistry> namespaceCache = new EhCacheAdapter<String, NamespaceRegistry>();
namespaceCache.setCache(namespaceEhCache);
SimpleCache<String, NamespaceRegistry> namespaceCache = new NullCache<String, NamespaceRegistry>();
namespaceDAO.setNamespaceRegistryCache(namespaceCache);
}

View File

@@ -21,10 +21,8 @@ package org.alfresco.repo.dictionary;
import java.util.ArrayList;
import java.util.List;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.dictionary.DictionaryDAOImpl.DictionaryRegistry;
import org.alfresco.repo.dictionary.NamespaceDAOImpl.NamespaceRegistry;
import org.alfresco.repo.tenant.SingleTServiceImpl;
@@ -120,25 +118,13 @@ public class TestModel
private static void initDictionaryCaches(DictionaryDAOImpl dictionaryDAO)
{
CacheManager cacheManager = new CacheManager();
Cache dictionaryEhCache = new Cache("dictionaryCache", 50, false, true, 0L, 0L);
cacheManager.addCache(dictionaryEhCache);
EhCacheAdapter<String, DictionaryRegistry> dictionaryCache = new EhCacheAdapter<String, DictionaryRegistry>();
dictionaryCache.setCache(dictionaryEhCache);
SimpleCache<String, DictionaryRegistry> dictionaryCache = new DefaultSimpleCache<String, DictionaryRegistry>();
dictionaryDAO.setDictionaryRegistryCache(dictionaryCache);
}
private static void initNamespaceCaches(NamespaceDAOImpl namespaceDAO)
{
CacheManager cacheManager = new CacheManager();
Cache namespaceEhCache = new Cache("namespaceCache", 50, false, true, 0L, 0L);
cacheManager.addCache(namespaceEhCache);
EhCacheAdapter<String, NamespaceRegistry> namespaceCache = new EhCacheAdapter<String, NamespaceRegistry>();
namespaceCache.setCache(namespaceEhCache);
SimpleCache<String, NamespaceRegistry> namespaceCache = new DefaultSimpleCache<String, NamespaceRegistry>();
namespaceDAO.setNamespaceRegistryCache(namespaceCache);
}
}

View File

@@ -23,7 +23,7 @@ import java.util.HashMap;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.remotecredentials.PasswordCredentialsInfoImpl;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -67,7 +67,7 @@ public class RemoteAlfrescoTicketServiceImpl implements RemoteAlfrescoTicketServ
private RetryingTransactionHelper retryingTransactionHelper;
private RemoteCredentialsService remoteCredentialsService;
private RemoteConnectorService remoteConnectorService;
private EhCacheAdapter<String, String> ticketsCache;
private SimpleCache<String, String> ticketsCache;
private Map<String,String> remoteSystemsUrls = new HashMap<String, String>();
private Map<String,Map<String,String>> remoteSystemsReqHeaders = new HashMap<String, Map<String,String>>();
@@ -89,9 +89,9 @@ public class RemoteAlfrescoTicketServiceImpl implements RemoteAlfrescoTicketServ
}
/**
* Sets the EhCache to be used to cache remote tickets in
* Sets the SimpleCache to be used to cache remote tickets in
*/
public void setTicketsCache(EhCacheAdapter<String, String> ticketsCache)
public void setTicketsCache(SimpleCache<String, String> ticketsCache)
{
this.ticketsCache = ticketsCache;
}

View File

@@ -21,6 +21,9 @@ package org.alfresco.repo.transaction;
import java.lang.reflect.Method;
import java.sql.BatchUpdateException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
@@ -31,8 +34,6 @@ import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import net.sf.ehcache.distribution.RemoteCacheException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.error.ExceptionStackUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
@@ -89,7 +90,7 @@ public class RetryingTransactionHelper
public static final Class[] RETRY_EXCEPTIONS;
static
{
RETRY_EXCEPTIONS = new Class[] {
Class<?>[] coreClasses = new Class[] {
ConcurrencyFailureException.class,
DeadlockLoserDataAccessException.class,
StaleObjectStateException.class,
@@ -104,9 +105,53 @@ public class RetryingTransactionHelper
TooManyResultsException.class, // Expected one result but found multiple (bad key alert)
ObjectNotFoundException.class,
CacheException.class, // Usually a cache replication issue
RemoteCacheException.class, // A cache replication issue
SQLGrammarException.class // Actually specific to MS SQL Server 2005 - we check for this
};
List<Class<?>> retryExceptions = new ArrayList<Class<?>>();
// Add core classes to the list.
retryExceptions.addAll(Arrays.asList(coreClasses));
// Add enterprise-specific classes to the list
retryExceptions.addAll(enterpriseRetryExceptions());
RETRY_EXCEPTIONS = retryExceptions.toArray(new Class[] {});
}
/**
* Use reflection to load a list of enterprise-specific exception classes to add to the
* core list specified in this class.
* <p>
* This is used to decouple this class from enterprise-specific libraries.
*
* @return List of enterprise exception classes or empty list if not available.
*/
private static List<Class<?>> enterpriseRetryExceptions()
{
List<Class<?>> retryExceptions = null;
try
{
Class<?> c = Class.forName("org.alfresco.enterprise.repo.transaction.RetryExceptions");
retryExceptions = (List<Class<?>>) c.newInstance();
}
catch (ClassNotFoundException error)
{
// It's ok not to have the enterprise class available.
}
catch (InstantiationException error)
{
throw new AlfrescoRuntimeException("Unable to instantiate enterprise RetryExceptions.");
}
catch (IllegalAccessException error)
{
throw new AlfrescoRuntimeException("Unable to instantiate enterprise RetryExceptions.");
}
// If no enterprise class found then create an empty list.
if (retryExceptions == null)
{
retryExceptions = Collections.emptyList();
}
return retryExceptions;
}
/**

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2005-2012 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.webdav;
import java.util.concurrent.ConcurrentMap;
import org.alfresco.repo.cluster.HazelcastInstanceFactory;
import org.alfresco.service.cmr.repository.NodeRef;
import com.hazelcast.core.HazelcastInstance;
/**
* Default implementation of the {@link LockStoreFactory} interface. Creates {@link LockStore}s
* backed by a Hazelcast distributed Map if clustering is enabled,
* otherwise it creates a non-clustered {@link SimpleLockStore}.
*
* @see LockStoreFactory
* @see LockStoreImpl
* @author Matt Ward
*/
public class LockStoreFactoryImpl implements LockStoreFactory
{
private static final String HAZELCAST_MAP_NAME = "webdav-locks";
private HazelcastInstanceFactory hazelcastInstanceFactory;
/**
* This method should be used sparingly and the created {@link LockStore}s should be
* retained (this factory does not cache instances of them).
*/
@Override
public synchronized LockStore createLockStore()
{
if (!hazelcastInstanceFactory.isClusteringEnabled())
{
return new SimpleLockStore();
}
else
{
HazelcastInstance instance = hazelcastInstanceFactory.getInstance();
ConcurrentMap<NodeRef, LockInfo> map = instance.getMap(HAZELCAST_MAP_NAME);
return new LockStoreImpl(map);
}
}
/**
* @param hazelcastInstanceFactory the factory that will create a HazelcastInstance if required.
*/
public synchronized void setHazelcastInstanceFactory(HazelcastInstanceFactory hazelcastInstanceFactory)
{
this.hazelcastInstanceFactory = hazelcastInstanceFactory;
}
}

View File

@@ -16,15 +16,18 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.cluster;
package org.alfresco.repo.webdav;
/**
* Implementing classes can react to members joining or leaving the cluster.
* LockStoreFactory that always returns a new {@link SimpleLockStore} instance.
*
* @author Matt Ward
*/
public interface ClusterMembershipListener
public class SimpleLockStoreFactory implements LockStoreFactory
{
void memberJoined(String member, String[] cluster);
void memberLeft(String member, String[] cluster);
@Override
public LockStore createLockStore()
{
return new SimpleLockStore();
}
}

View File

@@ -1,41 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<ehcache>
<!-- defaults -->
<diskStore
path="java.io.tmpdir"
/>
<defaultCache
maxElementsInMemory="5000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false"
>
</defaultCache>
<cache
name="cache1"
maxElementsInMemory="200000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="backingCache"
maxElementsInMemory="200000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
<cache
name="objectCache"
maxElementsInMemory="200000"
eternal="true"
overflowToDisk="false"
statistics="false"
/>
</ehcache>

View File

@@ -1,58 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<!-- sample bean configuration to test cache configurations -->
<beans>
<bean name="testEHCacheManager" class="org.alfresco.repo.cache.EhCacheManagerFactoryBean" >
<property name="configLocation">
<value>classpath:cache-test/cache-test-config.xml</value>
</property>
</bean>
<bean name="ehCache1" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="testEHCacheManager" />
</property>
<property name="cacheName">
<value>cache1</value>
</property>
</bean>
</property>
</bean>
<bean name="backingCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="testEHCacheManager" />
</property>
<property name="cacheName">
<value>backingCache</value>
</property>
</bean>
</property>
</bean>
<bean name="transactionalCache" class="org.alfresco.repo.cache.TransactionalCache">
<property name="sharedCache"><ref bean="backingCache" /></property>
<property name="name"><value>transactionalCache</value></property>
<property name="maxCacheSize"><value>200000</value></property>
</bean>
<bean name="objectCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean" >
<property name="cacheManager">
<ref bean="testEHCacheManager" />
</property>
<property name="cacheName">
<value>objectCache</value>
</property>
</bean>
</property>
</bean>
</beans>

View File

@@ -5,19 +5,7 @@
<import resource="classpath:alfresco/application-context.xml" />
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.cachingContentStoreCache</value>
</property>
</bean>
</property>
</bean>
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.DefaultSimpleCache"/>
<bean id="backingStore" class="org.alfresco.repo.content.filestore.FileContentStore">
<constructor-arg>

View File

@@ -35,24 +35,8 @@
</bean>
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.EhCacheAdapter">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref bean="internalEHCacheManager" />
</property>
<property name="cacheName">
<value>org.alfresco.cache.cachingContentStoreCache</value>
</property>
<property name="eternal" value="false"/>
<property name="timeToLive" value="0"/>
<property name="timeToIdle" value="0"/>
<property name="maxElementsInMemory" value="12"/>
<property name="maxElementsOnDisk" value="0"/>
<property name="overflowToDisk" value="false"/>
<property name="diskPersistent" value="false"/>
</bean>
</property>
<bean id="cachingContentStoreCache" class="org.alfresco.repo.cache.DefaultSimpleCache">
<property name="maxItems" value="12"/>
</bean>

View File

@@ -1,22 +0,0 @@
<?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="messengerFactory" class="org.alfresco.repo.cluster.HazelcastMessengerFactory">
<property name="hazelcastInstanceFactory" ref="hazelcastInstanceFactory"/>
</bean>
<bean id="hazelcastConfig" class="org.alfresco.repo.cluster.HazelcastConfigFactoryBean">
<property name="configFile" value="classpath:alfresco/hazelcast/hazelcast-udp.xml"/>
<property name="properties">
<props>
<prop key="alfresco.cluster.name">test_hazelcast_cluster</prop>
<prop key="alfresco.hazelcast.password">test_hazelcast_cluster_password</prop>
</props>
</property>
</bean>
<bean id="hazelcastInstanceFactory" class="org.alfresco.repo.cluster.HazelcastInstanceFactory">
<property name="config" ref="hazelcastConfig"/>
</bean>
</beans>

View File

@@ -1,166 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This configuration is used to test the functionality of the HazelcastConfigFactoryBean.
-->
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-basic.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<name>${alfresco.cluster.name}</name>
<password>${alfresco.hazelcast.password}</password>
</group>
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="false">
<interface>127.0.0.1</interface>
</tcp-ip>
<aws enabled="false">
<access-key>my-access-key</access-key>
<secret-key>my-secret-key</secret-key>
<!--optional, default is us-east-1 -->
<region>us-west-1</region>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-name>hazelcast-sg</security-group-name>
<tag-key>type</tag-key>
<tag-value>hz-nodes</tag-value>
</aws>
</join>
<interfaces enabled="false">
<interface>10.10.1.*</interface>
</interfaces>
<symmetric-encryption enabled="false">
<!--
encryption algorithm such as
DES/ECB/PKCS5Padding,
PBEWithMD5AndDES,
AES/CBC/PKCS5Padding,
Blowfish,
DESede
-->
<algorithm>PBEWithMD5AndDES</algorithm>
<!-- salt value to use when generating the secret key -->
<salt>thesalt</salt>
<!-- pass phrase to use when generating the secret key -->
<password>thepass</password>
<!-- iteration count to use when generating the secret key -->
<iteration-count>19</iteration-count>
</symmetric-encryption>
<asymmetric-encryption enabled="false">
<!-- encryption algorithm -->
<algorithm>RSA/NONE/PKCS1PADDING</algorithm>
<!-- private key password -->
<keyPassword>thekeypass</keyPassword>
<!-- private key alias -->
<keyAlias>local</keyAlias>
<!-- key store type -->
<storeType>JKS</storeType>
<!-- key store password -->
<storePassword>thestorepass</storePassword>
<!-- path to the key store -->
<storePath>keystore</storePath>
</asymmetric-encryption>
</network>
<executor-service>
<core-pool-size>16</core-pool-size>
<max-pool-size>64</max-pool-size>
<keep-alive-seconds>60</keep-alive-seconds>
</executor-service>
<queue name="default">
<!--
Maximum size of the queue. When a JVM's local queue size reaches the maximum,
all put/offer operations will get blocked until the queue size
of the JVM goes down below the maximum.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size-per-jvm>0</max-size-per-jvm>
<!--
Name of the map configuration that will be used for the backing distributed
map for this queue.
-->
<backing-map-ref>default</backing-map-ref>
</queue>
<map name="default">
<!--
Number of backups. If 1 is set as the backup-count for example,
then all entries of the map will be copied to another JVM for
fail-safety. 0 means no backup.
-->
<backup-count>1</backup-count>
<!--
Maximum number of seconds for each entry to stay in the map. Entries that are
older than <time-to-live-seconds> and not updated for <time-to-live-seconds>
will get automatically evicted from the map.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<time-to-live-seconds>0</time-to-live-seconds>
<!--
Maximum number of seconds for each entry to stay idle in the map. Entries that are
idle(not touched) for more than <max-idle-seconds> will get
automatically evicted from the map. Entry is touched if get, put or containsKey is called.
Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. Default is 0.
-->
<max-idle-seconds>0</max-idle-seconds>
<!--
Valid values are:
NONE (no eviction),
LRU (Least Recently Used),
LFU (Least Frequently Used).
NONE is the default.
-->
<eviction-policy>NONE</eviction-policy>
<!--
Maximum size of the map. When max size is reached,
map is evicted based on the policy defined.
Any integer between 0 and Integer.MAX_VALUE. 0 means
Integer.MAX_VALUE. Default is 0.
-->
<max-size policy="cluster_wide_map_size">0</max-size>
<!--
When max. size is reached, specified percentage of
the map will be evicted. Any integer between 0 and 100.
If 25 is set for example, 25% of the entries will
get evicted.
-->
<eviction-percentage>25</eviction-percentage>
<!--
While recovering from split-brain (network partitioning),
map entries in the small cluster will merge into the bigger cluster
based on the policy set here. When an entry merge into the
cluster, there might an existing entry with the same key already.
Values of these entries might be different for that same key.
Which value should be set for the key? Conflict is resolved by
the policy set here. Default policy is hz.ADD_NEW_ENTRY
There are built-in merge policies such as
hz.NO_MERGE ; no entry will merge.
hz.ADD_NEW_ENTRY ; entry will be added if the merging entry's key
doesn't exist in the cluster.
hz.HIGHER_HITS ; entry with the higher hits wins.
hz.LATEST_UPDATE ; entry with the latest update wins.
-->
<merge-policy>hz.ADD_NEW_ENTRY</merge-policy>
</map>
<!-- Add your own semaphore configurations here:
<semaphore name="default">
<initial-permits>10</initial-permits>
<semaphore-factory enabled="true">
<class-name>com.acme.MySemaphoreFactory</class-name>
</semaphore-factory>
</semaphore>
-->
<!-- Add your own map merge policy implementations here:
<merge-policies>
<map-merge-policy name="MY_MERGE_POLICY">
<class-name>com.acme.MyOwnMergePolicy</class-name>
</map-merge-policy>
</merge-policies>
-->
</hazelcast>

View File

@@ -11,7 +11,7 @@ hibernate.jdbc.use_streams_for_binary=true
hibernate.show_sql=false
hibernate.cache.use_query_cache=false
hibernate.max_fetch_depth=10
hibernate.cache.provider_class=org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean
hibernate.cache.provider_class=org.alfresco.repo.cache.DefaultCacheProvider
hibernate.cache.use_second_level_cache=true
hibernate.default_batch_fetch_size=1
hibernate.jdbc.batch_size=32

View File

@@ -1,48 +0,0 @@
<ehcache>
<!-- Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path
<diskStore path="java.io.tmpdir"/> -->
<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.
The following attributes are required:
maxElementsInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the
element is never expired.
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
The following attributes are optional:
timeToIdleSeconds - Sets the time to idle for an element before it expires.
i.e. The maximum amount of time between accesses before an element expires
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that an Element can idle for infinity.
The default value is 0.
timeToLiveSeconds - Sets the time to live for an element before it expires.
i.e. The maximum time between creation time and when an element expires.
Is only used if the element is not eternal.
Optional attribute. A value of 0 means that and Element can live for infinity.
The default value is 0.
diskPersistent - Whether the disk store persists between restarts of the Virtual Machine.
The default value is false.
diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
is 120 seconds.
-->
<defaultCache
maxElementsInMemory="100000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
/>
</ehcache>