Commit ee161a0b authored by Misagh Moayyed's avatar Misagh Moayyed
Browse files

Merge pull request #1163 from Unicon/registry-config

Auto configuration of memcached, hazelcast and ehcache registries
parents 58552eac f5743c89
......@@ -16,138 +16,52 @@ Ehcache integration is enabled by including the following dependency in the Mave
`EhCacheTicketRegistry` stores tickets in an [Ehcache](http://ehcache.org/) instance.
We present two configurations:
1. Single instance memory-backed cache with disk overflow for simple cases.
2. Distributed cache with peer replication over RMI for HA deployments.
## Memory Cache with Disk Overflow
The following Spring configuration provides a template for `ticketRegistry.xml`.
{% highlight xml %}
<bean id="ticketRegistry"
class="org.jasig.cas.ticket.registry.EhCacheTicketRegistry"
p:serviceTicketsCache-ref="serviceTicketsCache"
p:ticketGrantingTicketsCache-ref="ticketGrantingTicketsCache" />
<bean id="abstractTicketCache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:diskExpiryThreadIntervalSeconds="0"
p:diskPersistent="false"
p:eternal="false"
p:maxElementsInMemory="10000"
p:maxElementsOnDisk="20000"
p:memoryStoreEvictionPolicy="LRU"
p:overflowToDisk="true" />
<bean id="serviceTicketsCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
parent="abstractTicketCache"
p:cacheName="cas_st"
p:timeToIdle="0"
p:timeToLive="300" />
<bean id="ticketGrantingTicketsCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheName="cas_tgt"
parent="abstractTicketCache"
p:timeToIdle="0"
p:timeToLive="7201" />
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache-failsafe.xml"
p:shared="false"
p:cacheManagerName="ticketRegistryCacheManager" />
{% endhighlight %}
The Ehcache configuration file `ehcache-failsafe.xml` mentioned in the Spring configuration above:
{% highlight xml %}
<ehcache updateCheck="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir/cas"/>
</ehcache>
{% endhighlight %}
## Distributed Cache
Distributed caches are recommended for HA architectures since they offer fault tolerance in the ticket storage subsystem. The registry maintains service tickets and ticket-granting tickets in two separate caches, so that:
Distributed caches are recommended for HA architectures since they offer fault tolerance in the ticket storage
subsystem. The registry maintains service tickets and ticket-granting tickets in two separate caches, so that:
* Ticket Granting Tickets remain valid for a long time, replicated asynchronously
* Service Tickets are short lived and must be replicated right away because the requests to validate them may very likely arrive at different CAS cluster nodes
* Service Tickets are short lived and must be replicated right away because the requests
to validate them may very likely arrive at different CAS cluster nodes
###RMI Replication
Ehcache supports [RMI](http://docs.oracle.com/javase/6/docs/technotes/guides/rmi/index.html) replication for distributed caches composed of two or more nodes. To learn more about RMI replication with Ehcache, [see this resource](http://ehcache.org/documentation/user-guide/rmi-replicated-caching).
####Spring configuration template for `ticketRegistry.xml`.
{% highlight xml %}
<bean id="ticketRegistry"
class="org.jasig.cas.ticket.registry.EhCacheTicketRegistry"
p:serviceTicketsCache-ref="serviceTicketsCache"
p:ticketGrantingTicketsCache-ref="ticketGrantingTicketsCache" />
<bean id="abstractTicketCache" abstract="true"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManager"
p:diskExpiryThreadIntervalSeconds="0"
p:diskPersistent="false"
p:eternal="false"
p:maxElementsInMemory="10000"
p:maxElementsOnDisk="20000"
p:memoryStoreEvictionPolicy="LRU"
p:overflowToDisk="true"
p:bootstrapCacheLoader-ref="ticketCacheBootstrapCacheLoader" />
<!-- MUST use synchronous repl for service tickets for correct behavior. -->
<bean id="serviceTicketsCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
parent="abstractTicketCache"
p:cacheName="cas_st"
p:timeToIdle="0"
p:timeToLive="300"
p:cacheEventListeners-ref="ticketRMISynchronousCacheReplicator" />
<bean id="ticketGrantingTicketsCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean"
parent="abstractTicketCache"
p:cacheName="cas_tgt"
p:timeToIdle="0"
p:timeToLive="7201"
p:cacheEventListeners-ref="ticketRMIAsynchronousCacheReplicator" />
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache-replicated.xml"
p:shared="false"
p:cacheManagerName="ticketRegistryCacheManager" />
<bean id="ticketRMISynchronousCacheReplicator"
class="net.sf.ehcache.distribution.RMISynchronousCacheReplicator"
c:replicatePuts="true"
c:replicatePutsViaCopy="true"
c:replicateUpdates="true"
c:replicateUpdatesViaCopy="true"
c:replicateRemovals="true" />
<bean id="ticketRMIAsynchronousCacheReplicator"
class="net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator"
parent="ticketRMISynchronousCacheReplicator"
c:replicationInterval="10000"
c:maximumBatchSize="100" />
<bean id="ticketCacheBootstrapCacheLoader"
class="net.sf.ehcache.distribution.RMIBootstrapCacheLoader"
c:asynchronous="true"
c:maximumChunkSize="5000000" />
Ehcache supports [RMI](http://docs.oracle.com/javase/6/docs/technotes/guides/rmi/index.html)
replication for distributed caches composed of two or more nodes. To learn more about RMI
replication with Ehcache, [see this resource](http://ehcache.org/documentation/user-guide/rmi-replicated-caching).
####Configuration
{% highlight properties %}
# ehcache.config.file=classpath:ehcache-replicated.xml
# ehcache.cachemanager.shared=false
# ehcache.cachemanager.name=ticketRegistryCacheManager
# ehcache.disk.expiry.interval.seconds=0
# ehcache.disk.persistent=false
# ehcache.eternal=false
# ehcache.max.elements.memory=10000
# ehcache.max.elements.disk=0
# ehcache.eviction.policy=LRU
# ehcache.overflow.disk=false
# ehcache.cache.st.name=org.jasig.cas.ticket.ServiceTicket
# ehcache.cache.st.timeIdle=0
# ehcache.cache.st.timeAlive=300
# ehcache.cache.tgt.name=org.jasig.cas.ticket.TicketGrantingTicket
# ehcache.cache.tgt.timeIdle=7201
# ehcache.cache.tgt.timeAlive=0
# ehcache.cache.loader.async=true
# ehcache.cache.loader.chunksize=5000000
# ehcache.repl.async.interval=10000
# ehcache.repl.async.batch.size=100
# ehcache.repl.sync.puts=true
# ehcache.repl.sync.putscopy=true
# ehcache.repl.sync.updates=true
# ehcache.repl.sync.updatesCopy=true
# ehcache.repl.sync.removals=true
{% endhighlight %}
The Ehcache configuration for `ehcache-replicated.xml` mentioned in the Spring config follows.
The Ehcache configuration for `ehcache-replicated.xml` mentioned in the config follows.
{% highlight xml %}
<ehcache name="ehCacheTicketRegistryCache"
updateCheck="false"
......@@ -182,96 +96,33 @@ The Ehcache configuration for `ehcache-replicated.xml` mentioned in the Spring c
</ehcache>
{% endhighlight %}
Use either manual or automatic peer discovery to assemble members of distributed cache. If manual discover is used
for configuration, the file would vary according to the node on which CAS is deployed. For that reason it may be
helpful to place the configuration file on the filesystem at a well-known location and reference it in the
`EhCacheManagerFactoryBean` above as follows:
{% highlight xml %}
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="file:/path/to/well-known/ehcache-replicated.xml"
p:shared="false"
p:cacheManagerName="ticketRegistryCacheManager" />
{% endhighlight %}
###JGroups Replication
[JGroups](http://ehcache.org/documentation/2.5/replication/jgroups-replicated-caching) can be used as the underlying mechanism for the replication operations in Ehcache. JGroups offers a very flexible protocol stack, reliable unicast, and multicast message transmission. On the down side JGroups can be complex to configure and some protocol stacks have dependencies on others.
####Spring configuration template for `ticketRegistry.xml`.
The configuration is similar to above, except that ticket replicators and cache loaders need to be swapped out for their JGroups counterpart:
{% highlight xml %}
...
<bean id="ticketjgroupsSynchronousCacheReplicator" class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicator">
<constructor-arg name="replicatePuts" value="true"/>
<constructor-arg name="replicateUpdates" value="true"/>
<constructor-arg name="replicateUpdatesViaCopy" value="true"/>
<constructor-arg name="replicateRemovals" value="true"/>
</bean>
<bean id="ticketjgroupsAsynchronousCacheReplicator" class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicator" parent="ticketjgroupsSynchronousCacheReplicator">
<constructor-arg name="asynchronousReplicationInterval" value="1000"/>
</bean>
<bean id="ticketCacheBootstrapCacheLoader" class="net.sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoader">
<constructor-arg name="asynchronous" value="true"/>
<constructor-arg name="maximumChunkSize" value="5000000"/>
</bean>
...
{% endhighlight %}
The Ehcache JGroups confguration itself needs to be altered to be similar to the following:
{% highlight xml %}
<ehcache name="ehCacheTicketRegistryCache"
updateCheck="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.sf.net/ehcache.xsd">
<diskStore path="java.io.tmpdir/cas"/>
<!-- Using UDP multicast stack -->
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;):PING:
MERGE2:FD_SOCK:VERIFY_SUSPECT:pbcast.NAKACK:UNICAST:pbcast.STABLE:FRAG:pbcast.GMS"
propertySeparator="::"
/>
</ehcache>
{% endhighlight %}
Your maven overlay `pom.xml` will also need to declare the following dependencies:
{% highlight xml %}
<dependency>
<groupId>org.jgroups</groupId>
<artifactId>jgroups</artifactId>
<version>${jgroups.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-jgroupsreplication</artifactId>
<version>${ehcache-jgroups.version}</version>
</dependency>
{% endhighlight %}
###Eviction Policy
Ehcache manages the internal eviction policy of cached objects via `timeToIdle` and `timeToLive` settings. This results of having *no need* for a Ticket Registry Cleaner.
Ehcache manages the internal eviction policy of cached objects via `timeToIdle` and `timeToLive` settings.
The default CAS ticket registry cleaner is then not needed, but could be used to enable
[CAS single logout functionality](Logout-Single-Logout.html), if required.
There have been reports of cache eviction problems when tickets are expired, but haven't been removed from the cache due to ehache configuration. This can be a problem because old ticket references "hang around" in the cache despite being expired. In other words, Ehcache does [inline eviction](http://lists.terracotta.org/pipermail/ehcache-list/2011-November/000423.html) where expired objects in the cache object won't be collected from memory until the cache max size is reached or the expired entry is explicitly accessed. To reclaim memory on expired tickets, cache eviction policies are must be carefully configured to avoid memory creep. Disk offload and/or a more aggressive eviction could provide a suitable workaround.
There have been reports of cache eviction problems when tickets are expired, but haven't been
removed from the cache due to ehache configuration. This can be a problem because old ticket
references "hang around" in the cache despite being expired. In other words,
Ehcache does [inline eviction](http://lists.terracotta.org/pipermail/ehcache-list/2011-November/000423.html)
where expired objects in the cache object won't be collected from memory until the cache max size is reached
or the expired entry is explicitly accessed. To reclaim memory on expired tickets, cache eviction
policies are must be carefully configured to avoid memory creep. Disk offload and/or a more
aggressive eviction could provide a suitable workaround.
###Troubleshooting Guidelines
* You will need to ensure that network communication across CAS nodes is allowed and no firewall or other component is blocking traffic.
* You will need to ensure that network communication across CAS nodes is allowed and no firewall or other component
is blocking traffic.
* If you are running this on a server with active firewalls, you will probably need to specify a fixed `remoteObjectPort`, within the `cacheManagerPeerListenerFactory`.
* Depending on environment settings and version of Ehcache used, you may also have to adjust the `shared` setting above.
* If you are running this on a server with active firewalls, you will probably need to specify
a fixed `remoteObjectPort`, within the `cacheManagerPeerListenerFactory`.
* Depending on environment settings and version of Ehcache used, you may also have to adjust the
`shared` setting .
* Ensure that each cache manager specified a name that matches the Ehcache configuration itself.
* You may also need to adjust your expiration policy to allow for a larger time span, specially for service tickets depending on network traffic and communication delay across CAS nodes particualrly in the event that a node is trying to join the cluster.
* You may also need to adjust your expiration policy to allow for a larger time span, specially
for service tickets depending on network traffic and communication delay across CAS nodes particularly
in the event that a node is trying to join the cluster.
......@@ -21,16 +21,22 @@ This ticket registry implementation is enabled by simply including the module in
## Configuration
This implementation auto-configures most of the internal details of the underlying Hazelcast instance and the distributed `IMap` for tickets storage.
The only required configuration value on each CAS node in the cluster is a comma-separated list of *ALL* the member nodes defined in the configuration
property `hz.cluster.members` (in `cas.properties` file). For example: `hz.cluster.members=cas1.example.com,cas2.example.com`
Other optional properties that could be set are:
This implementation auto-configures most of the internal details of the underlying Hazelcast instance and
the distributed `IMap` for tickets storage.
{% highlight properties %}
# hz.cluster.portAutoIncrement=true
# hz.cluster.port=5701
# hz.cluster.multicast.enabled=false
# hz.cluster.members=cas1.example.com,cas2.example.com
# hz.cluster.tcpip.enabled=true
# hz.cluster.max.heapsize.percentage=85
# hz.cluster.max.heartbeat.seconds=5
# hz.cluster.eviction.percentage=10
# hz.cluster.eviction.policy=LRU
# hz.cluster.instance.name=${host.name}
{% endhighlight %}
* `hz.cluster.port` (default value is `5701`)
* `hz.cluster.portAutoIncrement` (default value is `true`)
* TGT time to live value for this implementation is set via `tgt.maxTimeToLiveInSeconds` and defaults to `28800`
* ST time to live value for this implementation is set via `st.timeToKillInSeconds` and defaults to `10`
## Logging
To enable additional logging for the registry, configure the log4j configuration file to add the following
......
......@@ -72,51 +72,15 @@ framework. This component is recommended over the default Java serialization mec
compact data, which benefits both storage requirements and throughput.
## Component Configuration
The following configuration is a template for `ticketRegistry.xml` Spring configuration:
{% highlight xml %}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="ticketRegistry"
class="org.jasig.cas.ticket.registry.MemCacheTicketRegistry"
c:client-ref="memcachedClient"
c:ticketGrantingTicketTimeOut="${tgt.maxTimeToLiveInSeconds}"
c:serviceTicketTimeOut="${st.timeToKillInSeconds}" />
<bean id="memcachedClient" class="net.spy.memcached.spring.MemcachedClientFactoryBean"
p:servers="${memcached.servers}"
p:protocol="${memcached.protocol}"
p:locatorType="${memcached.locatorType}"
p:failureMode="${memcached.failureMode}"
p:transcoder-ref="kryoTranscoder">
<property name="hashAlg">
<util:constant static-field="net.spy.memcached.DefaultHashAlgorithm.${memcached.hashAlgorithm}" />
</property>
</bean>
<bean id="kryoTranscoder"
class="org.jasig.cas.ticket.registry.support.kryo.KryoTranscoder"
init-method="initialize"
c:initialBufferSize="8192" />
</beans>
{% endhighlight %}
`MemCacheTicketRegistry` properties reference:
## Configuration
{% highlight properties %}
# It is common to run memcached on every CAS node
memcached.servers=cas-1.example.org:11211,cas-2.example.org:11211,cas-3.example.org:11211
memcached.hashAlgorithm=FNV1_64_HASH
memcached.protocol=BINARY
memcached.locatorType=ARRAY_MOD
memcached.failureMode=Redistribute
# memcached.servers=cas-1.example.org:11211,cas-2.example.org:11211,cas-3.example.org:11211
# memcached.hashAlgorithm=FNV1_64_HASH
# memcached.protocol=BINARY
# memcached.locatorType=ARRAY_MOD
# memcached.failureMode=Redistribute
# memcached.buffersize=8192
{% endhighlight %}
## High Availability Considerations
......
......@@ -205,6 +205,8 @@ public final class EhCacheTicketRegistry extends AbstractCrypticTicketRegistry i
@Override
public void afterPropertiesSet() throws Exception {
logger.info("Setting up Ehcache Ticket Registry...");
if (this.serviceTicketsCache == null || this.ticketGrantingTicketsCache == null) {
throw new BeanInstantiationException(this.getClass(),
"Both serviceTicketsCache and ticketGrantingTicketsCache are required properties.");
......@@ -231,7 +233,6 @@ public final class EhCacheTicketRegistry extends AbstractCrypticTicketRegistry i
}
/**
* {@inheritDoc}
* @see Cache#getKeysWithExpiryCheck()
*/
@Override
......@@ -241,7 +242,6 @@ public final class EhCacheTicketRegistry extends AbstractCrypticTicketRegistry i
}
/**
* {@inheritDoc}
* @see Cache#getKeysWithExpiryCheck()
*/
@Override
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to Apereo under one or more contributor license
agreements. See the NOTICE file distributed with this work
for additional information regarding copyright ownership.
Apereo licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a
copy of the License at the following location:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<description>
Configuration for the EhCache TicketRegistry which stores the tickets in a distributed EhCache and cleans
them out as specified intervals.
</description>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="${ehcache.config.file:classpath:ehcache-replicated.xml}"
p:shared="${ehcache.cachemanager.shared:false}"
p:cacheManagerName="${ehcache.cachemanager.name:ticketRegistryCacheManager}" />
<bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.EhCacheTicketRegistry"
p:serviceTicketsCache-ref="serviceTicketsCache"
p:ticketGrantingTicketsCache-ref="ticketGrantingTicketsCache" />
<bean id="abstractTicketCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
abstract="true">
<property name="cacheManager" ref="cacheManager" />
<property name="diskExpiryThreadIntervalSeconds" value="${ehcache.disk.expiry.interval.seconds:0}" />
<property name="diskPersistent" value="${ehcache.disk.persistent:false}" />
<property name="eternal" value="${ehcache.eternal:false}" />
<property name="maxElementsInMemory" value="${ehcache.max.elements.memory:10000}" />
<property name="maxElementsOnDisk" value="${ehcache.max.elements.disk:0}" />
<property name="memoryStoreEvictionPolicy" value="${ehcache.eviction.policy:LRU}" />
<property name="overflowToDisk" value="${ehcache.overflow.disk:false}" />
<property name="bootstrapCacheLoader">
<ref bean="ticketCacheBootstrapCacheLoader" />
</property>
</bean>
<bean id="serviceTicketsCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
parent="abstractTicketCache">
<property name="cacheName" value="${ehcache.cache.st.name:org.jasig.cas.ticket.ServiceTicket}" />
<property name="cacheEventListeners">
<ref bean="ticketRMISynchronousCacheReplicator" />
</property>
<!-- The maximum number of seconds an element can exist in the cache without being accessed. The
element expires at this limit and will no longer be returned from the cache. The default value is 0,
which means no TTI eviction takes place (infinite lifetime). -->
<property name="timeToIdle" value="${ehcache.cache.st.timeIdle:0}" />
<!-- The maximum number of seconds an element can exist in the cache regardless of use. The element
expires at this limit and will no longer be returned from the cache. The default value is 0, which means
no TTL eviction takes place (infinite lifetime). -->
<property name="timeToLive" value="${ehcache.cache.st.timeAlive:300}" />
</bean>
<bean id="ticketGrantingTicketsCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheName" value="${ehcache.cache.tgt.name:org.jasig.cas.ticket.TicketGrantingTicket}" />
<property name="cacheEventListeners">
<ref bean="ticketRMIAsynchronousCacheReplicator" />
</property>
<!-- The maximum number of seconds an element can exist in the cache regardless of use. The element
expires at this limit and will no longer be returned from the cache. The default value is 0, which means
no TTL eviction takes place (infinite lifetime). For this sample configuration, 2 hours of inactivity
before ticket granting tickets are expired automatically -->
<property name="timeToIdle" value="${ehcache.cache.tgt.timeIdle:7201}" />
<!-- The maximum number of seconds an element can exist in the cache without being accessed. The
element expires at this limit and will no longer be returned from the cache. The default value is 0,
which means no TTI eviction takes place (infinite lifetime). -->
<property name="timeToLive" value="${ehcache.cache.tgt.timeAlive:0}" />
</bean>
<bean id="ticketRMISynchronousCacheReplicator" class="net.sf.ehcache.distribution.RMISynchronousCacheReplicator">
<constructor-arg name="replicatePuts" value="${ehcache.repl.sync.puts:true}" />
<constructor-arg name="replicatePutsViaCopy" value="${ehcache.repl.sync.putscopy:true}" />
<constructor-arg name="replicateUpdates" value="${ehcache.repl.sync.updates:true}" />
<constructor-arg name="replicateUpdatesViaCopy" value="${ehcache.repl.sync.updatesCopy:true}" />
<constructor-arg name="replicateRemovals" value="${ehcache.repl.sync.removals:true}" />
</bean>
<bean id="ticketRMIAsynchronousCacheReplicator" class="net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator"
parent="ticketRMISynchronousCacheReplicator">
<constructor-arg name="replicationInterval" value="${ehcache.repl.async.interval:10000}" />
<constructor-arg name="maximumBatchSize" value="${ehcache.repl.async.batch.size:100}" />
</bean>
<bean id="ticketCacheBootstrapCacheLoader" class="net.sf.ehcache.distribution.RMIBootstrapCacheLoader">
<constructor-arg name="asynchronous" value="${ehcache.cache.loader.async:true}" />
<constructor-arg name="maximumChunkSize" value="${ehcache.cache.loader.chunksize:5000000}" />
</bean>
</beans>
......@@ -69,17 +69,13 @@ public class HazelcastTicketRegistry extends AbstractCrypticTicketRegistry imple
this.hz = hz;
}
/**
* {@inheritDoc}
*/
@Override
protected void updateTicket(final Ticket ticket) {
addTicket(ticket);
}
/**
* {@inheritDoc}
*/
@Override
protected boolean needsCallback() {
return false;
......@@ -102,9 +98,6 @@ public class HazelcastTicketRegistry extends AbstractCrypticTicketRegistry imple
logger.debug("ST timeout: [{}s]", serviceTicketTimeoutInSeconds);
}
/**
* {@inheritDoc}
*/
@Override
public void addTicket(final Ticket ticket) {
addTicket(ticket, getTimeout(ticket));
......@@ -121,9 +114,7 @@ public class HazelcastTicketRegistry extends AbstractCrypticTicketRegistry imple
this.registry.set(encTicket.getId(), encTicket, ttl, TimeUnit.SECONDS);
}
/**
* {@inheritDoc}
*/
@Override
public Ticket getTicket(final String ticketId) {
final String encTicketId = encodeTicketId(ticketId);
......@@ -131,9 +122,7 @@ public class HazelcastTicketRegistry extends AbstractCrypticTicketRegistry imple
return decodeTicket(ticket);
}
/**
* {@inheritDoc}
*/
@Override
public boolean deleteTicket(final String ticketId) {
final String encTicketId = encodeTicketId(ticketId);
......@@ -141,9 +130,6 @@ public class HazelcastTicketRegistry extends AbstractCrypticTicketRegistry imple
return this.registry.remove(encTicketId) != null;
}
/**
* {@inheritDoc}
*/
@Override
public Collection<Ticket> getTickets() {
return decodeTickets(this.registry.values());
......
......@@ -20,6 +20,8 @@
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd