/* * 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; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.annotation.Resource; import org.apache.geode.cache.CacheListener; import org.apache.geode.cache.CacheLoader; import org.apache.geode.cache.CacheLoaderException; import org.apache.geode.cache.CacheWriter; import org.apache.geode.cache.CacheWriterException; import org.apache.geode.cache.CustomExpiry; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.EntryEvent; import org.apache.geode.cache.EvictionAction; import org.apache.geode.cache.EvictionAlgorithm; import org.apache.geode.cache.EvictionAttributes; import org.apache.geode.cache.ExpirationAction; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.LoaderHelper; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionEvent; import org.apache.geode.cache.asyncqueue.AsyncEvent; import org.apache.geode.cache.asyncqueue.AsyncEventListener; import org.apache.geode.cache.util.CacheListenerAdapter; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanNameAware; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.StringUtils; /** * The LookupRegionMutationIntegrationTest class is a test suite of test cases testing the contract and integrated * functionality between natively-defined GemFire Cache Regions and SDG's Region lookup functionality combined with * Region attribute(s) mutation. * * @author John Blum * @see org.junit.Test * @see org.junit.runner.RunWith * @see org.springframework.data.gemfire.LookupRegionFactoryBean * @see org.springframework.test.context.ContextConfiguration * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner * @since 1.7.0 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @SuppressWarnings("unused") public class LookupRegionMutationIntegrationTest { @Resource(name = "Example") private Region<?, ?> example; protected void assertCacheListeners(CacheListener[] cacheListeners, Collection<String> expectedCacheListenerNames) { if (!expectedCacheListenerNames.isEmpty()) { assertNotNull("CacheListeners must not be null!", cacheListeners); assertEquals(expectedCacheListenerNames.size(), cacheListeners.length); assertTrue(toStrings(cacheListeners).containsAll(expectedCacheListenerNames)); } } protected void assertEvictionAttributes(EvictionAttributes evictionAttributes, EvictionAction expectedAction, EvictionAlgorithm expectedAlgorithm, int expectedMaximum) { assertNotNull("EvictionAttributes must not be null!", evictionAttributes); assertEquals(expectedAction, evictionAttributes.getAction()); assertEquals(expectedAlgorithm, evictionAttributes.getAlgorithm()); assertEquals(expectedMaximum, evictionAttributes.getMaximum()); } protected void assertExpirationAttributes(ExpirationAttributes expirationAttributes, String description, int expectedTimeout, ExpirationAction expectedAction) { assertNotNull(String.format("ExpirationAttributes for '%1$s' must not be null!", description), expirationAttributes); assertEquals(expectedAction, expirationAttributes.getAction()); assertEquals(expectedTimeout, expirationAttributes.getTimeout()); } protected void assertGemFireComponent(Object gemfireComponent, String expectedName) { assertNotNull("The GemFire component must not be null!", gemfireComponent); assertEquals(expectedName, gemfireComponent.toString()); } protected Collection<String> toStrings(Object[] objects) { List<String> cacheListenerNames = new ArrayList<String>(objects.length); for (Object object : objects) { cacheListenerNames.add(object.toString()); } return cacheListenerNames; } @Test public void testRegionConfiguration() { assertNotNull("'/Example' Region was not properly initialized!", example); assertEquals("Example", example.getName()); assertEquals("/Example", example.getFullPath()); assertNotNull(example.getAttributes()); assertEquals(DataPolicy.REPLICATE, example.getAttributes().getDataPolicy()); assertEquals(13, example.getAttributes().getInitialCapacity()); assertEquals(0.85f, example.getAttributes().getLoadFactor(), 0.0f); assertCacheListeners(example.getAttributes().getCacheListeners(), Arrays.asList("A", "B")); assertGemFireComponent(example.getAttributes().getCacheLoader(), "C"); assertGemFireComponent(example.getAttributes().getCacheWriter(), "D"); assertEvictionAttributes(example.getAttributes().getEvictionAttributes(), EvictionAction.OVERFLOW_TO_DISK, EvictionAlgorithm.LRU_ENTRY, 1000); assertExpirationAttributes(example.getAttributes().getRegionTimeToLive(), "Region TTL", 120, ExpirationAction.LOCAL_DESTROY); assertExpirationAttributes(example.getAttributes().getRegionIdleTimeout(), "Region TTI", 60, ExpirationAction.INVALIDATE); assertExpirationAttributes(example.getAttributes().getEntryTimeToLive(), "Entry TTL", 30, ExpirationAction.DESTROY); assertGemFireComponent(example.getAttributes().getCustomEntryIdleTimeout(), "E"); assertNotNull(example.getAttributes().getGatewaySenderIds()); assertEquals(1, example.getAttributes().getGatewaySenderIds().size()); assertEquals("GWS", example.getAttributes().getGatewaySenderIds().iterator().next()); assertNotNull(example.getAttributes().getAsyncEventQueueIds()); assertEquals(1, example.getAttributes().getAsyncEventQueueIds().size()); assertEquals("AEQ", example.getAttributes().getAsyncEventQueueIds().iterator().next()); } protected interface Nameable extends BeanNameAware { String getName(); void setName(String name); } protected static abstract class AbstractNameable implements Nameable { private String name; public String getName() { return name; } public void setName(final String name) { this.name = name; } @Override public void setBeanName(final String name) { if (!StringUtils.hasText(this.name)) { setName(name); } } @Override public String toString() { return getName(); } } public static final class TestAsyncEventListener extends AbstractNameable implements AsyncEventListener { @Override public boolean processEvents(List<AsyncEvent> events) { throw new UnsupportedOperationException("Not Implemented!"); } @Override public void close() { } } public static final class TestCacheListener<K, V> extends CacheListenerAdapter<K, V> implements Nameable { private String name; public String getName() { return name; } public void setName(final String name) { this.name = name; } @Override public void setBeanName(final String name) { if (!StringUtils.hasText(this.name)) { setName(name); } } @Override public String toString() { return getName(); } } public static final class TestCacheLoader<K, V> extends AbstractNameable implements CacheLoader<K, V> { @Override public V load(LoaderHelper<K, V> helper) throws CacheLoaderException { throw new UnsupportedOperationException("Not Implemented!"); } @Override public void close() { } } public static final class TestCacheWriter<K, V> extends AbstractNameable implements CacheWriter<K, V> { @Override public void beforeUpdate(EntryEvent<K, V> event) throws CacheWriterException { } @Override public void beforeCreate(EntryEvent<K, V> event) throws CacheWriterException { } @Override public void beforeDestroy(EntryEvent<K, V> event) throws CacheWriterException { } @Override public void beforeRegionDestroy(RegionEvent<K, V> event) throws CacheWriterException { } @Override public void beforeRegionClear(RegionEvent<K, V> event) throws CacheWriterException { } @Override public void close() { } } public static final class TestCustomExpiry<K, V> extends AbstractNameable implements CustomExpiry<K, V> { @Override public ExpirationAttributes getExpiry(Region.Entry<K, V> entry) { throw new UnsupportedOperationException("Not Implemented!"); } @Override public void close() { } } }