diff --git a/src/main/java/org/springframework/data/gemfire/GenericRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/GenericRegionFactoryBean.java new file mode 100644 index 00000000..c329f532 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/GenericRegionFactoryBean.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * The GenericRegionFactoryBean class is an extension of the abstract, base RegionFactoryBean class enabling developers + * to define a GemFire Cache Region with defaults. + * + * The defaults for DataPolicy is NORMAL and Scope is DISTRIBUTED_NO_ACK, effectively creating a "non-replicate", + * Distributed Region. + * + * This class enables developers to create various non-strongly-typed Regions (e.g. PARTITION, REPLICATE) based on + * various combinations of the DataPolicy, Scope and Subscription settings as defined in the Region Types section + * of the GemFire User Guide (see link below). How GemFire Regions receive and distribute entry updates + * is defined in the Storage and Distribution Options section. + * + * Note, it is generally better to define strong-typed Regions (e.g. PARTITION with PartitionedRegionFactoryBean) + * in your applications. However, different forms of distribution patterns and updates are desired + * in certain use cases. + * + * @author John Blum + * @see org.springframework.data.gemfire.RegionFactoryBean + * @link http://gemfire.docs.pivotal.io/latest/userguide/index.html#developing/region_options/region_types.html + * @link http://gemfire.docs.pivotal.io/latest/userguide/index.html#developing/region_options/storage_distribution_options.html + * @since 1.7.0 + */ +@SuppressWarnings("unused") +public class GenericRegionFactoryBean extends RegionFactoryBean { + +} diff --git a/src/test/java/org/springframework/data/gemfire/GenericRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/GenericRegionFactoryBeanTest.java new file mode 100644 index 00000000..b9491eb5 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/GenericRegionFactoryBeanTest.java @@ -0,0 +1,183 @@ +/* + * 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 org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.Scope; + +/** + * The GenericRegionFactoryBeanTest class is a test suite of test cases testing the contract and functionality + * of the GenericRegionFactoryBean class. + * + * @author John Blum + * @see org.springframework.data.gemfire.GenericRegionFactoryBean + * @since 1.7.0 + */ +public class GenericRegionFactoryBeanTest { + + // as defined in the com.gemstone.gemfire.internal.cache.AbstractRegion class + private static final Scope DEFAULT_SCOPE = Scope.DISTRIBUTED_NO_ACK; + + private static Region defaultRegion; + private static Region emptyRegion; + private static Region localRegion; + private static Region normalRegion; + private static Region persistentPartitionRegion; + private static Region preloadedRegion; + private static Region replicateRegion; + + @BeforeClass + public static void setup() throws Exception { + Cache gemfireCache = new CacheFactory() + .set("name", GenericRegionFactoryBeanTest.class.getSimpleName()) + .set("mcast-port", "0") + .set("log-level", "warning") + .create(); + + RegionFactoryBean defaultRegionFactory = new GenericRegionFactoryBean(); + defaultRegionFactory.setCache(gemfireCache); + defaultRegionFactory.setName("DefaultRegion"); + defaultRegionFactory.afterPropertiesSet(); + + defaultRegion = defaultRegionFactory.getObject(); + + RegionFactoryBean emptyRegionFactory = new GenericRegionFactoryBean(); + emptyRegionFactory.setCache(gemfireCache); + emptyRegionFactory.setDataPolicy(DataPolicy.EMPTY); + emptyRegionFactory.setName("EmptyRegion"); + emptyRegionFactory.setScope(Scope.DISTRIBUTED_NO_ACK); + emptyRegionFactory.afterPropertiesSet(); + + emptyRegion = emptyRegionFactory.getObject(); + + RegionFactoryBean localRegionFactory = new GenericRegionFactoryBean(); + localRegionFactory.setCache(gemfireCache); + localRegionFactory.setDataPolicy(DataPolicy.NORMAL); + localRegionFactory.setName("LocalRegion"); + localRegionFactory.setScope(Scope.LOCAL); + localRegionFactory.afterPropertiesSet(); + + localRegion = localRegionFactory.getObject(); + + RegionFactoryBean normalRegionFactory = new GenericRegionFactoryBean(); + normalRegionFactory.setCache(gemfireCache); + normalRegionFactory.setDataPolicy(DataPolicy.NORMAL); + normalRegionFactory.setName("NormalRegion"); + normalRegionFactory.setScope(Scope.DISTRIBUTED_ACK); + normalRegionFactory.afterPropertiesSet(); + + normalRegion = normalRegionFactory.getObject(); + + RegionFactoryBean persistentPartitionRegionFactory = new GenericRegionFactoryBean(); + persistentPartitionRegionFactory.setCache(gemfireCache); + persistentPartitionRegionFactory.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); + persistentPartitionRegionFactory.setName("PersistentPartitionRegion"); + persistentPartitionRegionFactory.setPersistent(true); + persistentPartitionRegionFactory.afterPropertiesSet(); + + persistentPartitionRegion = persistentPartitionRegionFactory.getObject(); + + RegionFactoryBean preloadedRegionFactory = new GenericRegionFactoryBean(); + preloadedRegionFactory.setCache(gemfireCache); + preloadedRegionFactory.setDataPolicy(DataPolicy.PRELOADED); + preloadedRegionFactory.setName("PreloadedRegion"); + preloadedRegionFactory.afterPropertiesSet(); + + preloadedRegion = preloadedRegionFactory.getObject(); + + RegionFactoryBean replicateRegionFactory = new GenericRegionFactoryBean(); + replicateRegionFactory.setCache(gemfireCache); + replicateRegionFactory.setDataPolicy(DataPolicy.REPLICATE); + replicateRegionFactory.setName("ReplicateRegion"); + replicateRegionFactory.setScope(Scope.GLOBAL); + replicateRegionFactory.afterPropertiesSet(); + + replicateRegion = replicateRegionFactory.getObject(); + } + + @AfterClass + public static void tearDown() { + try { + CacheFactory.getAnyInstance().close(); + } + catch (Exception ignore) { + } + } + + protected void assertRegionAttributes(Region region, String expectedRegionName, DataPolicy expectedDataPolicy, + Scope expectedScope) { + assertRegionAttributes(region, expectedRegionName, String.format("%1$s%2$s", Region.SEPARATOR, expectedRegionName), + expectedDataPolicy, expectedScope); + } + + protected void assertRegionAttributes(Region region, String expectedRegionName, String expectedRegionPath, + DataPolicy expectedDataPolicy, Scope expectedScope) { + assertNotNull("The GemFire Cache Region must not be null!", region); + assertEquals(expectedRegionName, region.getName()); + assertEquals(expectedRegionPath, region.getFullPath()); + assertNotNull("The RegionAttributes must be specified!", region.getAttributes()); + assertEquals(expectedDataPolicy, region.getAttributes().getDataPolicy()); + assertEquals(expectedScope, region.getAttributes().getScope()); + } + + @Test + public void defaultRegionAttributes() { + assertRegionAttributes(defaultRegion, "DefaultRegion", DataPolicy.DEFAULT, DEFAULT_SCOPE); + } + + @Test + public void emptyRegionAttributes() { + assertRegionAttributes(emptyRegion, "EmptyRegion", DataPolicy.EMPTY, Scope.DISTRIBUTED_NO_ACK); + } + + @Test + public void localRegionAttributes() { + assertRegionAttributes(localRegion, "LocalRegion", DataPolicy.NORMAL, Scope.LOCAL); + } + + @Test + public void normalRegionAttributes() { + assertRegionAttributes(normalRegion, "NormalRegion", DataPolicy.NORMAL, Scope.DISTRIBUTED_ACK); + } + + @Test + public void persistentPartitionRegionAttributes() { + assertRegionAttributes(persistentPartitionRegion, "PersistentPartitionRegion", DataPolicy.PERSISTENT_PARTITION, + DEFAULT_SCOPE); + } + + @Test + public void preloadedRegionAttributes() { + assertRegionAttributes(preloadedRegion, "PreloadedRegion", DataPolicy.PRELOADED, DEFAULT_SCOPE); + } + + @Test + public void replicateRegionAttributes() { + assertRegionAttributes(replicateRegion, "ReplicateRegion", DataPolicy.REPLICATE, Scope.GLOBAL); + } + +}