SGF-404 - Enable Expiration settings and policies to be specified per application domain object using an @Expiration annotation and a custom, SDG-provided CustomExpiry instance.
(cherry picked from commit a9b7f9d8e8deca6aa198e24d441d8e77bf3247cc) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.CustomExpiry;
|
||||
import com.gemstone.gemfire.cache.ExpirationAction;
|
||||
import com.gemstone.gemfire.cache.ExpirationAttributes;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* The AnnotationBasedExpiration class is an implementation of GemFire's CustomExpiry interface that determines
|
||||
* the Time-To-Live (TTL) or Idle-Timeout (TTI) expiration policy of a Region entry by introspecting the Region
|
||||
* entry's class type and reflecting on any Region entries annotated with Spring Data GemFire's Expiration-based
|
||||
* Annotations.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.support.Expiration
|
||||
* @see org.springframework.data.gemfire.support.IdleTimeoutExpiration
|
||||
* @see org.springframework.data.gemfire.support.TimeToLiveExpiration
|
||||
* @see com.gemstone.gemfire.cache.CustomExpiry
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class AnnotationBasedExpiration<K, V> implements CustomExpiry<K, V> {
|
||||
|
||||
//private ExpirationAttributes defaultExpirationAttributes = ExpirationAttributes.DEFAULT;
|
||||
private ExpirationAttributes defaultExpirationAttributes;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the AnnotationBasedExpiration class with no default expiration policy.
|
||||
*/
|
||||
public AnnotationBasedExpiration() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the AnnotationBasedExpiration class initialized with a specific, default
|
||||
* expiration policy.
|
||||
*
|
||||
* @param defaultExpirationAttributes expiration settings used as the default expiration policy.
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
*/
|
||||
public AnnotationBasedExpiration(ExpirationAttributes defaultExpirationAttributes) {
|
||||
this.defaultExpirationAttributes = defaultExpirationAttributes;
|
||||
}
|
||||
|
||||
public static <K, V> AnnotationBasedExpiration<K, V> forIdleTimeout() {
|
||||
return forIdleTimeout(null);
|
||||
}
|
||||
|
||||
public static <K, V> AnnotationBasedExpiration<K, V> forIdleTimeout(ExpirationAttributes defaultExpirationAttributes) {
|
||||
return new AnnotationBasedExpiration<K, V>(defaultExpirationAttributes) {
|
||||
@Override protected ExpirationMetaData getExpirationMetaData(final Region.Entry<K, V> entry) {
|
||||
return (isIdleTimeoutConfigured(entry) ? ExpirationMetaData.from(getIdleTimeout(entry))
|
||||
: super.getExpirationMetaData(entry));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <K, V> AnnotationBasedExpiration<K, V> forTimeToLive() {
|
||||
return forTimeToLive(null);
|
||||
}
|
||||
|
||||
public static <K, V> AnnotationBasedExpiration<K, V> forTimeToLive(ExpirationAttributes defaultExpirationAttributes) {
|
||||
return new AnnotationBasedExpiration<K, V>(defaultExpirationAttributes) {
|
||||
@Override protected ExpirationMetaData getExpirationMetaData(final Region.Entry<K, V> entry) {
|
||||
return (isTimeToLiveConfigured(entry) ? ExpirationMetaData.from(getTimeToLive(entry))
|
||||
: super.getExpirationMetaData(entry));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the expiration policy to use by default when no application domain object specific expiration meta-data
|
||||
* has been specified.
|
||||
*
|
||||
* @param defaultExpirationAttributes expiration settings used as the default expiration policy.
|
||||
* @see #getDefaultExpirationAttributes()
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
*/
|
||||
public void setDefaultExpirationAttributes(ExpirationAttributes defaultExpirationAttributes) {
|
||||
this.defaultExpirationAttributes = defaultExpirationAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expiration policy used by default when no application domain object specific expiration meta-data
|
||||
* has been specified.
|
||||
*
|
||||
* @return an instance of ExpirationAttributes with expiration settings defining the default expiration policy.
|
||||
* @see #setDefaultExpirationAttributes(com.gemstone.gemfire.cache.ExpirationAttributes)
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
*/
|
||||
protected ExpirationAttributes getDefaultExpirationAttributes() {
|
||||
//return (defaultExpirationAttributes != null ? defaultExpirationAttributes : ExpirationAttributes.DEFAULT);
|
||||
return defaultExpirationAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the expiration for a given entry. Returning null indicates that the default for the Region
|
||||
* should be used. The entry parameter should not be used after this method invocation completes.
|
||||
*
|
||||
* @param entry the entry to calculate the expiration for.
|
||||
* @return the expiration to be used, null if the Region's defaults should be used.
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
*/
|
||||
@Override
|
||||
public ExpirationAttributes getExpiry(Region.Entry<K, V> entry) {
|
||||
return newExpirationAttributes(getExpirationMetaData(entry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom expiration (Annotation-based) meta-data for the given Region entry.
|
||||
*
|
||||
* @param entry the Region entry used as the source of the expiration meta-data.
|
||||
* @return ExpirationMetaData extracted from the Region entry.
|
||||
* @throws NullPointerException if the Region.Entry, Region or the Region's attributes are null.
|
||||
* @see org.springframework.data.gemfire.support.AnnotationBasedExpiration.ExpirationMetaData
|
||||
*/
|
||||
protected ExpirationMetaData getExpirationMetaData(Region.Entry<K, V> entry) {
|
||||
return (isExpirationConfigured(entry) ? ExpirationMetaData.from(getExpiration(entry)) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of ExpirationAttributes configured with the application domain object specific
|
||||
* expiration policy. If the application domain object type has not been annotated with custom expiration
|
||||
* meta-data, then the default expiration settings are used.
|
||||
*
|
||||
* @param expirationMetaData application domain object specific expiration policy meta-data used to construct
|
||||
* the ExpirationAttributes.
|
||||
* @return a custom ExpirationAttributes configured with the application domain object specific expiration policy
|
||||
* or the default expiration settings if the application domain object has not been annotated with custom
|
||||
* expiration meta-data.
|
||||
* @see org.springframework.data.gemfire.support.AnnotationBasedExpiration.ExpirationMetaData
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
* @see #getDefaultExpirationAttributes()
|
||||
*/
|
||||
protected ExpirationAttributes newExpirationAttributes(ExpirationMetaData expirationMetaData) {
|
||||
return (expirationMetaData != null ? expirationMetaData.toExpirationAttributes()
|
||||
: getDefaultExpirationAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the Region Entry has been annotated with the Expiration Annotation.
|
||||
*
|
||||
* @param entry the Region.Entry to evaluate for the presence of the Expiration Annotation.
|
||||
* @return a boolean value indicating whether the Region Entry has been annotated with @Expiration.
|
||||
* @see org.springframework.data.gemfire.support.Expiration
|
||||
* @see #isAnnotationPresent(Object, Class)
|
||||
*/
|
||||
protected boolean isExpirationConfigured(Region.Entry<K, V> entry) {
|
||||
return isAnnotationPresent(entry.getValue(), Expiration.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Expiration Annotation meta-data from the Region Entry.
|
||||
*
|
||||
* @param entry the Region.Entry from which to extract the Expiration Annotation meta-data.
|
||||
* @return the Expiration Annotation meta-data for the given Region Entry or {@code null}
|
||||
* if the Region Entry has not been annotated with @Expiration.
|
||||
* @see org.springframework.data.gemfire.support.Expiration
|
||||
* @see #getAnnotation(Object, Class)
|
||||
*/
|
||||
protected Expiration getExpiration(Region.Entry<K, V> entry) {
|
||||
return getAnnotation(entry.getValue(), Expiration.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the Region Entry has been annotated with the IdleTimeoutExpiration Annotation.
|
||||
*
|
||||
* @param entry the Region.Entry to evaluate for the presence of the IdleTimeoutExpiration Annotation.
|
||||
* @return a boolean value indicating whether the Region Entry has been annotated with @IdleTimeoutExpiration.
|
||||
* @see org.springframework.data.gemfire.support.IdleTimeoutExpiration
|
||||
* @see #isAnnotationPresent(Object, Class)
|
||||
*/
|
||||
protected boolean isIdleTimeoutConfigured(Region.Entry<K, V> entry) {
|
||||
return isAnnotationPresent(entry.getValue(), IdleTimeoutExpiration.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the IdleTimeoutExpiration Annotation meta-data from the Region Entry.
|
||||
*
|
||||
* @param entry the Region.Entry from which to extract the IdleTimeoutExpiration Annotation meta-data.
|
||||
* @return the IdleTimeoutExpiration Annotation meta-data for the given Region Entry or {@code null}
|
||||
* if the Region Entry has not been annotated with @IdleTimeoutExpiration.
|
||||
* @see org.springframework.data.gemfire.support.IdleTimeoutExpiration
|
||||
* @see #getAnnotation(Object, Class)
|
||||
*/
|
||||
protected IdleTimeoutExpiration getIdleTimeout(Region.Entry<K, V> entry) {
|
||||
return getAnnotation(entry.getValue(), IdleTimeoutExpiration.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the Region Entry has been annotated with the TimeToLiveExpiration Annotation.
|
||||
*
|
||||
* @param entry the Region.Entry to evaluate for the presence of the TimeToLiveExpiration Annotation.
|
||||
* @return a boolean value indicating whether the Region Entry has been annotated with @TimeToLiveExpiration.
|
||||
* @see org.springframework.data.gemfire.support.TimeToLiveExpiration
|
||||
* @see #isAnnotationPresent(Object, Class)
|
||||
*/
|
||||
protected boolean isTimeToLiveConfigured(Region.Entry<K, V> entry) {
|
||||
return isAnnotationPresent(entry.getValue(), TimeToLiveExpiration.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TimeToLiveExpiration Annotation meta-data from the Region Entry.
|
||||
*
|
||||
* @param entry the Region.Entry from which to extract the TimeToLiveExpiration Annotation meta-data.
|
||||
* @return the TimeToLiveExpiration Annotation meta-data for the given Region Entry or {@code null}
|
||||
* if the Region Entry has not been annotated with @TimeToLiveExpiration.
|
||||
* @see org.springframework.data.gemfire.support.TimeToLiveExpiration
|
||||
* @see #getAnnotation(Object, Class)
|
||||
*/
|
||||
protected TimeToLiveExpiration getTimeToLive(Region.Entry<K, V> entry) {
|
||||
return getAnnotation(entry.getValue(), TimeToLiveExpiration.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private <T extends Annotation> boolean isAnnotationPresent(Object obj, Class<T> annotationType) {
|
||||
return (obj != null && obj.getClass().isAnnotationPresent(annotationType));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private <T extends Annotation> T getAnnotation(Object obj, Class<T> annotationType) {
|
||||
return AnnotationUtils.getAnnotation(obj.getClass(), annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Region containing this callback is closed or destroyed, when the Cache is closed,
|
||||
* or when a callback is removed from a Region using an AttributesMutator.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The ExpirationMetaData class encapsulates the settings constituting the expiration policy including
|
||||
* the expiration timeout and the action performed when expiration occurs.
|
||||
*
|
||||
* @see com.gemstone.gemfire.cache.ExpirationAttributes
|
||||
*/
|
||||
protected static class ExpirationMetaData {
|
||||
|
||||
private final int timeout;
|
||||
|
||||
private final ExpirationActionType expirationAction;
|
||||
|
||||
protected ExpirationMetaData(final int timeout, final ExpirationActionType expirationAction) {
|
||||
this.timeout = timeout;
|
||||
this.expirationAction = expirationAction;
|
||||
}
|
||||
|
||||
protected static ExpirationMetaData from(ExpirationAttributes expirationAttributes) {
|
||||
return new ExpirationMetaData(expirationAttributes.getTimeout(), ExpirationActionType.valueOf(
|
||||
expirationAttributes.getAction()));
|
||||
}
|
||||
|
||||
protected static ExpirationMetaData from(Expiration expiration) {
|
||||
return new ExpirationMetaData(expiration.timeout(), expiration.action());
|
||||
}
|
||||
|
||||
protected static ExpirationMetaData from(IdleTimeoutExpiration expiration) {
|
||||
return new ExpirationMetaData(expiration.timeout(), expiration.action());
|
||||
}
|
||||
|
||||
protected static ExpirationMetaData from(TimeToLiveExpiration expiration) {
|
||||
return new ExpirationMetaData(expiration.timeout(), expiration.action());
|
||||
}
|
||||
|
||||
public ExpirationAttributes toExpirationAttributes() {
|
||||
return new ExpirationAttributes(timeout(), expirationAction());
|
||||
}
|
||||
|
||||
public ExpirationActionType action() {
|
||||
return expirationAction;
|
||||
}
|
||||
|
||||
public ExpirationAction expirationAction() {
|
||||
return action().getExpirationAction();
|
||||
}
|
||||
|
||||
public int timeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof ExpirationMetaData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExpirationMetaData that = (ExpirationMetaData) obj;
|
||||
|
||||
return (this.timeout() == that.timeout()
|
||||
&& ObjectUtils.nullSafeEquals(this.action(), that.action()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashValue = 17;
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(timeout());
|
||||
hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(action());
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("{ @type = %1$s, timeout = %2$d, action = %3$s }", getClass().getName(),
|
||||
timeout(), action());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
|
||||
/**
|
||||
* Expiration is an enumerated type encapsulating custom expiration settings for application domain objects
|
||||
* to express their general expiration policy.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.ExpirationActionType
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
|
||||
public @interface Expiration {
|
||||
|
||||
ExpirationActionType action() default ExpirationActionType.INVALIDATE;
|
||||
|
||||
int timeout() default 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
|
||||
/**
|
||||
* IdleTimeoutExpiration is an enumerated type encapsulating custom expiration settings for application domain objects
|
||||
* to express their idle-timeout (TTI) expiration policy.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.ExpirationActionType
|
||||
* @see org.springframework.data.gemfire.support.Expiration
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
|
||||
@SuppressWarnings("unused")
|
||||
public @interface IdleTimeoutExpiration {
|
||||
|
||||
ExpirationActionType action() default ExpirationActionType.INVALIDATE;
|
||||
|
||||
int timeout() default 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
|
||||
/**
|
||||
* TimeToLiveExpiration is an enumerated type encapsulating custom expiration settings for application domain objects
|
||||
* to express their time-to-live (TTL) expiration policy.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.ExpirationActionType
|
||||
* @see org.springframework.data.gemfire.support.Expiration
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
|
||||
@SuppressWarnings("unused")
|
||||
public @interface TimeToLiveExpiration {
|
||||
|
||||
ExpirationActionType action() default ExpirationActionType.INVALIDATE;
|
||||
|
||||
int timeout() default 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.CustomExpiry;
|
||||
import com.gemstone.gemfire.cache.ExpirationAction;
|
||||
import com.gemstone.gemfire.cache.ExpirationAttributes;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* The AnnotationBasedExpirationConfigurationIntegrationTest class is a test suite of test cases testing
|
||||
* the configuration of Annotation-defined expiration policies on Region Entry TTL and TTI
|
||||
* custom expiration settings.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.support.AnnotationBasedExpiration
|
||||
* @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(initializers = GemfireTestApplicationContextInitializer.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class AnnotationBasedExpirationConfigurationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("ttiExpiration")
|
||||
private AnnotationBasedExpiration<Object, Object> idleTimeoutExpiration;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("ttlExpiration")
|
||||
private AnnotationBasedExpiration<Object, Object> timeToLiveExpiration;
|
||||
|
||||
@Autowired
|
||||
private ExpirationAttributes defaultExpirationAttributes;
|
||||
|
||||
@Resource(name = "Example")
|
||||
private Region<Object, Object> example;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
assertThat(example, is(not(nullValue())));
|
||||
assertThat(example.getName(), is(equalTo("Example")));
|
||||
assertThat(example.getFullPath(), is(equalTo(String.format("%1$s%2$s", Region.SEPARATOR, "Example"))));
|
||||
assertThat(example.getAttributes(), is(not(nullValue())));
|
||||
assertThat(defaultExpirationAttributes, is(not(nullValue())));
|
||||
assertThat(defaultExpirationAttributes.getTimeout(), is(equalTo(600)));
|
||||
assertThat(defaultExpirationAttributes.getAction(), is(equalTo(ExpirationAction.DESTROY)));
|
||||
assertThat(idleTimeoutExpiration, is(instanceOf(CustomExpiry.class)));
|
||||
assertThat(idleTimeoutExpiration.getDefaultExpirationAttributes(), is(nullValue()));
|
||||
assertThat(timeToLiveExpiration, is(instanceOf(CustomExpiry.class)));
|
||||
assertThat(timeToLiveExpiration.getDefaultExpirationAttributes(), is(sameInstance(defaultExpirationAttributes)));
|
||||
}
|
||||
|
||||
protected void assertExpiration(ExpirationAttributes expected, ExpirationAttributes actual) {
|
||||
assertExpiration(actual, expected.getTimeout(), expected.getAction());
|
||||
}
|
||||
|
||||
protected void assertExpiration(ExpirationAttributes expirationAttributes, int expectedTimeout,
|
||||
ExpirationAction expectedAction) {
|
||||
|
||||
assertThat(expirationAttributes, is(not(nullValue())));
|
||||
assertThat(expirationAttributes.getTimeout(), is(equalTo(expectedTimeout)));
|
||||
assertThat(expirationAttributes.getAction(), is(equalTo(expectedAction)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Region.Entry<Object, Object> mockRegionEntry(Object value) {
|
||||
Region.Entry<Object, Object> mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(value);
|
||||
|
||||
return mockRegionEntry;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exampleRegionIdleTimeoutExpirationPolicy() {
|
||||
CustomExpiry<Object, Object> expiration = example.getAttributes().getCustomEntryIdleTimeout();
|
||||
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithIdleTimeoutExpirationPolicy())), 120, ExpirationAction.INVALIDATE);
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithTimeToLiveGenericExpirationPolicies())), 60, ExpirationAction.INVALIDATE);
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithGenericExpirationPolicy())), 60, ExpirationAction.DESTROY);
|
||||
assertThat(expiration.getExpiry(mockRegionEntry(new ApplicationDomainObjectWithNoExpirationPolicy())),
|
||||
is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exampleRegionTimeToLiveExpirationPolicy() {
|
||||
CustomExpiry<Object, Object> expiration = example.getAttributes().getCustomEntryTimeToLive();
|
||||
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithTimeToLiveGenericExpirationPolicies())), 300, ExpirationAction.DESTROY);
|
||||
assertExpiration(defaultExpirationAttributes, expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithIdleTimeoutExpirationPolicy())));
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithGenericExpirationPolicy())), 60, ExpirationAction.DESTROY);
|
||||
assertExpiration(defaultExpirationAttributes, expiration.getExpiry(mockRegionEntry(
|
||||
new ApplicationDomainObjectWithNoExpirationPolicy())));
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.INVALIDATE)
|
||||
@TimeToLiveExpiration(timeout = 300, action = ExpirationActionType.DESTROY)
|
||||
protected static class ApplicationDomainObjectWithTimeToLiveGenericExpirationPolicies {
|
||||
}
|
||||
|
||||
@IdleTimeoutExpiration(timeout = 120, action = ExpirationActionType.INVALIDATE)
|
||||
protected static class ApplicationDomainObjectWithIdleTimeoutExpirationPolicy {
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.DESTROY)
|
||||
protected static class ApplicationDomainObjectWithGenericExpirationPolicy {
|
||||
}
|
||||
|
||||
protected static class ApplicationDomainObjectWithNoExpirationPolicy {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.isA;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.support.AnnotationBasedExpiration.ExpirationMetaData;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.ExpirationActionType;
|
||||
|
||||
import com.gemstone.gemfire.cache.ExpirationAction;
|
||||
import com.gemstone.gemfire.cache.ExpirationAttributes;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* The AnnotationBasedExpirationTest class is a test suite of test cases testing the contract and functionality
|
||||
* of the AnnotationBasedExpirationTest.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.support.AnnotationBasedExpiration
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
|
||||
public class AnnotationBasedExpirationTest {
|
||||
|
||||
private AnnotationBasedExpiration noDefaultExpiration = new AnnotationBasedExpiration();
|
||||
|
||||
protected void assertExpiration(ExpirationAttributes expirationAttributes, int expectedTimeout,
|
||||
ExpirationAction expectedAction) {
|
||||
|
||||
assertThat(expirationAttributes, is(not(nullValue())));
|
||||
assertThat(expirationAttributes.getTimeout(), is(equalTo(expectedTimeout)));
|
||||
assertThat(expirationAttributes.getAction(), is(equalTo(expectedAction)));
|
||||
}
|
||||
|
||||
protected void assertExpiration(ExpirationMetaData expirationMetaData, int expectedTimeout,
|
||||
ExpirationActionType expectedExpirationAction) {
|
||||
|
||||
assertThat(expirationMetaData, is(not(nullValue())));
|
||||
assertThat(expirationMetaData.timeout(), is(equalTo(expectedTimeout)));
|
||||
assertThat(expirationMetaData.action(), is(equalTo(expectedExpirationAction)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructUninitializedAnnotationBasedExpirationInstance() {
|
||||
AnnotationBasedExpiration expiration = new AnnotationBasedExpiration();
|
||||
|
||||
assertThat(expiration.getDefaultExpirationAttributes(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructInitializedAnnotationBasedExpirationInstance() {
|
||||
AnnotationBasedExpiration expiration = new AnnotationBasedExpiration(ExpirationAttributes.DEFAULT);
|
||||
|
||||
assertThat(expiration.getDefaultExpirationAttributes(), is(equalTo(ExpirationAttributes.DEFAULT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forIdleTimeoutNoDefaultExpiration() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
AnnotationBasedExpiration expiration = AnnotationBasedExpiration.forIdleTimeout();
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 120, ExpirationAction.LOCAL_INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveGenericExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 60, ExpirationAction.INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(expiration.getExpiry(mockRegionEntry), is(nullValue()));
|
||||
verify(mockRegionEntry, atLeast(3)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forIdleTimeoutWithDefaultExpiration() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
ExpirationAttributes defaultExpiration = new ExpirationAttributes(300, ExpirationAction.DESTROY);
|
||||
|
||||
AnnotationBasedExpiration expiration = AnnotationBasedExpiration.forIdleTimeout(defaultExpiration);
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 120, ExpirationAction.LOCAL_INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveGenericExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 60, ExpirationAction.INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(expiration.getExpiry(mockRegionEntry), is(equalTo(defaultExpiration)));
|
||||
verify(mockRegionEntry, atLeast(3)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forTimeToLiveNoDefaultExpiration() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
AnnotationBasedExpiration expiration = AnnotationBasedExpiration.forTimeToLive();
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 300, ExpirationAction.LOCAL_DESTROY);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutGenericExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 60, ExpirationAction.INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(expiration.getExpiry(mockRegionEntry), is(nullValue()));
|
||||
verify(mockRegionEntry, atLeast(3)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forTimeToLiveWithDefaultExpiration() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
ExpirationAttributes defaultExpiration = new ExpirationAttributes(300, ExpirationAction.DESTROY);
|
||||
|
||||
AnnotationBasedExpiration expiration = AnnotationBasedExpiration.forTimeToLive(defaultExpiration);
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 300, ExpirationAction.LOCAL_DESTROY);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutGenericExpiration());
|
||||
assertExpiration(expiration.getExpiry(mockRegionEntry), 60, ExpirationAction.INVALIDATE);
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(expiration.getExpiry(mockRegionEntry), is(equalTo(defaultExpiration)));
|
||||
verify(mockRegionEntry, atLeast(3)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetDefaultExpirationAttributes() {
|
||||
ExpirationAttributes expectedExpirationAttributes = new ExpirationAttributes(120, ExpirationAction.INVALIDATE);
|
||||
AnnotationBasedExpiration expiration = new AnnotationBasedExpiration();
|
||||
|
||||
expiration.setDefaultExpirationAttributes(expectedExpirationAttributes);
|
||||
|
||||
assertThat(expiration.getDefaultExpirationAttributes(), is(equalTo(expectedExpirationAttributes)));
|
||||
|
||||
expiration.setDefaultExpirationAttributes(null);
|
||||
|
||||
assertThat(expiration.getDefaultExpirationAttributes(), is(nullValue()));
|
||||
|
||||
expiration.setDefaultExpirationAttributes(ExpirationAttributes.DEFAULT);
|
||||
|
||||
assertThat(expiration.getDefaultExpirationAttributes(), is(equalTo(ExpirationAttributes.DEFAULT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExpiryCallsGetExpirationMetaDataOnRegionEntryFollowedByNewExpirationAttributes() {
|
||||
final ExpirationAttributes expectedExpirationAttributes = new ExpirationAttributes(60,
|
||||
ExpirationAction.LOCAL_DESTROY);
|
||||
|
||||
final Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
AnnotationBasedExpiration expiration = new AnnotationBasedExpiration() {
|
||||
@Override protected ExpirationMetaData getExpirationMetaData(Region.Entry entry) {
|
||||
assertThat(entry, is(sameInstance(mockRegionEntry)));
|
||||
return ExpirationMetaData.from(expectedExpirationAttributes);
|
||||
}
|
||||
|
||||
@Override protected ExpirationAttributes newExpirationAttributes(ExpirationMetaData expirationMetaData) {
|
||||
assertThat(expirationMetaData.timeout(), is(equalTo(expectedExpirationAttributes.getTimeout())));
|
||||
assertThat(expirationMetaData.expirationAction(), is(equalTo(expectedExpirationAttributes.getAction())));
|
||||
return expectedExpirationAttributes;
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(expiration.getExpiry(mockRegionEntry), is(equalTo(expectedExpirationAttributes)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpirationConfiguredWithGenericExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isExpirationConfigured(mockRegionEntry), is(true));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isExpirationConfigured(mockRegionEntry), is(true));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpirationConfiguredWithNoGenericExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertThat(noDefaultExpiration.isExpirationConfigured(mockRegionEntry), is(false));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.isExpirationConfigured(mockRegionEntry), is(false));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isIdleTimeoutConfiguredWithIdleTimeoutExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutExpiration());
|
||||
assertThat(noDefaultExpiration.isIdleTimeoutConfigured(mockRegionEntry), is(true));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isIdleTimeoutConfigured(mockRegionEntry), is(true));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isIdleTimeoutConfiguredWithNoIdleTimeoutExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isIdleTimeoutConfigured(mockRegionEntry), is(false));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.isIdleTimeoutConfigured(mockRegionEntry), is(false));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isTimeToLiveConfiguredWithTimeToLiveExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveExpiration());
|
||||
assertThat(noDefaultExpiration.isTimeToLiveConfigured(mockRegionEntry), is(true));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isTimeToLiveConfigured(mockRegionEntry), is(true));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
public void isTimeToLiveConfiguredWithNoTimeToLiveExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.isTimeToLiveConfigured(mockRegionEntry), is(false));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.isTimeToLiveConfigured(mockRegionEntry), is(false));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExpirationWithGenericExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getExpiration(mockRegionEntry), isA(Expiration.class));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getExpiration(mockRegionEntry), isA(Expiration.class));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExpirationWithNoGenericExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutExpiration());
|
||||
assertThat(noDefaultExpiration.getExpiration(mockRegionEntry), is(nullValue()));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.getExpiration(mockRegionEntry), is(nullValue()));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdleTimeoutWithIdleTimeoutExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutExpiration());
|
||||
assertThat(noDefaultExpiration.getIdleTimeout(mockRegionEntry), isA(IdleTimeoutExpiration.class));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getIdleTimeout(mockRegionEntry), isA(IdleTimeoutExpiration.class));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdleTimeoutWithNoIdleTimeoutExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getIdleTimeout(mockRegionEntry), is(nullValue()));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.getIdleTimeout(mockRegionEntry), is(nullValue()));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTimeToLiveWithTimeToLiveExpirationBasedRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveExpiration());
|
||||
assertThat(noDefaultExpiration.getTimeToLive(mockRegionEntry), isA(TimeToLiveExpiration.class));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getTimeToLive(mockRegionEntry), isA(TimeToLiveExpiration.class));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTimeToLiveWithNoTimeToLiveExpirationRegionEntry() {
|
||||
Region.Entry mockRegionEntry = mock(Region.Entry.class, "MockRegionEntry");
|
||||
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithIdleTimeoutGenericExpiration());
|
||||
assertThat(noDefaultExpiration.getTimeToLive(mockRegionEntry), is(nullValue()));
|
||||
when(mockRegionEntry.getValue()).thenReturn(new RegionEntryValueWithNoExpiration());
|
||||
assertThat(noDefaultExpiration.getTimeToLive(mockRegionEntry), is(nullValue()));
|
||||
verify(mockRegionEntry, times(2)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromExpiration() {
|
||||
ExpirationMetaData expirationMetaData = ExpirationMetaData.from(
|
||||
RegionEntryValueWithGenericExpiration.class.getAnnotation(Expiration.class));
|
||||
|
||||
assertExpiration(expirationMetaData, 60, ExpirationActionType.INVALIDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromExpirationIdleTimeout() {
|
||||
ExpirationMetaData expirationMetaData = ExpirationMetaData.from(
|
||||
RegionEntryValueWithIdleTimeoutExpiration.class.getAnnotation(IdleTimeoutExpiration.class));
|
||||
|
||||
assertExpiration(expirationMetaData, 120, ExpirationActionType.LOCAL_INVALIDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromExpirationTimeToLive() {
|
||||
ExpirationMetaData expirationMetaData = ExpirationMetaData.from(
|
||||
RegionEntryValueWithTimeToLiveExpiration.class.getAnnotation(TimeToLiveExpiration.class));
|
||||
|
||||
assertExpiration(expirationMetaData, 300, ExpirationActionType.LOCAL_DESTROY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toExpirationAttributes() {
|
||||
ExpirationMetaData expirationMetaData = new ExpirationMetaData(90, ExpirationActionType.DESTROY);
|
||||
|
||||
assertExpiration(expirationMetaData.toExpirationAttributes(), expirationMetaData.timeout(),
|
||||
expirationMetaData.expirationAction());
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.INVALIDATE)
|
||||
@IdleTimeoutExpiration(timeout = 120, action = ExpirationActionType.LOCAL_INVALIDATE)
|
||||
@TimeToLiveExpiration(timeout = 300, action = ExpirationActionType.LOCAL_DESTROY)
|
||||
public static class RegionEntryValueWithTimeToLiveIdleTimeoutGenericExpiration {
|
||||
}
|
||||
|
||||
@IdleTimeoutExpiration(timeout = 120, action = ExpirationActionType.LOCAL_INVALIDATE)
|
||||
@TimeToLiveExpiration(timeout = 300, action = ExpirationActionType.LOCAL_DESTROY)
|
||||
public static class RegionEntryValueWithTimeToLiveIdleTimeoutExpiration {
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.INVALIDATE)
|
||||
@TimeToLiveExpiration(timeout = 300, action = ExpirationActionType.LOCAL_DESTROY)
|
||||
public static class RegionEntryValueWithTimeToLiveGenericExpiration {
|
||||
}
|
||||
|
||||
@TimeToLiveExpiration(timeout = 300, action = ExpirationActionType.LOCAL_DESTROY)
|
||||
public static class RegionEntryValueWithTimeToLiveExpiration {
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.INVALIDATE)
|
||||
@IdleTimeoutExpiration(timeout = 120, action = ExpirationActionType.LOCAL_INVALIDATE)
|
||||
public static class RegionEntryValueWithIdleTimeoutGenericExpiration {
|
||||
}
|
||||
|
||||
@IdleTimeoutExpiration(timeout = 120, action = ExpirationActionType.LOCAL_INVALIDATE)
|
||||
public static class RegionEntryValueWithIdleTimeoutExpiration {
|
||||
}
|
||||
|
||||
@Expiration(timeout = 60, action = ExpirationActionType.INVALIDATE)
|
||||
public static class RegionEntryValueWithGenericExpiration {
|
||||
}
|
||||
|
||||
public static class RegionEntryValueWithNoExpiration {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
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
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">SpringGemFireCachingIntegrationTest</prop>
|
||||
<prop key="mcast-port">0</prop>
|
||||
<prop key="log-level">warning</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe:cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<bean id="defaultExpirationAttributes" class="com.gemstone.gemfire.cache.ExpirationAttributes">
|
||||
<constructor-arg value="600"/>
|
||||
<constructor-arg value="#{T(com.gemstone.gemfire.cache.ExpirationAction).DESTROY}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="ttiExpiration" class="org.springframework.data.gemfire.support.AnnotationBasedExpiration"
|
||||
factory-method="forIdleTimeout"/>
|
||||
|
||||
<bean id="ttlExpiration" class="org.springframework.data.gemfire.support.AnnotationBasedExpiration"
|
||||
factory-method="forTimeToLive">
|
||||
<constructor-arg ref="defaultExpirationAttributes"/>
|
||||
</bean>
|
||||
|
||||
<gfe:partitioned-region id="Example" persistent="false">
|
||||
<gfe:custom-entry-ttl ref="ttlExpiration"/>
|
||||
<gfe:custom-entry-tti ref="ttiExpiration"/>
|
||||
</gfe:partitioned-region>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user