/* * 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.expiration; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; 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.mock; import static org.mockito.Mockito.when; import javax.annotation.Resource; import org.apache.geode.cache.CustomExpiry; import org.apache.geode.cache.ExpirationAction; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.Region; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; import org.springframework.expression.EvaluationException; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * 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 AnnotationBasedExpiration * @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer * @see org.springframework.test.context.ContextConfiguration * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @see org.apache.geode.cache.CustomExpiry * @see org.apache.geode.cache.ExpirationAction * @see org.apache.geode.cache.ExpirationAttributes * @since 1.7.0 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(initializers = GemfireTestApplicationContextInitializer.class) @SuppressWarnings("unused") public class AnnotationBasedExpirationConfigurationIntegrationTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @Autowired @Qualifier("genericExpiration") private AnnotationBasedExpiration<Object, Object> genericExpiration; @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(genericExpiration, is(instanceOf(CustomExpiry.class))); assertThat(genericExpiration.getDefaultExpirationAttributes(), is(nullValue())); 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 ApplicationDomainObjectWithTimeToLiveAndGenericExpirationPolicies())), 60, ExpirationAction.INVALIDATE); assertExpiration(expiration.getExpiry(mockRegionEntry(new ApplicationDomainObjectWithIdleTimeoutExpirationPolicy())), 120, ExpirationAction.INVALIDATE); assertExpiration(expiration.getExpiry(mockRegionEntry(new ApplicationDomainObjectWithGenericExpirationPolicy())), 60, ExpirationAction.DESTROY); assertThat(expiration.getExpiry(mockRegionEntry(new ApplicationDomainObjectWithNoExpirationPolicy())), is(nullValue())); assertThat(expiration.getExpiry(mockRegionEntry(new RegionEntryTimeToLiveExpirationPolicy())), is(nullValue())); assertExpiration(expiration.getExpiry(mockRegionEntry(new RegionEntryIdleTimeoutExpirationPolicy())), 60, ExpirationAction.INVALIDATE); assertExpiration(expiration.getExpiry(mockRegionEntry(new RegionEntryGenericExpirationPolicy())), 60, ExpirationAction.DESTROY); } @Test public void exampleRegionTimeToLiveExpirationPolicy() { CustomExpiry<Object, Object> expiration = example.getAttributes().getCustomEntryTimeToLive(); assertExpiration(expiration.getExpiry(mockRegionEntry(new ApplicationDomainObjectWithTimeToLiveAndGenericExpirationPolicies())), 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()))); assertExpiration(expiration.getExpiry(mockRegionEntry(new RegionEntryTimeToLiveExpirationPolicy())), 60, ExpirationAction.LOCAL_INVALIDATE); assertExpiration(defaultExpirationAttributes, expiration.getExpiry(mockRegionEntry(new RegionEntryIdleTimeoutExpirationPolicy()))); assertExpiration(expiration.getExpiry(mockRegionEntry(new RegionEntryGenericExpirationPolicy())), 60, ExpirationAction.DESTROY); } @Test public void genericExpirationPolicy() { assertExpiration(genericExpiration.getExpiry(mockRegionEntry( new ApplicationDomainObjectWithTimeToLiveAndGenericExpirationPolicies())), 60, ExpirationAction.INVALIDATE); assertThat(genericExpiration.getExpiry(mockRegionEntry( new ApplicationDomainObjectWithIdleTimeoutExpirationPolicy())), is(nullValue())); assertExpiration(genericExpiration.getExpiry(mockRegionEntry( new ApplicationDomainObjectWithGenericExpirationPolicy())), 60, ExpirationAction.DESTROY); assertThat(genericExpiration.getExpiry(mockRegionEntry( new ApplicationDomainObjectWithNoExpirationPolicy())), is(nullValue())); assertThat(genericExpiration.getExpiry(mockRegionEntry( new RegionEntryTimeToLiveExpirationPolicy())), is(nullValue())); assertThat(genericExpiration.getExpiry(mockRegionEntry( new RegionEntryIdleTimeoutExpirationPolicy())), is(nullValue())); assertExpiration(genericExpiration.getExpiry(mockRegionEntry( new RegionEntryGenericExpirationPolicy())), 60, ExpirationAction.DESTROY); } @Test public void invalidExpirationAction() { expectedException.expect(EvaluationException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); expectedException.expectMessage(String.format("[%s] is not resolvable as an ExpirationAction(Type)", "@expirationProperties['gemfire.region.entry.expiration.invalid.action.string']")); genericExpiration.getExpiry(mockRegionEntry(new RegionEntryWithInvalidExpirationAction())); } @Test public void invalidExpirationTimeout() { expectedException.expect(IllegalArgumentException.class); expectedException.expectCause(is(nullValue(Throwable.class))); genericExpiration.getExpiry(mockRegionEntry(new RegionEntryWithInvalidExpirationTimeout())); } @Expiration(timeout = "60", action = "INVALIDATE") @TimeToLiveExpiration(timeout = "300", action = "DESTROY") protected static class ApplicationDomainObjectWithTimeToLiveAndGenericExpirationPolicies { } @IdleTimeoutExpiration(timeout = "120", action = "INVALIDATE") protected static class ApplicationDomainObjectWithIdleTimeoutExpirationPolicy { } @Expiration(timeout = "60", action = "DESTROY") protected static class ApplicationDomainObjectWithGenericExpirationPolicy { } protected static class ApplicationDomainObjectWithNoExpirationPolicy { } @TimeToLiveExpiration(timeout = "${gemfire.region.entry.expiration.timeout}", action = "${gemfire.region.entry.expiration.action.string}") protected static class RegionEntryTimeToLiveExpirationPolicy { } @IdleTimeoutExpiration(timeout = "@expirationProperties['gemfire.region.entry.expiration.timeout']", action = "@expirationProperties['gemfire.region.entry.expiration.action.gemfire.type']") protected static class RegionEntryIdleTimeoutExpirationPolicy { } @Expiration(timeout = "${gemfire.region.entry.expiration.timeout}", action = "@expirationProperties['gemfire.region.entry.expiration.action.spring.type']") protected static class RegionEntryGenericExpirationPolicy { } @Expiration(timeout = "${gemfire.region.entry.expiration.timeout}", action = "@expirationProperties['gemfire.region.entry.expiration.invalid.action.string']") protected static class RegionEntryWithInvalidExpirationAction { } @Expiration(timeout = "${gemfire.region.entry.expiration.invalid.timeout}", action = "@expirationProperties['gemfire.region.entry.expiration.action.spring.type']") protected static class RegionEntryWithInvalidExpirationTimeout { } }