diff --git a/src/main/java/org/springframework/data/gemfire/LocalRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/LocalRegionFactoryBean.java index 5d6f4d0b..59206a91 100644 --- a/src/main/java/org/springframework/data/gemfire/LocalRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/LocalRegionFactoryBean.java @@ -16,6 +16,7 @@ package org.springframework.data.gemfire; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.RegionFactory; @@ -23,12 +24,13 @@ import com.gemstone.gemfire.cache.Scope; /** * @author David Turanski - * + * @author John Blum */ public class LocalRegionFactoryBean extends RegionFactoryBean { + @Override public void setScope(Scope scope) { - throw new UnsupportedOperationException("setScope() is not allowed for Local Regions"); + throw new UnsupportedOperationException("Setting the Scope on Local Regions is not allowed."); } @Override @@ -37,24 +39,38 @@ public class LocalRegionFactoryBean extends RegionFactoryBean { super.afterPropertiesSet(); } + /** + * Resolves the Data Policy used by this "local" GemFire Region (i.e. locally Scoped; Scope.LOCAL) based on the + * enumerated value from com.gemstone.gemfire.cache.RegionShortcuts (LOCAL, LOCAL_PERSISTENT, LOCAL_HEAP_LRU, + * LOCAL_OVERFLOW, and LOCAL_PERSISTENT_OVERFLOW), but without consideration of the Eviction settings. + *

+ * @param regionFactory the GemFire RegionFactory used to created the Local Region. + * @param persistent a boolean value indicating whether the Local Region should persist it's data. + * @param dataPolicy requested Data Policy as set by the user in the Spring GemFire configuration meta-data. + * @see com.gemstone.gemfire.cache.DataPolicy + * @see com.gemstone.gemfire.cache.RegionFactory + * @see com.gemstone.gemfire.cache.RegionShortcut + */ @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { - if (dataPolicy != null) { - dataPolicy = dataPolicy.toUpperCase(); - if ("NORMAL".equals(dataPolicy) || dataPolicy == null) { - regionFactory.setDataPolicy(DataPolicy.NORMAL); - } - else if ("PRELOADED".equals(dataPolicy)) { - regionFactory.setDataPolicy(DataPolicy.PRELOADED); - } - else if ("EMPTY".equals(dataPolicy)) { - Assert.isTrue(persistent == null || !persistent, "Cannot have persistence on an empty region"); - regionFactory.setDataPolicy(DataPolicy.EMPTY); - } - else { - throw new IllegalArgumentException("Data policy '" + dataPolicy - + "' is unsupported or invalid for local regions."); - } + DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy); + + Assert.isTrue(resolvedDataPolicy != null || (resolvedDataPolicy == null && !StringUtils.hasText(dataPolicy)), + String.format("Data Policy '%1$s' is invalid.", dataPolicy)); + + if (resolvedDataPolicy == null || DataPolicy.NORMAL.equals(resolvedDataPolicy)) { + // NOTE this is safe since a LOCAL Scoped NORMAL Region requiring persistence can be satisfied with + // PERSISTENT_REPLICATE, per the RegionShortcut.LOCAL_PERSISTENT + regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.NORMAL); + } + else if (DataPolicy.PRELOADED.equals(resolvedDataPolicy)) { + // NOTE this is safe since a LOCAL Scoped PRELOADED Region requiring persistence can be satisfied with + // PERSISTENT_REPLICATE, per the RegionShortcut.LOCAL_PERSISTENT + regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.PRELOADED); + } + else { + throw new IllegalArgumentException(String.format("Data Policy '%1$s' is not supported in Local Regions.", + dataPolicy)); } } diff --git a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java index 11226876..546093e4 100644 --- a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java @@ -26,41 +26,41 @@ import com.gemstone.gemfire.cache.RegionFactory; /** * @author David Turanski - * + * @author John Blum */ public class PartitionedRegionFactoryBean extends RegionFactoryBean { @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { if (dataPolicy != null) { - DataPolicy dp = new DataPolicyConverter().convert(dataPolicy); - Assert.notNull(dp, "Data policy " + dataPolicy + " is invalid"); - Assert.isTrue(dp.withPartitioning(), "Data Policy " + dp.toString() - + " is not supported in partitioned regions"); - if (!isPersistent()) { - regionFactory.setDataPolicy(dp); - } - else { - Assert.isTrue(dp.withPersistence(), "Data Policy " + dp.toString() - + "is invalid when persistent is false"); - regionFactory.setDataPolicy(dp); - } - return; + DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy); + + Assert.notNull(resolvedDataPolicy, String.format("Data Policy '%1$s' is invalid.", dataPolicy)); + + // Validate that the user-defined Data Policy matches the appropriate Spring GemFire XML namespace + // configuration meta-data element for Region (i.e. )! + Assert.isTrue(resolvedDataPolicy.withPartitioning(), String.format( + "Data Policy '%1$s' is not supported in Partitioned Regions.", resolvedDataPolicy)); + + // Validate that the data-policy and persistent attributes are compatible when specified! + assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy); + + regionFactory.setDataPolicy(resolvedDataPolicy); } - if (isPersistent()) { - // check first for GemFire 6.5 - if (ConcurrentMap.class.isAssignableFrom(Region.class)) { - regionFactory.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); - } - else { - throw new IllegalArgumentException( - "Can define persistent partitions only from GemFire 6.5 onwards - current version is [" - + CacheFactory.getVersion() + "]"); - } + else if (isPersistent()) { + // first, check the presence of GemFire 6.5 or Higher + Assert.isTrue(isGemFireVersion65orHigher(), String.format( + "Can define Persistent Partitioned Regions only from GemFire 6.5 onwards; current version is [%1$s]", + CacheFactory.getVersion())); + regionFactory.setDataPolicy(DataPolicy.PERSISTENT_PARTITION); } else { regionFactory.setDataPolicy(DataPolicy.PARTITION); } } + private boolean isGemFireVersion65orHigher() { + return ConcurrentMap.class.isAssignableFrom(Region.class); + } + } diff --git a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java index aa971267..427df3bc 100644 --- a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java @@ -24,14 +24,12 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.context.SmartLifecycle; import org.springframework.core.io.Resource; import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.wan.GatewaySenderWrapper; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import com.gemstone.gemfire.cache.AttributesFactory; import com.gemstone.gemfire.cache.Cache; -import com.gemstone.gemfire.cache.CacheClosedException; import com.gemstone.gemfire.cache.CacheListener; import com.gemstone.gemfire.cache.CacheLoader; import com.gemstone.gemfire.cache.CacheWriter; @@ -56,20 +54,19 @@ import com.gemstone.gemfire.cache.wan.GatewaySender; * * @author Costin Leau * @author David Turanski + * @author John Blum */ public class RegionFactoryBean extends RegionLookupFactoryBean implements DisposableBean, SmartLifecycle { - private boolean autoStartup = true; - - private boolean running; - protected final Log log = LogFactory.getLog(getClass()); - private boolean destroy = false; - + private boolean autoStartup = true; private boolean close = true; + private boolean destroy = false; + private boolean running; - private Resource snapshot; + private Boolean enableGateway; + private Boolean persistent; private CacheListener cacheListeners[]; @@ -77,31 +74,23 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple private CacheWriter cacheWriter; - private Object gatewaySenders[]; - - private Object asyncEventQueues[]; + private Object[] asyncEventQueues; + private Object[] gatewaySenders; private RegionAttributes attributes; + private Resource snapshot; + private Scope scope; - private Boolean persistent; - - private Boolean enableGateway; - - private String hubId; - - private String diskStoreName; - private String dataPolicy; - - private Region region; + private String diskStoreName; + private String hubId; @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); - region = getRegion(); - postProcess(region); + postProcess(getRegion()); } @Override @@ -110,11 +99,12 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple Cache c = (Cache) cache; - if (attributes != null) + if (attributes != null) { AttributesFactory.validateAttributes(attributes); + } - final RegionFactory regionFactory = (attributes != null ? c.createRegionFactory(attributes) : c - . createRegionFactory()); + final RegionFactory regionFactory = (attributes != null ? c.createRegionFactory(attributes) : + c. createRegionFactory()); if (hubId != null) { enableGateway = enableGateway == null ? true : enableGateway; @@ -122,12 +112,14 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple regionFactory.setGatewayHubId(hubId); } + if (enableGateway != null) { if (enableGateway) { Assert.notNull(hubId, "enableGateway requires the hubId property to be true"); } regionFactory.setEnableGateway(enableGateway); } + if (!ObjectUtils.isEmpty(cacheListeners)) { for (CacheListener listener : cacheListeners) { regionFactory.addCacheListener(listener); @@ -135,9 +127,8 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple } if (!ObjectUtils.isEmpty(gatewaySenders)) { - Assert.isTrue( - hubId == null, - "It is invalid to configure a region with both a hubId and gatewaySenders. Note that the enableGateway and hubId properties are deprecated since Gemfire 7.0"); + Assert.isTrue(hubId == null, "It is invalid to configure a region with both a hubId and gatewaySenders." + + " Note that the enableGateway and hubId properties are deprecated since Gemfire 7.0"); for (Object gatewaySender : gatewaySenders) { regionFactory.addGatewaySenderId(((GatewaySender) gatewaySender).getId()); } @@ -169,60 +160,56 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple if (attributes != null) { Assert.state(!attributes.isLockGrantor() || scope.isGlobal(), - "Lock grantor only applies to a global scoped region"); + "Lock grantor only applies to a global scoped region"); } + // get underlying AttributesFactory postProcess(findAttrFactory(regionFactory)); - Region reg = regionFactory.create(regionName); + Region region = regionFactory.create(regionName); log.info("Created new cache region [" + regionName + "]"); + if (snapshot != null) { - reg.loadSnapshot(snapshot.getInputStream()); + region.loadSnapshot(snapshot.getInputStream()); } if (attributes != null && attributes.isLockGrantor()) { - reg.becomeLockGrantor(); + region.becomeLockGrantor(); } - return reg; + return region; } /** - * This validates the configured data policy and may override it, taking - * into account the persistent attribute and constraints for the region type - * @param regionFactory - * @param persistent - * @param dataPolicy requested data policy + * Validates the configured Data Policy and may override it, taking into account the 'persistent' attribute + * and constraints for the Region type. + *

+ * @param regionFactory the GemFire RegionFactory used to created the Local Region. + * @param persistent a boolean value indicating whether the Local Region should persist it's data. + * @param dataPolicy requested Data Policy as set by the user in the Spring GemFire configuration meta-data. + * @see com.gemstone.gemfire.cache.DataPolicy + * @see com.gemstone.gemfire.cache.RegionFactory */ protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { if (dataPolicy != null) { - regionFactory.setDataPolicy(convertAndValidate(dataPolicy)); + DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy); + + Assert.notNull(resolvedDataPolicy, String.format("Data Policy '%1$s' is invalid.", dataPolicy)); + assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy); + + regionFactory.setDataPolicy(resolvedDataPolicy); } else { regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.DEFAULT); } } - private DataPolicy convertAndValidate(final String dataPolicy) { - final DataPolicy dataPolicyType = new DataPolicyConverter().convert(dataPolicy); - - Assert.notNull(dataPolicyType, String.format("Data policy %1$s is invalid", dataPolicy)); - - if (dataPolicyType.withPersistence()) { - // NOTE isNotPersistent means the user explicitly set the persistent attribute for the Region to false, - // and this conflicts with the Data Policy (via the that was set by the user, which indicates persistence. - Assert.isTrue(!isNotPersistent(), String.format("Data policy %1$s is invalid when persistent is false", - dataPolicy)); - } - - return dataPolicyType; - } - @SuppressWarnings("unchecked") private AttributesFactory findAttrFactory(RegionFactory regionFactory) { - Field attrField = ReflectionUtils.findField(RegionFactory.class, "attrsFactory", AttributesFactory.class); - ReflectionUtils.makeAccessible(attrField); - return (AttributesFactory) ReflectionUtils.getField(attrField, regionFactory); + Field attrsFactoryField = ReflectionUtils.findField(RegionFactory.class, "attrsFactory", + AttributesFactory.class); + ReflectionUtils.makeAccessible(attrsFactoryField); + return (AttributesFactory) ReflectionUtils.getField(attrsFactoryField, regionFactory); } /** @@ -252,32 +239,22 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple @Override public void destroy() throws Exception { - if (region != null) { + if (getRegion() != null) { if (close) { - if (!region.getRegionService().isClosed()) { + if (!getRegion().getRegionService().isClosed()) { try { - region.close(); - region = null; + getRegion().close(); } catch (Exception cce) { // nothing to see folks, move on. } } } if (destroy) { - region.destroyRegion(); - region = null; + getRegion().destroyRegion(); } } } - /** - * Indicates whether the region referred by this factory bean, will be - * destroyed on shutdown (default false). - */ - public void setDestroy(boolean destroy) { - this.destroy = destroy; - } - /** * Indicates whether the region referred by this factory bean, will be * closed on shutdown (default true). @@ -286,6 +263,14 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple this.close = close; } + /** + * Indicates whether the region referred by this factory bean, will be + * destroyed on shutdown (default false). + */ + public void setDestroy(boolean destroy) { + this.destroy = destroy; + } + /** * Sets the snapshots used for loading a newly created region. That * is, the snapshot will be used only when a new region is created - @@ -400,12 +385,54 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple this.attributes = attributes; } - protected boolean isPersistent() { - return persistent != null && persistent; + /** + * Validates that the settings for Data Policy and the 'persistent' attribute in elements + * are compatible. + *

+ * @param resolvedDataPolicy the GemFire Data Policy resolved form the Spring GemFire XML namespace configuration + * meta-data. + * @see #isPersistent() + * @see #isNotPersistent() + * @see com.gemstone.gemfire.cache.DataPolicy + */ + protected void assertDataPolicyAndPersistentAttributesAreCompatible(final DataPolicy resolvedDataPolicy) { + final boolean persistentNotSpecified = (this.persistent == null); + + if (resolvedDataPolicy.withPersistence()) { + Assert.isTrue(persistentNotSpecified || isPersistent(), String.format( + "Data Policy '%1$s' is invalid when persistent is false.", resolvedDataPolicy)); + } + else { + // NOTE otherwise, the Data Policy is with persistence, so... + Assert.isTrue(persistentNotSpecified || isNotPersistent(), String.format( + "Data Policy '%1$s' is invalid when persistent is true.", resolvedDataPolicy)); + } } + /** + * Returns true when the user explicitly specified a value for the persistent attribute and it is true. If the + * persistent attribute was not explicitly specified, then the persistence setting is implicitly undefined + * and will be determined by the Data Policy. + *

+ * @return true when the user specified an explicit value for the persistent attribute and it is true; + * false otherwise. + * @see #isNotPersistent() + */ + protected boolean isPersistent() { + return Boolean.TRUE.equals(persistent); + } + + /** + * Returns true when the user explicitly specified a value for the persistent attribute and it is false. If the + * persistent attribute was not explicitly specified, then the persistence setting is implicitly undefined + * and will be determined by the Data Policy. + *

+ * @return true when the user specified an explicit value for the persistent attribute and it is false; + * false otherwise. + * @see #isPersistent() + */ protected boolean isNotPersistent() { - return persistent != null && !persistent; + return Boolean.FALSE.equals(persistent); } /* (non-Javadoc) @@ -413,12 +440,11 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple */ @Override public void start() { - if (!ObjectUtils.isEmpty(gatewaySenders)) { synchronized (gatewaySenders) { for (Object obj : gatewaySenders) { GatewaySender gws = (GatewaySender) obj; - if (!gws.isManualStart() && !gws.isRunning()) { + if (!(gws.isManualStart() || gws.isRunning())) { gws.start(); } } @@ -435,9 +461,8 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple if (!ObjectUtils.isEmpty(gatewaySenders)) { synchronized (gatewaySenders) { for (Object obj : gatewaySenders) { - GatewaySender gws = (GatewaySender) obj; - gws.stop(); - } + ((GatewaySender) obj).stop(); + } } } this.running = false; @@ -475,4 +500,5 @@ public class RegionFactoryBean extends RegionLookupFactoryBean imple stop(); callback.run(); } + } diff --git a/src/main/java/org/springframework/data/gemfire/RegionLookupFactoryBean.java b/src/main/java/org/springframework/data/gemfire/RegionLookupFactoryBean.java index 5c51dfc2..f21843d7 100644 --- a/src/main/java/org/springframework/data/gemfire/RegionLookupFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/RegionLookupFactoryBean.java @@ -39,16 +39,19 @@ public class RegionLookupFactoryBean implements FactoryBean>, protected final Log log = LogFactory.getLog(getClass()); - private String beanName; private GemFireCache cache; - private String name; private Region region; + private String beanName; + private String name; + public void afterPropertiesSet() throws Exception { Assert.notNull(cache, "Cache property must be set"); + name = (!StringUtils.hasText(name) ? beanName : name); Assert.hasText(name, "Name (or beanName) property must be set"); + synchronized (cache) { region = cache.getRegion(name); if (region != null) { @@ -116,4 +119,5 @@ public class RegionLookupFactoryBean implements FactoryBean>, protected Region getRegion() { return region; } -} \ No newline at end of file + +} diff --git a/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java index bf6f16f6..50ff9cae 100644 --- a/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBean.java @@ -22,32 +22,35 @@ import com.gemstone.gemfire.cache.RegionFactory; /** * @author David Turanski - * + * @author John Blum */ public class ReplicatedRegionFactoryBean extends RegionFactoryBean { + @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { - DataPolicy dp = null; if (dataPolicy != null) { - dataPolicy = dataPolicy.toUpperCase(); - if ("EMPTY".equals(dataPolicy)) { - Assert.isTrue(persistent == null || !persistent, "Cannot have persistence on an empty region"); - dp = DataPolicy.EMPTY; + DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy); + + Assert.notNull(resolvedDataPolicy, String.format("Data Policy '%1$s' is invalid.", dataPolicy)); + + // Validate that the data-policy and persistent attributes are compatible when specified! + assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy); + + if (DataPolicy.EMPTY.equals(resolvedDataPolicy)) { + resolvedDataPolicy = DataPolicy.EMPTY; } else { - dp = new DataPolicyConverter().convert(dataPolicy); - Assert.notNull(dp, "Data policy " + dataPolicy + " is invalid"); - Assert.isTrue(dp.withReplication(), "Data policy " + dataPolicy - + " is invalid or unsupported in replicated regions"); - if (isPersistent()) { - Assert.isTrue(dp.withPersistence(), "Data policy " + dataPolicy - + " is invalid when persistent is false"); - } + // Validate that the user-defined Data Policy matches the appropriate Spring GemFire XML namespace + // configuration meta-data element for Region (i.e. )! + Assert.isTrue(resolvedDataPolicy.withReplication(), String.format("" + + "Data Policy '%1$s' is not supported in Replicated Regions.", resolvedDataPolicy)); } + + regionFactory.setDataPolicy(resolvedDataPolicy); } else { - dp = (isPersistent()) ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.REPLICATE; + regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.REPLICATE); } - regionFactory.setDataPolicy(dp); } + } diff --git a/src/test/java/org/springframework/data/gemfire/DataPolicyConverterTest.java b/src/test/java/org/springframework/data/gemfire/DataPolicyConverterTest.java index c9fe3d69..ee1ea18d 100644 --- a/src/test/java/org/springframework/data/gemfire/DataPolicyConverterTest.java +++ b/src/test/java/org/springframework/data/gemfire/DataPolicyConverterTest.java @@ -24,14 +24,14 @@ import com.gemstone.gemfire.cache.DataPolicy; /** * @author David Turanski - * + * @author John Blum */ public class DataPolicyConverterTest { private final DataPolicyConverter converter = new DataPolicyConverter(); protected int getDataPolicyEnumerationSize() { - for (byte ordinal = 0; true; ordinal++) { + for (byte ordinal = 0; ordinal < Byte.MAX_VALUE; ordinal++) { try { DataPolicy.fromOrdinal(ordinal); } @@ -39,6 +39,9 @@ public class DataPolicyConverterTest { return ordinal; } } + + throw new IndexOutOfBoundsException("The size of the Data Policy enumeration could not be determined" + + " because the ordinal based on Byte.MAX_VALUE was exhausted!"); } @Test @@ -63,4 +66,5 @@ public class DataPolicyConverterTest { assertNull(converter.convert("invalid")); assertNull(converter.convert(null)); } + } diff --git a/src/test/java/org/springframework/data/gemfire/LocalRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/LocalRegionFactoryBeanTest.java index 5e1aa71d..1a4b2702 100644 --- a/src/test/java/org/springframework/data/gemfire/LocalRegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/LocalRegionFactoryBeanTest.java @@ -17,18 +17,34 @@ package org.springframework.data.gemfire; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import org.junit.Test; import org.springframework.data.gemfire.support.AbstractRegionFactoryBeanTest; import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionFactory; /** + * The PartitionedRegionFactoryBeanTest class is a test suite of test cases testing the component functionality + * and correct behavior of the PartitionedRegionFactoryBean class. + *

* @author David Turanski - * + * @author John Blum + * @see org.mockito.Mockito + * @see org.junit.Test + * @see org.springframework.data.gemfire.PartitionedRegionFactoryBean + * @since 1.3.x */ +@SuppressWarnings("unchecked") public class LocalRegionFactoryBeanTest extends AbstractRegionFactoryBeanTest { + private final LocalRegionFactoryBean factoryBean = new LocalRegionFactoryBean(); + @SuppressWarnings("rawtypes") private RegionFactoryBeanConfig defaultConfig() { return new RegionFactoryBeanConfig(new LocalRegionFactoryBean(), "default") { @@ -42,24 +58,6 @@ public class LocalRegionFactoryBeanTest extends AbstractRegionFactoryBeanTest { @Override public void configureRegionFactoryBean() { - // TODO Auto-generated method stub - } - }; - } - - @SuppressWarnings("rawtypes") - private RegionFactoryBeanConfig emptyConfig() { - return new RegionFactoryBeanConfig(new LocalRegionFactoryBean(), "empty") { - - @Override - public void verify() { - Region region = regionFactoryBean.getRegion(); - assertEquals(DataPolicy.EMPTY, region.getAttributes().getDataPolicy()); - } - - @Override - public void configureRegionFactoryBean() { - regionFactoryBean.setDataPolicy("empty"); } }; } @@ -83,7 +81,102 @@ public class LocalRegionFactoryBeanTest extends AbstractRegionFactoryBeanTest { @Override protected void createRegionFactoryBeanConfigs() { addRFBConfig(defaultConfig()); - addRFBConfig(emptyConfig()); addRFBConfig(invalidConfig()); } + + protected RegionFactory createMockRegionFactory() { + return mock(RegionFactory.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithInvalidDataPolicyName() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "INVALID_DATA_POLICY_NAME"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'INVALID_DATA_POLICY_NAME' is invalid.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.NORMAL)); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PRELOADED)); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithInvalidDataPolicyRegionType() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "PARTITION"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'PARTITION' is not supported in Local Regions.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.NORMAL)); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PRELOADED)); + } + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.NORMAL)); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndNormalDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "Normal"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.NORMAL)); + } + + @Test + public void testResolveDataPolicyWhenNotPersistentAndNormalDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "NORMAL"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.NORMAL)); + } + + @Test + public void testResolveDataPolicyWhenPersistentAndNormalDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "NORMAL"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndPreloadedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "preloaded"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PRELOADED)); + } + + @Test + public void testResolveDataPolicyWhenNotPersistentAndPreloadedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "PreLoaded"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PRELOADED)); + } + + @Test + public void testResolveDataPolicyWhenPersistentAndPreloadedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "PRELOADED"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + } diff --git a/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java new file mode 100644 index 00000000..f8238e85 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/PartitionedRegionFactoryBeanTest.java @@ -0,0 +1,168 @@ +/* + * 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.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.RegionFactory; + +/** + * The PartitionedRegionFactoryBeanTest class is a test suite of test cases testing the component functionality + * and correct behavior of the PartitionedRegionFactoryBean class. + *

+ * @author John Blum + * @see org.mockito.Mockito + * @see org.junit.Test + * @see org.springframework.data.gemfire.PartitionedRegionFactoryBean + * @since 1.3.3 + */ +@SuppressWarnings("unchecked") +public class PartitionedRegionFactoryBeanTest { + + private final PartitionedRegionFactoryBean factoryBean = new PartitionedRegionFactoryBean(); + + protected RegionFactory createMockRegionFactory() { + return mock(RegionFactory.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithInvalidDataPolicyName() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "INVALID_DATA_POLICY_NAME"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'INVALID_DATA_POLICY_NAME' is invalid.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithInvalidDataPolicyRegionType() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "REPLICATE"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'REPLICATE' is not supported in Partitioned Regions.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION)); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "PARTITION"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION)); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndPersistentPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "PERSISTENT_PARTITION"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION)); + } + + @Test + public void testResolveDataPolicyWithPersistentFalseAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION)); + } + + @Test + public void testResolveDataPolicyWithPersistentTrueAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION)); + } + + @Test + public void testResolveDataPolicyWithPersistentFalseAndPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "PARTITION"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION)); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithPersistentFalseAndPersistentPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "PERSISTENT_PARTITION"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'PERSISTENT_PARTITION' is invalid when persistent is false.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION)); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithPersistentTrueAndPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "PARTITION"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'PARTITION' is invalid when persistent is true.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PARTITION)); + } + } + + @Test + public void testResolveDataPolicyWithPersistentTrueAndPersistentPartitionedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "PERSISTENT_PARTITION"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION)); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java new file mode 100644 index 00000000..5553f596 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/ReplicatedRegionFactoryBeanTest.java @@ -0,0 +1,204 @@ +/* + * 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.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.Test; + +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.RegionFactory; + +/** + * The ReplicatedRegionFactoryBeanTest class is a test suite of test cases testing the component functionality + * and correct behavior of the ReplicatedRegionFactoryBean class. + *

+ * @author John Blum + * @see org.mockito.Mockito + * @see org.junit.Test + * @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean + * @since 1.3.3 + */ +@SuppressWarnings("unchecked") +public class ReplicatedRegionFactoryBeanTest { + + private final ReplicatedRegionFactoryBean factoryBean = new ReplicatedRegionFactoryBean(); + + protected RegionFactory createMockRegionFactory() { + return mock(RegionFactory.class); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + + @Test + public void testResolveDataPolicyWhenNotPersistentAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + + @Test + public void testResolveDataPolicyWhenPersistentAndDataPolicyUnspecified() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, null); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + + @Test + public void testResolveDataPolicyWithPersistentUnspecifiedAndEmptyDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "EMPTY"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.EMPTY)); + } + + @Test + public void testResolveDataPolicyWhenNotPersistentAndEmptyDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "empty"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.EMPTY)); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWhenPersistentAndEmptyDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + try { + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "empty"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'EMPTY' is invalid when persistent is true.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.EMPTY)); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithPersistentUnspecifiedAndInvalidDataPolicyName() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "INVALID_DATA_POLICY_NAME"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'INVALID_DATA_POLICY_NAME' is invalid.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.REPLICATE)); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWithPersistentUnspecifiedAndInvalidDataPolicyRegionType() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.resolveDataPolicy(mockRegionFactory, null, "PARTITION"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'PARTITION' is not supported in Replicated Regions.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.PARTITION)); + } + } + + @Test + public void testResolveDataPolicyWhenPersistentUnspecifiedAndReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "REPLICATE"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + + @Test + public void testResolveDataPolicyWhenNotPersistentAndReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "REPLICATE"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWhenPersistentAndReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "REPLICATE"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'REPLICATE' is invalid when persistent is true.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + } + + @Test + public void testResolveDataPolicyWhenPersistentUnspecifiedAndPersistentReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.resolveDataPolicy(mockRegionFactory, null, "PERSISTENT_REPLICATE"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + + @Test(expected = IllegalArgumentException.class) + public void testResolveDataPolicyWhenNotPersistentAndPersistentReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + + try { + factoryBean.setPersistent(false); + factoryBean.resolveDataPolicy(mockRegionFactory, false, "PERSISTENT_REPLICATE"); + } + catch (IllegalArgumentException e) { + assertEquals("Data Policy 'PERSISTENT_REPLICATE' is invalid when persistent is false.", e.getMessage()); + throw e; + } + finally { + verify(mockRegionFactory, never()).setDataPolicy(null); + verify(mockRegionFactory, never()).setDataPolicy(eq(DataPolicy.REPLICATE)); + } + } + + @Test + public void testResolveDataPolicyWhenPersistentAndPersistentReplicatedDataPolicy() { + RegionFactory mockRegionFactory = createMockRegionFactory(); + factoryBean.setPersistent(true); + factoryBean.resolveDataPolicy(mockRegionFactory, true, "PERSISTENT_REPLICATE"); + verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE)); + } + +}