Completed Peer Cache Region Template testing for JIRA feature requests SGF-207 and SGF-254 adding support for template-defined Regions.

This commit is contained in:
John Blum
2014-08-27 00:04:39 -07:00
committed by John Blum
parent dab04833c9
commit 5919d87658
6 changed files with 588 additions and 280 deletions

View File

@@ -163,8 +163,8 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
}
if (attributes != null) {
Assert.state(!attributes.isLockGrantor() || scope.isGlobal(),
"Lock Grantor only applies to a global scoped region.");
Assert.state(!attributes.isLockGrantor() || (scope == null) || scope.isGlobal(),
"Lock Grantor only applies to a 'GLOBAL' scoped Region.");
}
postProcess(regionFactory);

View File

@@ -375,11 +375,9 @@ abstract class ParsingUtils {
static void parseScope(Element element, BeanDefinitionBuilder builder) {
String scopeAttributeValue = element.getAttribute("scope");
Scope scope = (StringUtils.hasText(scopeAttributeValue)
? Scope.fromString(scopeAttributeValue.toUpperCase().replace("-", "_"))
: Scope.DISTRIBUTED_ACK);
builder.addPropertyValue("scope", scope);
if (StringUtils.hasText(scopeAttributeValue)) {
builder.addPropertyValue("scope", Scope.fromString(scopeAttributeValue.toUpperCase().replace("-", "_")));
}
}
private static boolean parseExpiration(Element rootElement, String elementName, String propertyName,

View File

@@ -614,31 +614,33 @@ CustomExpiry Time to idle (or idle timeout) configuration for the region entries
</xsd:element>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="cloning-enabled" type="xsd:string" default="true">
<xsd:attribute name="cloning-enabled" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[[
Determines how fromDelta applies deltas to the local cache for delta propagation. When true, the updates are applied to a
clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.
Determines how fromDelta applies deltas to the local cache for delta propagation. When true, the updates are applied
to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place
in the cache. GemFire default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="close" type="xsd:string" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the defined region should be closed or not at shutdown. Close performs a local destroy but leaves behind the region
disk files. Additionally it notifies the listeners and callbacks.
Indicates whether the defined Region should be closed at shutdown. Close performs a local destroy but leaves behind
the Region disk files. Additionally, close notifies listeners and callbacks.
Default is false
Note: Regions are automatically closed when cache closes.
Note, Regions are automatically closed when the Cache closes.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="concurrency-checks-enabled" type="xsd:string" default="true">
<xsd:attribute name="concurrency-checks-enabled" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[[
Indicates whether concurrency checks (versioning) are enabled for the region
]]></xsd:documentation>
Determines whether members perform checks to provide consistent handling for concurrent or out-of-order updates to
distributed Regions. GemFire default is true.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="destroy" type="xsd:string" default="false">
@@ -661,12 +663,11 @@ Note this attribute only applies if a disk store is configured for this region.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="disk-synchronous" type="xsd:string" default="false">
<xsd:attribute name="disk-synchronous" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the writing to the disk is synchronous or not. Default is false, meaning asynchronous writing.
Note this attribute only applies if a disk store is configured for this region.
For Regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.
GemFire default is true.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -693,19 +694,19 @@ for the "same" Region (by name), then this can cause confusion or have unexpecte
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-jta" type="xsd:string" use="optional" default="false">
<xsd:attribute name="ignore-jta" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether operations on this region participates in active JTA transactions or ignores them and operates outside of transactions.
This is primarily used in cache loaders, writers, and listeners that need to perform non-transactional operations on a region,
such as caching a result set.
Indicates whether operations on this Region participates in active JTA transactions or ignores them and operates
outside of transactions. This is primarily used in cache loaders, writers, and listeners that need to perform
non-transactional operations on a Region, such as caching a result set. GemFire default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="initial-capacity" type="xsd:string" use="optional" default="16">
<xsd:attribute name="initial-capacity" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Sets the initial capacity (number of entries) for the region
Sets the initial capacity (number of entries) for the Region. GemFire default is 16.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -716,11 +717,12 @@ The fully qualified class name of the expected key type
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="load-factor" type="xsd:string" default="0.75">
<xsd:attribute name="load-factor" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[[
Together with the initial-capacity region attribute, sets the initial parameters on the underlying java.util.ConcurrentHashMap
used for storing region entries. This must be a floating point number between 0 and 1, inclusive.
Together with the initial-capacity Region attribute, sets the initial parameters on the underlying
java.util.ConcurrentHashMap used for storing Region entries. This must be a floating point number
between 0 and 1, inclusive. GemFire default value is 0.75.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -738,11 +740,11 @@ Note: Persistence for partitioned regions is supported only from GemFire 6.5 onw
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="statistics" type="xsd:string" default="false">
<xsd:attribute name="statistics" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether statistics are enabled or disabled for this region and its entries.
Default is false, meaning statistics are disabled.
Boolean specifying whether to gather statistics on the Region. Statistics must be enabled to use expiration on the
Region. GemFire default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -753,8 +755,7 @@ Specifies the parent, template Region from which to inherit the Region attribute
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="value-constraint" type="xsd:string"
use="optional">
<xsd:attribute name="value-constraint" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully qualified class name of the expected value type
@@ -791,8 +792,7 @@ The name of the region definition.]]>
<xsd:complexContent>
<xsd:extension base="baseReadOnlyRegionType">
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="cache-loader" type="beanDeclarationType"
minOccurs="0" maxOccurs="1">
<xsd:element name="cache-loader" type="beanDeclarationType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation source="com.gemstone.gemfire.cache.CacheLoader"><![CDATA[
The cache loader definition for this region. A cache loader allows data to be placed into a region.
@@ -804,8 +804,7 @@ The cache loader definition for this region. A cache loader allows data to be pl
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="cache-writer" type="beanDeclarationType"
minOccurs="0" maxOccurs="1">
<xsd:element name="cache-writer" type="beanDeclarationType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation source="com.gemstone.gemfire.cache.CacheWriter"><![CDATA[
The cache writer definition for this region. A cache writer acts as a dedicated synchronous listener that is notified
@@ -838,23 +837,25 @@ A comma delimited list of required role names
<xsd:attribute name="loss-action" type="xsd:string" default="no-access">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set one of the following values to specify how access to the region is affected when one or more required roles are lost:
(full-access, limited-access, no-access, or reconnect).
Set one of the following values to specify how access to the Region is affected when one or more required roles are lost:
(full-access, limited-access, no-access, or reconnect). GemFire default is 'no-access' when required-roles is
specified, and in SDG, the required-roles attribute is required.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resumption-action" type="xsd:string" default="reinitialize">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies how the region is affected by resumption of reliability when one or more missing required roles return to the distributed membership:
(none or reinitialize).
Specifies how the Region is affected by resumption of reliability when one or more missing required roles return
to the distributed membership: (none or reinitialize). GemFire default is reinitialize when required-roles is
specified, and in SDG, the required-roles attribute is required.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="gateway-sender" type="baseGatewaySenderType" />
<xsd:element name="gateway-sender" type="baseGatewaySenderType"/>
<xsd:element name="gateway-sender-ref">
<xsd:complexType>
<xsd:attribute name="bean" type="xsd:string" use="optional">
@@ -869,7 +870,7 @@ use inner bean declarations.
</xsd:element>
</xsd:choice>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="async-event-queue" type="baseAsyncEventQueueType" />
<xsd:element name="async-event-queue" type="baseAsyncEventQueueType"/>
<xsd:element name="async-event-queue-ref">
<xsd:complexType>
<xsd:attribute name="bean" type="xsd:string" use="optional">
@@ -898,10 +899,11 @@ Specifies if WAN Gateway hub id if enable-gateway is true. (Deprecated since Gem
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="index-update-type" use="optional" default="synchronous">
<xsd:attribute name="index-update-type" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies whether Region indexes are maintained synchronously with region modifications, or asynchronously in a background thread.
Specifies whether Region indexes are maintained synchronously with Region modifications, or asynchronously
in a background thread. GemFire default is synchronous.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
@@ -986,19 +988,21 @@ Required for subregions.
</xsd:attributeGroup>
<!-- -->
<xsd:attributeGroup name="distributedRegionAttributes">
<xsd:attribute name="enable-async-conflation" type="xsd:string" default="false">
<xsd:attribute name="enable-async-conflation" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
For TCP/IP distributions between peers, specifies whether to allow aggregation of asynchronous messages sent by the producer member for the region.
This is a special-purpose boolean attribute that applies only when asynchronous queues are used for slow consumers
]]></xsd:documentation>
For TCP/IP distributions between peers, specifies whether to allow aggregation of asynchronous messages sent
by the producer member for the Region. This is a special-purpose boolean attribute that applies only when
asynchronous queues are used for slow consumers. A false value disables conflation so that all asynchronous messages
are sent individually. GemFire default is false (even though GemFire User Guide states it is true).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="enable-subscription-conflation" type="xsd:string" default="false">
<xsd:attribute name="enable-subscription-conflation" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the region can conflate its messages to the client.
]]></xsd:documentation>
Indicates whether the Region can conflate its messages to the client. GemFire default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="multicast-enabled" type="xsd:string">
@@ -1027,15 +1031,14 @@ up-to-date copy of the data.
<xsd:complexContent>
<xsd:extension base="baseRegionType">
<xsd:sequence>
<xsd:element name="subscription" minOccurs="0"
maxOccurs="1">
<xsd:element name="subscription" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Subscription policy for the replicated region.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="type" type="subscriptionPolicyType" />
<xsd:attribute name="type" type="subscriptionPolicyType"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="eviction" minOccurs="0" maxOccurs="1">
@@ -1047,8 +1050,7 @@ Eviction policy for the replicated region.
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="evictionType">
<xsd:attribute name="action" type="evictionActionType"
fixed="OVERFLOW_TO_DISK">
<xsd:attribute name="action" type="evictionActionType" fixed="OVERFLOW_TO_DISK">
<xsd:annotation>
<xsd:documentation><![CDATA[
The action to take when performing eviction.
@@ -1059,7 +1061,7 @@ The action to take when performing eviction.
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:group ref="subRegionGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:group ref="subRegionGroup" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attributeGroup ref="distributedRegionAttributes"/>
<xsd:attribute name="concurrency-level">
@@ -1086,10 +1088,11 @@ stictly necessary, but if set, then the value must agree with the 'persistent' a
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="is-lock-grantor" type="xsd:string" use="optional" default="false">
<xsd:attribute name="is-lock-grantor" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the region is a lock grantor.This attribute is only relevant for regions with global scope, as only they allow locking.
Indicates whether the Region is a lock grantor. This attribute is only relevant for Regions with global scope,
as only they allow locking. GemFire default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -1176,8 +1179,7 @@ in different members, for high availability in case of an application failure.
<xsd:complexContent>
<xsd:extension base="baseRegionType">
<xsd:sequence>
<xsd:element name="partition-resolver" type="beanDeclarationType"
minOccurs="0" maxOccurs="1">
<xsd:element name="partition-resolver" type="beanDeclarationType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation source="com.gemstone.gemfire.cache.PartitionResolver"><![CDATA[
The partition resolver definition for this region, allowing for custom partitioning. GemFire uses the resolver to
@@ -1223,8 +1225,7 @@ use inner bean declarations.
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="fixed-partition" minOccurs="0"
maxOccurs="unbounded">
<xsd:element name="fixed-partition" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation
source="com.gemstone.gemfire.cache.partition.FixedPartitionAttributes"><![CDATA[
@@ -1260,8 +1261,7 @@ Specifies the number of buckets to allocate to the fixed partition
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="subscription" minOccurs="0"
maxOccurs="1">
<xsd:element name="subscription" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Subscription policy for the partitioned region.
@@ -1280,8 +1280,7 @@ Eviction policy for the partitioned region.
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="evictionType">
<xsd:attribute name="action" type="evictionActionType"
default="LOCAL_DESTROY">
<xsd:attribute name="action" type="evictionActionType" default="LOCAL_DESTROY">
<xsd:annotation>
<xsd:documentation><![CDATA[
The action to take when performing eviction.
@@ -1294,11 +1293,12 @@ The action to take when performing eviction.
</xsd:element>
</xsd:sequence>
<xsd:attributeGroup ref="distributedRegionAttributes" />
<xsd:attribute name="copies" use="optional" default="0" type="xsd:string">
<xsd:attribute name="copies" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The number of copies (0-3) for each partition for high-availability. By default, no copies are created meaning there is no
redundancy. Each copy provides extra backup at the expense of extra storages.
The number of copies (0-3) of each partition for high-availability. By default, no copies are created meaning
there is no redundancy. Each copy provides extra backup at the expense of extra storage. GemFire default is 0, or
no redundancy.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
@@ -1326,9 +1326,9 @@ stictly necessary, but if set, then the value must agree with the 'persistent' a
<xsd:attribute name="local-max-memory" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum amount of memory, in megabytes, to be used by the region in this process. If not set, a default of 90%
The maximum amount of memory, in megabytes, to be used by the Region in this process. If not set, a default of 90%
of available heap is used.
]]></xsd:documentation>
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="total-max-memory" type="xsd:string" use="optional">
@@ -1343,24 +1343,26 @@ Note: This setting must be the same in all processes using the region.
<xsd:attribute name="total-buckets" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The total number of hash buckets to be used by the region in all processes.
The total number of hash buckets to be used by the Region in all processes.
A bucket is the smallest unit of data management in a partitioned region. Entries are stored in buckets and buckets may
move from one VM to another. Buckets may also have copies, depending on redundancy to provide high availability in the
face of VM failure.
The number of buckets should be prime and as a rough guide at the least four times the number of partition VMs. However
, there is significant overhead to managing a bucket, particularly for higher values of redundancy.
A Bucket is the smallest unit of data management in a Partitioned Region. Entries are stored in Buckets and Buckets may
move from one VM to another. Buckets may also have copies, depending on redundancy to provide high availability in the
face of VM failure.
Note: This setting must be the same in all processes using the region.
The number of Buckets should be prime, and as a rough guide, at the least four times the number of partition VMs.
However, there is significant overhead to managing a Bucket, particularly for higher values of redundancy.
Note: This setting must be the same in all processes using the Region.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="recovery-delay" type="xsd:string" use="optional" default="-1">
<xsd:attribute name="recovery-delay" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The delay in milliseconds that existing members will wait before satisfying redundancy after another member crashes.
-1 (the default) indicates that redundancy will not be recovered after a failure.
]]></xsd:documentation>
Applies when copies is greater than zero. The number of milliseconds to wait after a member crashes
before reestablishing redundancy for the Region. A setting of -1 disables automatic recovery of redundancy
after member failure. Gemfire default is -1.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="shortcut" use="optional">
@@ -1386,12 +1388,14 @@ The RegionShortcut for this region. Allows easy initialization of the region bas
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="startup-recovery-delay" type="xsd:string" use="optional" default="-1">
<xsd:attribute name="startup-recovery-delay" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The delay in milliseconds that new members will wait before satisfying redundancy. -1 indicates that adding new members
will not trigger redundancy recovery. The default is to recover redundancy immediately when a new member is added.
]]></xsd:documentation>
Applies when copies is greater than zero. The number of milliseconds a newly started member should wait
before trying to satisfy redundancy of Region data stored on other members. A setting of -1 disables automatic recovery
of redundancy after new members join. GemFire default is 0, meaning the default is to recover redundancy immediately
when a new member joins the cluster.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
@@ -1937,8 +1941,7 @@ Eviction policy for the partitioned region.
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="evictionType">
<xsd:attribute name="action" type="evictionActionType"
default="LOCAL_DESTROY">
<xsd:attribute name="action" type="evictionActionType" default="LOCAL_DESTROY">
<xsd:annotation>
<xsd:documentation><![CDATA[
The action to take when performing eviction.
@@ -1972,8 +1975,7 @@ cache to differ from other caches.
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="pool-name" type="xsd:string"
use="optional">
<xsd:attribute name="pool-name" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the pool used by this client. If not set, a default pool (initialized when using client-cache) will be used.

View File

@@ -22,7 +22,10 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeNotNull;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
@@ -36,7 +39,9 @@ import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitia
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.gemstone.gemfire.cache.CacheListener;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheLoaderException;
import com.gemstone.gemfire.cache.DataPolicy;
@@ -44,18 +49,25 @@ import com.gemstone.gemfire.cache.EntryOperation;
import com.gemstone.gemfire.cache.EvictionAction;
import com.gemstone.gemfire.cache.EvictionAlgorithm;
import com.gemstone.gemfire.cache.EvictionAttributes;
import com.gemstone.gemfire.cache.ExpirationAction;
import com.gemstone.gemfire.cache.ExpirationAttributes;
import com.gemstone.gemfire.cache.InterestPolicy;
import com.gemstone.gemfire.cache.LoaderHelper;
import com.gemstone.gemfire.cache.LossAction;
import com.gemstone.gemfire.cache.MembershipAttributes;
import com.gemstone.gemfire.cache.PartitionResolver;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionAttributes;
import com.gemstone.gemfire.cache.ResumptionAction;
import com.gemstone.gemfire.cache.Scope;
import com.gemstone.gemfire.cache.SubscriptionAttributes;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
import com.gemstone.gemfire.cache.partition.PartitionListener;
import com.gemstone.gemfire.cache.partition.PartitionListenerAdapter;
import com.gemstone.gemfire.cache.util.CacheListenerAdapter;
import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
import com.gemstone.gemfire.cache.util.ObjectSizer;
import com.gemstone.gemfire.distributed.Role;
/**
* The TemplateRegionsNamespaceTests class...
@@ -63,9 +75,12 @@ import com.gemstone.gemfire.cache.util.CacheWriterAdapter;
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.context.ApplicationContext
* @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
* @see com.gemstone.gemfire.cache.Cache
* @see com.gemstone.gemfire.cache.Region
* @since 1.5.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@@ -76,14 +91,185 @@ public class TemplateRegionsNamespaceTests {
@Autowired
private ApplicationContext applicationContext;
@Resource(name = "SimpleReplicateRegion")
private Region<Integer, String> simpleReplicateRegion;
@Resource(name = "NonTemplateBasedReplicateRegion")
private Region<Integer, String> nonTemplateBasedReplicateRegion;
@Resource(name = "InheritedReplicateRegion")
private Region<Long, String> inheritedReplicateRegion;
@Resource(name = "TemplateBasedReplicateRegion")
private Region<String, Object> templateBasedReplicateRegion;
@Resource(name = "ComplexReplicateRegion")
private Region complexReplicateRegion;
@Resource(name = "/TemplateBasedReplicateRegion/TemplateBasedReplicateSubRegion")
private Region<Integer, String> templateBasedReplicateSubRegion;
@Resource(name = "TemplateBasedPartitionRegion")
private Region<Date, Object> templateBasedPartitionRegion;
@Resource(name = "TemplateBasedLocalRegion")
private Region<Long, String> templateBasedLocalRegion;
protected void assertAsyncEventQueues(final Region<?, ?> region, final String... expectedNames) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getAsyncEventQueueIds());
assertEquals(expectedNames.length, region.getAttributes().getAsyncEventQueueIds().size());
for (String asyncEventQueueId : region.getAttributes().getAsyncEventQueueIds()) {
assertTrue(Arrays.asList(expectedNames).contains(asyncEventQueueId));
}
}
protected void assertCacheListeners(final Region<?, ?> region, final String... expectedNames) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getCacheListeners());
assertEquals(expectedNames.length, region.getAttributes().getCacheListeners().length);
for (CacheListener cacheListener : region.getAttributes().getCacheListeners()) {
assertTrue(cacheListener instanceof TestCacheListener);
assertTrue(Arrays.asList(expectedNames).contains(cacheListener.toString()));
}
}
protected void assertCacheLoader(final Region<?, ?> region, final String expectedName) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertTrue(region.getAttributes().getCacheLoader() instanceof TestCacheLoader);
assertEquals(expectedName, region.getAttributes().getCacheLoader().toString());
}
protected void assertCacheWriter(final Region<?, ?> region, final String expectedName) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertTrue(region.getAttributes().getCacheWriter() instanceof TestCacheWriter);
assertEquals(expectedName, region.getAttributes().getCacheWriter().toString());
}
protected void assertDefaultEvictionAttributes(final EvictionAttributes evictionAttributes) {
assumeNotNull(evictionAttributes);
assertEvictionAttributes(evictionAttributes, EvictionAction.NONE, EvictionAlgorithm.NONE, 0, null);
}
protected void assertEvictionAttributes(final EvictionAttributes evictionAttributes,
final EvictionAction expectedAction,
final EvictionAlgorithm expectedAlgorithm,
final int expectedMaximum,
final ObjectSizer expectedObjectSizer)
{
assertNotNull("The 'EvictionAttributes' must not be null!", evictionAttributes);
assertEquals(expectedAction, evictionAttributes.getAction());
assertEquals(expectedAlgorithm, evictionAttributes.getAlgorithm());
assertEquals(expectedMaximum, evictionAttributes.getMaximum());
assertEquals(expectedObjectSizer, evictionAttributes.getObjectSizer());
}
protected void assertDefaultExpirationAttributes(final ExpirationAttributes expirationAttributes) {
assumeNotNull(expirationAttributes);
assertEquals(ExpirationAction.INVALIDATE, expirationAttributes.getAction());
assertEquals(0, expirationAttributes.getTimeout());
}
protected void assertExpirationAttributes(final ExpirationAttributes expirationAttributes,
final ExpirationAction expectedAction,
final int expectedTimeout)
{
assertNotNull("The 'ExpirationAttributes' must not be null!", expirationAttributes);
assertEquals(expectedAction, expirationAttributes.getAction());
assertEquals(expectedTimeout, expirationAttributes.getTimeout());
}
protected void assertGatewaySenders(final Region<?, ?> region, final String... gatewaySenderNames) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getGatewaySenderIds());
assertEquals(gatewaySenderNames.length, region.getAttributes().getGatewaySenderIds().size());
for (String gatewaySenderId : region.getAttributes().getGatewaySenderIds()) {
assertTrue(Arrays.asList(gatewaySenderNames).contains(gatewaySenderId));
}
}
protected void assertDefaultMembershipAttributes(final MembershipAttributes membershipAttributes) {
assumeNotNull(membershipAttributes);
assertMembershipAttributes(membershipAttributes, LossAction.FULL_ACCESS, ResumptionAction.NONE);
}
protected void assertMembershipAttributes(final MembershipAttributes membershipAttributes,
final LossAction expectedLossAction,
final ResumptionAction expectedResumptionAction,
final String... expectedRequiredRoles)
{
assertNotNull("The 'MembershipAttributes' must not be null!", membershipAttributes);
assertEquals(expectedLossAction, membershipAttributes.getLossAction());
assertEquals(expectedResumptionAction, membershipAttributes.getResumptionAction());
if (!ObjectUtils.isEmpty(expectedRequiredRoles)) {
for (Role membershipRole : membershipAttributes.getRequiredRoles()) {
assertTrue(String.format("Role '%1$s' was not found!", membershipRole),
Arrays.asList(expectedRequiredRoles).contains(membershipRole.getName()));
}
}
}
protected void assertPartitionListener(final Region<?, ?> region, final String... expectedNames) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getPartitionAttributes());
assertNotNull(region.getAttributes().getPartitionAttributes().getPartitionListeners());
assertEquals(expectedNames.length, region.getAttributes().getPartitionAttributes().getPartitionListeners().length);
for (PartitionListener partitionListener : region.getAttributes().getPartitionAttributes().getPartitionListeners()) {
assertTrue(partitionListener instanceof TestPartitionListener);
assertTrue(Arrays.asList(expectedNames).contains(partitionListener.toString()));
}
}
protected void assertPartitionResolver(final Region<?, ?> region, final String expectedName) {
assertNotNull(region);
assertNotNull(region.getAttributes());
assertNotNull(region.getAttributes().getPartitionAttributes());
assertTrue(
region.getAttributes().getPartitionAttributes().getPartitionResolver() instanceof TestPartitionResolver);
assertEquals(expectedName, region.getAttributes().getPartitionAttributes().getPartitionResolver().toString());
}
protected void assertDefaultRegionAttributes(final Region region) {
assertNotNull("The Region must not be null!", region);
assertNotNull(String.format("The Region (%1$s) must have 'RegionAttributes' defined!",
region.getFullPath()), region.getAttributes());
assertNull(region.getAttributes().getCompressor());
assertNull(region.getAttributes().getCustomEntryIdleTimeout());
assertNull(region.getAttributes().getCustomEntryTimeToLive());
assertNull(region.getAttributes().getDiskStoreName());
assertFalse(region.getAttributes().getEnableGateway());
assertNullEmpty(region.getAttributes().getGatewayHubId());
assertFalse(region.getAttributes().getMulticastEnabled());
assertNullEmpty(region.getAttributes().getPoolName());
assertDefaultExpirationAttributes(region.getAttributes().getRegionTimeToLive());
assertDefaultExpirationAttributes(region.getAttributes().getRegionIdleTimeout());
}
protected void assertDefaultSubscriptionAttributes(final SubscriptionAttributes subscriptionAttributes) {
assumeNotNull(subscriptionAttributes);
assertSubscriptionAttributes(subscriptionAttributes, InterestPolicy.CACHE_CONTENT);
}
protected void assertSubscriptionAttributes(final SubscriptionAttributes subscriptionAttributes,
final InterestPolicy expectedInterestPolicy)
{
assertNotNull("The 'SubscriptionAttributes' must not be null!", subscriptionAttributes);
assertEquals(expectedInterestPolicy, subscriptionAttributes.getInterestPolicy());
}
protected static void assertEmpty(final Object[] array) {
assertTrue((array == null || array.length == 0));
}
protected static void assertEmpty(final Iterable<?> collection) {
assertTrue(collection == null || !collection.iterator().hasNext());
}
protected static void assertNullEmpty(final String value) {
assertFalse(StringUtils.hasText(value));
}
protected static void assertRegionMetaData(final Region<?, ?> region, final String expectedRegionName) {
assertRegionMetaData(region, expectedRegionName, Region.SEPARATOR + expectedRegionName);
@@ -98,56 +284,14 @@ public class TemplateRegionsNamespaceTests {
expectedRegionName), region.getAttributes());
}
@SuppressWarnings("deprecation")
protected static <K, V> void assertBaseRegionAttributes(final Region<K, V> region) {
assertNotNull("The Region must not be null!", region);
RegionAttributes<K, V> regionAttributes = region.getAttributes();
assertNotNull("The Region must have RegionAttributes defined!", regionAttributes);
assertTrue(regionAttributes.getCloningEnabled());
assertFalse(regionAttributes.getConcurrencyChecksEnabled());
assertTrue(regionAttributes.isDiskSynchronous());
assertTrue(regionAttributes.getIgnoreJTA());
assertEquals(Long.class, regionAttributes.getKeyConstraint());
assertEquals(0.90f, regionAttributes.getLoadFactor());
assertFalse(regionAttributes.getDataPolicy().withPersistence());
assertTrue(regionAttributes.getStatisticsEnabled());
assertEquals(String.class, regionAttributes.getValueConstraint());
assertTrue(regionAttributes.getIndexMaintenanceSynchronous());
assertTrue(ObjectUtils.isEmpty(regionAttributes.getCacheListeners()));
assertNotNull(regionAttributes.getCacheLoader());
assertTrue(regionAttributes.getCacheLoader() instanceof TestCacheLoader);
assertEquals("X", regionAttributes.getCacheLoader().toString());
assertNotNull(regionAttributes.getCacheWriter());
assertTrue(regionAttributes.getCacheWriter() instanceof TestCacheWriter);
assertEquals("Y", regionAttributes.getCacheWriter().toString());
}
protected static <K, V> void assertBaseReplicateRegionAttributes(final Region<K, V> replicateRegion) {
assertBaseRegionAttributes(replicateRegion);
assertEquals(2, replicateRegion.getAttributes().getConcurrencyLevel());
assertTrue(replicateRegion.getAttributes().getEnableAsyncConflation());
assertTrue(replicateRegion.getAttributes().getEnableSubscriptionConflation());
EvictionAttributes evictionAttributes = replicateRegion.getAttributes().getEvictionAttributes();
assertNotNull(evictionAttributes);
assertEquals(EvictionAction.OVERFLOW_TO_DISK, evictionAttributes.getAction());
assertEquals(EvictionAlgorithm.LRU_ENTRY, evictionAttributes.getAlgorithm());
assertEquals(1000, evictionAttributes.getMaximum());
SubscriptionAttributes subscriptionAttributes = replicateRegion.getAttributes().getSubscriptionAttributes();
assertNotNull(subscriptionAttributes);
assertEquals(InterestPolicy.CACHE_CONTENT, subscriptionAttributes.getInterestPolicy());
}
@Test
public void testNoAbstractRegionTemplateBeans() {
String[] beanNames = {
"BaseRegion", "ExtendedRegionWithOverrides", "BaseReplicateRegion", "BasePartitionRegion", "BaseLocalRegion"
"BaseRegionTemplate",
"ExtendedRegionTemplate",
"ReplicateRegionTemplate",
"PartitionRegionTemplate",
"LocalRegionTemplate"
};
for (String beanName : beanNames) {
@@ -156,7 +300,7 @@ public class TemplateRegionsNamespaceTests {
try {
applicationContext.getBean(beanName);
fail(String.format("The abstract bean definition '%1$s' should not exists as a bean in the Spring context!",
fail(String.format("The abstract bean definition '%1$s' should not exist as a bean in the Spring context!",
beanName));
}
catch (BeansException ignore) {
@@ -167,74 +311,196 @@ public class TemplateRegionsNamespaceTests {
}
@Test
public void testSimpleReplicateRegion() {
assertRegionMetaData(simpleReplicateRegion, "SimpleReplicateRegion");
assertEquals(DataPolicy.PERSISTENT_REPLICATE, simpleReplicateRegion.getAttributes().getDataPolicy());
assertEquals(8, simpleReplicateRegion.getAttributes().getConcurrencyLevel());
assertEquals(Integer.class, simpleReplicateRegion.getAttributes().getKeyConstraint());
assertTrue(simpleReplicateRegion.getAttributes().isLockGrantor());
assertEquals(Scope.GLOBAL, simpleReplicateRegion.getAttributes().getScope());
assertNull(simpleReplicateRegion.getAttributes().getValueConstraint());
assertNotNull(simpleReplicateRegion.getAttributes().getCacheListeners());
assertEquals(1, simpleReplicateRegion.getAttributes().getCacheListeners().length);
assertTrue(simpleReplicateRegion.getAttributes().getCacheListeners()[0] instanceof TestCacheListener);
assertEquals("Simple", simpleReplicateRegion.getAttributes().getCacheListeners()[0].toString());
assertNull(simpleReplicateRegion.getAttributes().getCacheLoader());
assertNull(simpleReplicateRegion.getAttributes().getCacheWriter());
public void testNonTemplateBasedReplicateRegion() {
assertRegionMetaData(nonTemplateBasedReplicateRegion, "NonTemplateBasedReplicateRegion");
assertDefaultRegionAttributes(nonTemplateBasedReplicateRegion);
assertEmpty(nonTemplateBasedReplicateRegion.getAttributes().getAsyncEventQueueIds());
assertEmpty(nonTemplateBasedReplicateRegion.getAttributes().getCacheListeners());
assertCacheLoader(nonTemplateBasedReplicateRegion, "ABC");
assertNull(nonTemplateBasedReplicateRegion.getAttributes().getCacheWriter());
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getCloningEnabled());
assertTrue(nonTemplateBasedReplicateRegion.getAttributes().getConcurrencyChecksEnabled());
assertEquals(12, nonTemplateBasedReplicateRegion.getAttributes().getConcurrencyLevel());
assertEquals(DataPolicy.REPLICATE, nonTemplateBasedReplicateRegion.getAttributes().getDataPolicy());
assertTrue(nonTemplateBasedReplicateRegion.getAttributes().isDiskSynchronous());
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getEnableAsyncConflation());
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getEnableSubscriptionConflation());
assertDefaultEvictionAttributes(nonTemplateBasedReplicateRegion.getAttributes().getEvictionAttributes());
assertDefaultExpirationAttributes(nonTemplateBasedReplicateRegion.getAttributes().getEntryIdleTimeout());
assertDefaultExpirationAttributes(nonTemplateBasedReplicateRegion.getAttributes().getEntryTimeToLive());
assertEmpty(nonTemplateBasedReplicateRegion.getAttributes().getGatewaySenderIds());
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getIgnoreJTA());
assertTrue(nonTemplateBasedReplicateRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(97, nonTemplateBasedReplicateRegion.getAttributes().getInitialCapacity());
assertNull(nonTemplateBasedReplicateRegion.getAttributes().getKeyConstraint());
assertEquals("0.65", String.valueOf(nonTemplateBasedReplicateRegion.getAttributes().getLoadFactor()));
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().isLockGrantor());
assertDefaultMembershipAttributes(nonTemplateBasedReplicateRegion.getAttributes().getMembershipAttributes());
assertNull(nonTemplateBasedReplicateRegion.getAttributes().getPartitionAttributes());
assertEquals(Scope.DISTRIBUTED_NO_ACK, nonTemplateBasedReplicateRegion.getAttributes().getScope());
assertFalse(nonTemplateBasedReplicateRegion.getAttributes().getStatisticsEnabled());
assertDefaultSubscriptionAttributes(nonTemplateBasedReplicateRegion.getAttributes().getSubscriptionAttributes());
assertNull(nonTemplateBasedReplicateRegion.getAttributes().getValueConstraint());
}
@Test
public void testInheritedReplicateRegion() {
assertRegionMetaData(inheritedReplicateRegion, "InheritedReplicateRegion");
assertEquals(Scope.DISTRIBUTED_ACK, inheritedReplicateRegion.getAttributes().getScope());
assertBaseReplicateRegionAttributes(inheritedReplicateRegion);
public void testTemplateBasedReplicateRegion() {
assertRegionMetaData(templateBasedReplicateRegion, "TemplateBasedReplicateRegion");
assertDefaultRegionAttributes(templateBasedReplicateRegion);
assertEmpty(templateBasedReplicateRegion.getAttributes().getAsyncEventQueueIds());
assertCacheListeners(templateBasedReplicateRegion, "XYZ");
assertCacheLoader(templateBasedReplicateRegion, "dbLoader");
assertNull(templateBasedReplicateRegion.getAttributes().getCacheWriter());
assertTrue(templateBasedReplicateRegion.getAttributes().getCloningEnabled());
assertFalse(templateBasedReplicateRegion.getAttributes().getConcurrencyChecksEnabled());
assertEquals(24, templateBasedReplicateRegion.getAttributes().getConcurrencyLevel());
assertEquals(DataPolicy.REPLICATE, templateBasedReplicateRegion.getAttributes().getDataPolicy());
assertFalse(templateBasedReplicateRegion.getAttributes().isDiskSynchronous());
assertFalse(templateBasedReplicateRegion.getAttributes().getEnableAsyncConflation());
assertTrue(templateBasedReplicateRegion.getAttributes().getEnableSubscriptionConflation());
assertEvictionAttributes(templateBasedReplicateRegion.getAttributes().getEvictionAttributes(),
EvictionAction.OVERFLOW_TO_DISK, EvictionAlgorithm.LRU_ENTRY, 2024, null);
assertExpirationAttributes(templateBasedReplicateRegion.getAttributes().getEntryIdleTimeout(),
ExpirationAction.DESTROY, 600);
assertExpirationAttributes(templateBasedReplicateRegion.getAttributes().getEntryTimeToLive(),
ExpirationAction.INVALIDATE, 300);
assertEmpty(templateBasedReplicateRegion.getAttributes().getGatewaySenderIds());
assertTrue(templateBasedReplicateRegion.getAttributes().getIgnoreJTA());
assertTrue(templateBasedReplicateRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(51, templateBasedReplicateRegion.getAttributes().getInitialCapacity());
assertEquals(String.class, templateBasedReplicateRegion.getAttributes().getKeyConstraint());
assertEquals("0.85", String.valueOf(templateBasedReplicateRegion.getAttributes().getLoadFactor()));
assertTrue(templateBasedReplicateRegion.getAttributes().isLockGrantor());
assertDefaultMembershipAttributes(templateBasedReplicateRegion.getAttributes().getMembershipAttributes());
assertNull(templateBasedReplicateRegion.getAttributes().getPartitionAttributes());
assertEquals(Scope.GLOBAL, templateBasedReplicateRegion.getAttributes().getScope());
assertTrue(templateBasedReplicateRegion.getAttributes().getStatisticsEnabled());
assertSubscriptionAttributes(templateBasedReplicateRegion.getAttributes().getSubscriptionAttributes(),
InterestPolicy.CACHE_CONTENT);
assertEquals(Object.class, templateBasedReplicateRegion.getAttributes().getValueConstraint());
}
@Test
@SuppressWarnings("deprecation")
public void testComplexReplicateRegion() {
assertRegionMetaData(complexReplicateRegion, "ComplexReplicateRegion");
assertEquals(DataPolicy.PERSISTENT_REPLICATE, complexReplicateRegion.getAttributes().getDataPolicy());
assertEquals(Scope.DISTRIBUTED_ACK, complexReplicateRegion.getAttributes().getScope());
assertFalse(complexReplicateRegion.getAttributes().getCloningEnabled());
assertEquals(2, complexReplicateRegion.getAttributes().getConcurrencyLevel());
assertTrue(complexReplicateRegion.getAttributes().isDiskSynchronous());
assertFalse(complexReplicateRegion.getAttributes().getEnableAsyncConflation());
assertTrue(complexReplicateRegion.getAttributes().getEnableSubscriptionConflation());
assertFalse(complexReplicateRegion.getAttributes().getIgnoreJTA());
assertEquals(1000, complexReplicateRegion.getAttributes().getInitialCapacity());
assertEquals(Integer.class, complexReplicateRegion.getAttributes().getKeyConstraint());
assertEquals(0.90f, complexReplicateRegion.getAttributes().getLoadFactor());
assertTrue(complexReplicateRegion.getAttributes().getStatisticsEnabled());
assertTrue(complexReplicateRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(String.class, complexReplicateRegion.getAttributes().getValueConstraint());
assertNotNull(complexReplicateRegion.getAttributes().getCacheListeners());
assertEquals(1, complexReplicateRegion.getAttributes().getCacheListeners().length);
assertTrue(complexReplicateRegion.getAttributes().getCacheListeners()[0] instanceof TestCacheListener);
assertEquals("ComplexListener", complexReplicateRegion.getAttributes().getCacheListeners()[0].toString());
assertNotNull(complexReplicateRegion.getAttributes().getCacheLoader());
assertEquals("ComplexLoader", complexReplicateRegion.getAttributes().getCacheLoader().toString());
assertNotNull(complexReplicateRegion.getAttributes().getCacheWriter());
assertEquals("Y", complexReplicateRegion.getAttributes().getCacheWriter().toString());
EvictionAttributes evictionAttributes = complexReplicateRegion.getAttributes().getEvictionAttributes();
assertNotNull(evictionAttributes);
assertEquals(EvictionAction.OVERFLOW_TO_DISK, evictionAttributes.getAction());
assertEquals(EvictionAlgorithm.LRU_ENTRY, evictionAttributes.getAlgorithm());
assertEquals(1024, evictionAttributes.getMaximum());
SubscriptionAttributes subscriptionAttributes = complexReplicateRegion.getAttributes().getSubscriptionAttributes();
assertNotNull(subscriptionAttributes);
assertEquals(InterestPolicy.ALL, subscriptionAttributes.getInterestPolicy());
public void testTemplateBasedReplicateSubRegion() {
assertRegionMetaData(templateBasedReplicateSubRegion, "TemplateBasedReplicateSubRegion",
"/TemplateBasedReplicateRegion/TemplateBasedReplicateSubRegion");
assertDefaultRegionAttributes(templateBasedReplicateSubRegion);
assertAsyncEventQueues(templateBasedReplicateSubRegion, "TestAsyncEventQueue");
assertCacheListeners(templateBasedReplicateSubRegion, "testListener");
assertCacheLoader(templateBasedReplicateSubRegion, "A");
assertCacheWriter(templateBasedReplicateSubRegion, "B");
assertFalse(templateBasedReplicateSubRegion.getAttributes().getCloningEnabled());
assertTrue(templateBasedReplicateSubRegion.getAttributes().getConcurrencyChecksEnabled());
assertEquals(16, templateBasedReplicateSubRegion.getAttributes().getConcurrencyLevel());
assertEquals(DataPolicy.REPLICATE, templateBasedReplicateSubRegion.getAttributes().getDataPolicy());
assertFalse(templateBasedReplicateSubRegion.getAttributes().isDiskSynchronous());
assertTrue(templateBasedReplicateSubRegion.getAttributes().getEnableAsyncConflation());
assertFalse(templateBasedReplicateSubRegion.getAttributes().getEnableSubscriptionConflation());
assertDefaultEvictionAttributes(templateBasedReplicateSubRegion.getAttributes().getEvictionAttributes());
assertExpirationAttributes(templateBasedReplicateSubRegion.getAttributes().getEntryIdleTimeout(),
ExpirationAction.DESTROY, 600);
assertExpirationAttributes(templateBasedReplicateSubRegion.getAttributes().getEntryTimeToLive(),
ExpirationAction.DESTROY, 600);
assertGatewaySenders(templateBasedReplicateSubRegion, "TestGatewaySender");
assertTrue(templateBasedReplicateSubRegion.getAttributes().getIgnoreJTA());
assertFalse(templateBasedReplicateSubRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(51, templateBasedReplicateSubRegion.getAttributes().getInitialCapacity());
assertEquals(Integer.class, templateBasedReplicateSubRegion.getAttributes().getKeyConstraint());
assertEquals("0.95", String.valueOf(templateBasedReplicateSubRegion.getAttributes().getLoadFactor()));
assertFalse(templateBasedReplicateSubRegion.getAttributes().isLockGrantor());
assertMembershipAttributes(templateBasedReplicateSubRegion.getAttributes().getMembershipAttributes(),
LossAction.LIMITED_ACCESS, ResumptionAction.NONE, "readWriteNode");
assertNull(templateBasedReplicateSubRegion.getAttributes().getPartitionAttributes());
assertEquals(Scope.DISTRIBUTED_NO_ACK, templateBasedReplicateSubRegion.getAttributes().getScope());
assertTrue(templateBasedReplicateSubRegion.getAttributes().getStatisticsEnabled());
assertDefaultSubscriptionAttributes(templateBasedReplicateSubRegion.getAttributes().getSubscriptionAttributes());
assertEquals(String.class, templateBasedReplicateSubRegion.getAttributes().getValueConstraint());
}
protected static interface Nameable {
void setName(String name);
@Test
public void testTemplateBasedPartitionRegion() {
assertRegionMetaData(templateBasedPartitionRegion, "TemplateBasedPartitionRegion");
assertDefaultRegionAttributes(templateBasedPartitionRegion);
assertAsyncEventQueues(templateBasedPartitionRegion, "TestAsyncEventQueue");
assertCacheListeners(templateBasedPartitionRegion, "X", "Y", "Z");
assertCacheLoader(templateBasedPartitionRegion, "A");
assertCacheWriter(templateBasedPartitionRegion, "dbWriter");
assertFalse(templateBasedPartitionRegion.getAttributes().getCloningEnabled());
assertTrue(templateBasedPartitionRegion.getAttributes().getConcurrencyChecksEnabled());
assertEquals(DataPolicy.PERSISTENT_PARTITION, templateBasedPartitionRegion.getAttributes().getDataPolicy());
assertTrue(templateBasedPartitionRegion.getAttributes().isDiskSynchronous());
assertTrue(templateBasedPartitionRegion.getAttributes().getEnableAsyncConflation());
assertTrue(templateBasedPartitionRegion.getAttributes().getEnableSubscriptionConflation());
assertEvictionAttributes(templateBasedPartitionRegion.getAttributes().getEvictionAttributes(),
EvictionAction.OVERFLOW_TO_DISK, EvictionAlgorithm.LRU_ENTRY, 8192000, null);
assertExpirationAttributes(templateBasedPartitionRegion.getAttributes().getEntryIdleTimeout(),
ExpirationAction.DESTROY, 600);
assertExpirationAttributes(templateBasedPartitionRegion.getAttributes().getEntryTimeToLive(),
ExpirationAction.INVALIDATE, 300);
assertGatewaySenders(templateBasedPartitionRegion, "TestGatewaySender");
assertFalse(templateBasedPartitionRegion.getAttributes().getIgnoreJTA());
assertFalse(templateBasedPartitionRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(51, templateBasedPartitionRegion.getAttributes().getInitialCapacity());
assertEquals(Date.class, templateBasedPartitionRegion.getAttributes().getKeyConstraint());
assertEquals("0.7", String.valueOf(templateBasedPartitionRegion.getAttributes().getLoadFactor()));
assertFalse(templateBasedPartitionRegion.getAttributes().isLockGrantor());
assertMembershipAttributes(templateBasedPartitionRegion.getAttributes().getMembershipAttributes(),
LossAction.NO_ACCESS, ResumptionAction.REINITIALIZE, "admin", "root", "supertool");
assertNotNull(templateBasedPartitionRegion.getAttributes().getPartitionAttributes());
assertEquals("Neighbor",
templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getColocatedWith());
assertEquals(8192, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getLocalMaxMemory());
assertEquals(2, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getRedundantCopies());
assertEquals(60000l, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getRecoveryDelay());
assertEquals(15000l, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getStartupRecoveryDelay());
assertEquals(16384, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getTotalMaxMemory());
assertEquals(91, templateBasedPartitionRegion.getAttributes().getPartitionAttributes().getTotalNumBuckets());
assertPartitionListener(templateBasedPartitionRegion, "testListener");
assertPartitionResolver(templateBasedPartitionRegion, "testResolver");
assertEquals(Scope.DISTRIBUTED_NO_ACK, templateBasedPartitionRegion.getAttributes().getScope());
assertTrue(templateBasedPartitionRegion.getAttributes().getStatisticsEnabled());
assertSubscriptionAttributes(templateBasedPartitionRegion.getAttributes().getSubscriptionAttributes(),
InterestPolicy.ALL);
assertEquals(Object.class, templateBasedPartitionRegion.getAttributes().getValueConstraint());
}
protected static abstract class AbstractNameable implements Nameable {
@Test
public void testTemplateBasedLocalRegion() {
assertRegionMetaData(templateBasedLocalRegion, "TemplateBasedLocalRegion");
assertDefaultRegionAttributes(templateBasedLocalRegion);
assertEmpty(templateBasedLocalRegion.getAttributes().getAsyncEventQueueIds());
assertCacheListeners(templateBasedLocalRegion, "X", "Y", "Z");
assertNull(templateBasedLocalRegion.getAttributes().getCacheLoader());
assertNull(templateBasedLocalRegion.getAttributes().getCacheWriter());
assertTrue(templateBasedLocalRegion.getAttributes().getCloningEnabled());
assertFalse(templateBasedLocalRegion.getAttributes().getConcurrencyChecksEnabled());
assertEquals(8, templateBasedLocalRegion.getAttributes().getConcurrencyLevel());
assertEquals(DataPolicy.NORMAL, templateBasedLocalRegion.getAttributes().getDataPolicy());
assertFalse(templateBasedLocalRegion.getAttributes().isDiskSynchronous());
assertFalse(templateBasedLocalRegion.getAttributes().getEnableAsyncConflation());
assertFalse(templateBasedLocalRegion.getAttributes().getEnableSubscriptionConflation());
assertEvictionAttributes(templateBasedLocalRegion.getAttributes().getEvictionAttributes(),
EvictionAction.LOCAL_DESTROY, EvictionAlgorithm.LRU_ENTRY, 4096, null);
assertExpirationAttributes(templateBasedLocalRegion.getAttributes().getEntryIdleTimeout(),
ExpirationAction.DESTROY, 600);
assertExpirationAttributes(templateBasedLocalRegion.getAttributes().getEntryTimeToLive(),
ExpirationAction.INVALIDATE, 300);
assertEmpty(templateBasedLocalRegion.getAttributes().getGatewaySenderIds());
assertTrue(templateBasedLocalRegion.getAttributes().getIgnoreJTA());
assertTrue(templateBasedLocalRegion.getAttributes().getIndexMaintenanceSynchronous());
assertEquals(51, templateBasedLocalRegion.getAttributes().getInitialCapacity());
assertEquals(Long.class, templateBasedLocalRegion.getAttributes().getKeyConstraint());
assertEquals("0.85", String.valueOf(templateBasedLocalRegion.getAttributes().getLoadFactor()));
assertFalse(templateBasedLocalRegion.getAttributes().isLockGrantor());
assertDefaultMembershipAttributes(templateBasedLocalRegion.getAttributes().getMembershipAttributes());
assertNull(templateBasedLocalRegion.getAttributes().getPartitionAttributes());
assertEquals(Scope.LOCAL, templateBasedLocalRegion.getAttributes().getScope());
assertTrue(templateBasedLocalRegion.getAttributes().getStatisticsEnabled());
assertDefaultSubscriptionAttributes(templateBasedLocalRegion.getAttributes().getSubscriptionAttributes());
assertEquals(String.class, templateBasedLocalRegion.getAttributes().getValueConstraint());
}
public static final class TestAsyncEventListener implements AsyncEventListener {
private String name;
@@ -242,8 +508,13 @@ public class TemplateRegionsNamespaceTests {
this.name = name;
}
protected String getName() {
return this.name;
@Override
public boolean processEvents(final List<AsyncEvent> asyncEvents) {
return false;
}
@Override
public void close() {
}
@Override
@@ -252,17 +523,6 @@ public class TemplateRegionsNamespaceTests {
}
}
public static final class TestAsyncEventListener extends AbstractNameable implements AsyncEventListener {
@Override public boolean processEvents(final List<AsyncEvent> asyncEvents) {
return false;
}
@Override public void close() {
}
}
public static final class TestCacheListener extends CacheListenerAdapter {
private String name;
@@ -277,14 +537,26 @@ public class TemplateRegionsNamespaceTests {
}
}
public static final class TestCacheLoader extends AbstractNameable implements CacheLoader {
public static final class TestCacheLoader implements CacheLoader {
@Override public Object load(final LoaderHelper loaderHelper) throws CacheLoaderException {
private String name;
public void setName(final String name) {
this.name = name;
}
@Override
public Object load(final LoaderHelper loaderHelper) throws CacheLoaderException {
return null;
}
@Override public void close() {
@Override
public void close() {
}
@Override
public String toString() {
return name;
}
}
@@ -303,6 +575,7 @@ public class TemplateRegionsNamespaceTests {
}
public static final class TestPartitionListener extends PartitionListenerAdapter {
private String name;
public void setName(final String name) {
@@ -315,17 +588,31 @@ public class TemplateRegionsNamespaceTests {
}
}
public static final class TestPartitionResolver extends AbstractNameable implements PartitionResolver {
public static final class TestPartitionResolver implements PartitionResolver {
@Override public Object getRoutingObject(final EntryOperation entryOperation) {
private String name;
public void setName(final String name) {
this.name = name;
}
@Override
public Object getRoutingObject(final EntryOperation entryOperation) {
return null;
}
@Override public String getName() {
return super.getName();
@Override
public String getName() {
return name;
}
@Override public void close() {
@Override
public void close() {
}
@Override
public String toString() {
return name;
}
}

View File

@@ -453,16 +453,14 @@ public class MockRegionFactory<K,V> {
RegionService mockRegionService = mockRegionService();
Region region = mock(Region.class);
when(region.getAttributes()).thenAnswer(new Answer<RegionAttributes>() {
@Override public RegionAttributes answer(InvocationOnMock invocation) throws Throwable {
return regionAttributes;
}
});
when(region.getAttributes()).thenReturn(regionAttributes);
String fullPath = (name.startsWith(Region.SEPARATOR) ? name : Region.SEPARATOR + name);
String regionFullPath = (name.startsWith(Region.SEPARATOR) ? name : Region.SEPARATOR + name);
String regionName = (name.lastIndexOf(Region.SEPARATOR) > 0 ?
name.substring(name.lastIndexOf(Region.SEPARATOR) + Region.SEPARATOR.length()) : name);
when(region.getFullPath()).thenReturn(fullPath);
when(region.getName()).thenReturn(name);
when(region.getFullPath()).thenReturn(regionFullPath);
when(region.getName()).thenReturn(regionName);
when(region.getRegionService()).thenReturn(mockRegionService);
when(region.getSubregion(anyString())).thenAnswer(new Answer<Region>() {

View File

@@ -19,78 +19,101 @@
<gfe:gateway-sender id="TestGatewaySender" remote-distributed-system-id="123" manual-start="true" persistent="false"
parallel="true" dispatcher-threads="8"/>
<!-- Region Templates -->
<!-- Template Regions -->
<gfe:region-template id="BaseRegion" cloning-enabled="true" concurrency-checks-enabled="false"
disk-synchronous="true" ignore-jta="true" initial-capacity="1000"
key-constraint="java.lang.Long" load-factor="0.90" persistent="false" statistics="true"
value-constraint="java.lang.String" index-update-type="synchronous">
<gfe:cache-loader>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheLoader" p:name="X"/>
</gfe:cache-loader>
<gfe:cache-writer>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheWriter" p:name="Y"/>
</gfe:cache-writer>
</gfe:region-template>
<gfe:region-template id="ExtendedRegionWithOverrides" cloning-enabled="false" concurrency-checks-enabled="true"
disk-synchronous="false" ignore-jta="false" key-constraint="java.lang.String" persistent="false"
template="BaseRegion">
<gfe:region-template id="BaseRegionTemplate" cloning-enabled="true" concurrency-checks-enabled="false"
disk-synchronous="false" ignore-jta="true" initial-capacity="51" key-constraint="java.lang.Long"
load-factor="0.85" persistent="false" statistics="true" value-constraint="java.lang.String">
<gfe:cache-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="X"/>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="Y"/>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="Z"/>
</gfe:cache-listener>
<gfe:entry-ttl timeout="300" action="INVALIDATE"/>
<gfe:entry-tti timeout="600" action="DESTROY"/>
</gfe:region-template>
<gfe:region-template id="ExtendedRegionTemplate" index-update-type="asynchronous" cloning-enabled="false"
concurrency-checks-enabled="true" key-constraint="java.lang.Integer" load-factor="0.55"
template="BaseRegionTemplate">
<gfe:cache-loader>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheLoader" p:name="A"/>
</gfe:cache-loader>
<gfe:cache-writer>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheWriter" p:name="B"/>
</gfe:cache-writer>
<gfe:membership-attributes required-roles="readWriteNode" loss-action="limited-access" resumption-action="none"/>
<gfe:gateway-sender-ref bean="TestGatewaySender"/>
<gfe:async-event-queue-ref bean="TestAsyncEventQueue"/>
</gfe:region-template>
<!-- REPLICATE Region -->
<gfe:replicated-region-template id="BaseReplicateRegion" concurrency-level="2" enable-async-conflation="true"
enable-subscription-conflation="true" scope="global" template="BaseRegion">
<gfe:replicated-region-template id="ReplicateRegionTemplate" concurrency-level="24" scope="distributed-ack"
index-update-type="synchronous" disk-synchronous="false" enable-subscription-conflation="true"
key-constraint="java.lang.String" persistent="true" value-constraint="java.lang.Object"
template="BaseRegionTemplate">
<gfe:cache-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="XYZ"/>
</gfe:cache-listener>
<gfe:subscription type="CACHE_CONTENT"/>
<gfe:eviction type="ENTRY_COUNT" threshold="1000" action="OVERFLOW_TO_DISK"/>
<gfe:eviction threshold="2024" type="ENTRY_COUNT"/>
</gfe:replicated-region-template>
<gfe:replicated-region id="SimpleReplicateRegion" persistent="true" concurrency-level="8" is-lock-grantor="true" scope="global"
key-constraint="java.lang.Integer">
<gfe:cache-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="Simple"/>
</gfe:cache-listener>
</gfe:replicated-region>
<gfe:replicated-region id="InheritedReplicateRegion" template="BaseReplicateRegion"/>
<gfe:replicated-region id="ComplexReplicateRegion" persistent="true" key-constraint="java.lang.Integer" ignore-jta="false"
enable-async-conflation="false" cloning-enabled="false" template="BaseReplicateRegion">
<gfe:cache-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="ComplexListener"/>
</gfe:cache-listener>
<gfe:replicated-region id="NonTemplateBasedReplicateRegion" persistent="false" load-factor="0.65" initial-capacity="97"
concurrency-level="12">
<gfe:cache-loader>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheLoader" p:name="ComplexLoader"/>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheLoader" p:name="ABC"/>
</gfe:cache-loader>
<gfe:subscription type="ALL"/>
<gfe:eviction type="ENTRY_COUNT" threshold="1024" action="OVERFLOW_TO_DISK"/>
</gfe:replicated-region>
<gfe:replicated-region id="TemplateBasedReplicateRegion" persistent="false" is-lock-grantor="true" scope="global"
template="ReplicateRegionTemplate">
<gfe:cache-loader>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheLoader" p:name="dbLoader"/>
</gfe:cache-loader>
<gfe:replicated-region name="TemplateBasedReplicateSubRegion" enable-async-conflation="true" load-factor="0.95"
template="ExtendedRegionTemplate">
<gfe:cache-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheListener" p:name="testListener"/>
</gfe:cache-listener>
<gfe:entry-ttl timeout="600" action="DESTROY"/>
</gfe:replicated-region>
</gfe:replicated-region>
<!-- PARTITION Region -->
<gfe:partitioned-region-template id="BasePartitionRegion" copies="2" local-max-memory="1000" total-max-memory="4000"
total-buckets="77" recovery-delay="1000" startup-recovery-delay="5000"
template="ExtendedRegionWithOverrides">
<gfe:partitioned-region-template id="PartitionRegionTemplate" copies="1" local-max-memory="1024"
total-max-memory="16384" recovery-delay="60000" startup-recovery-delay="15000"
enable-async-conflation="false" enable-subscription-conflation="true"
load-factor="0.70" value-constraint="java.lang.Object"
template="ExtendedRegionTemplate">
<gfe:partition-resolver>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestPartitionResolver" p:name="A"/>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestPartitionResolver" p:name="testResolver"/>
</gfe:partition-resolver>
<gfe:eviction type="ENTRY_COUNT" threshold="8192000" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region-template>
<gfe:partitioned-region id="TemplateBasedPartitionRegion" copies="2" colocated-with="Neighbor" local-max-memory="8192"
total-buckets="91" disk-synchronous="true" enable-async-conflation="true" ignore-jta="false"
key-constraint="java.util.Date" persistent="true" template="PartitionRegionTemplate">
<gfe:cache-writer>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestCacheWriter" p:name="dbWriter"/>
</gfe:cache-writer>
<gfe:membership-attributes required-roles="admin,root,supertool" loss-action="no-access" resumption-action="reinitialize"/>
<gfe:partition-listener>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestPartitionListener" p:name="B"/>
<bean class="org.springframework.data.gemfire.config.TemplateRegionsNamespaceTests$TestPartitionListener" p:name="testListener"/>
</gfe:partition-listener>
<gfe:subscription type="ALL"/>
<gfe:eviction type="MEMORY_SIZE" threshold="4000" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region-template>
</gfe:partitioned-region>
<gfe:partitioned-region id="Neighbor" persistent="false"/>
<!-- LOCAL Region -->
<gfe:local-region-template id="BaseLocalRegion" concurrency-level="4">
<gfe:eviction type="ENTRY_COUNT" threshold="8192" action="LOCAL_DESTROY"/>
<gfe:local-region-template id="LocalRegionTemplate" concurrency-level="8" template="BaseRegionTemplate">
<gfe:eviction type="ENTRY_COUNT" threshold="4096" action="LOCAL_DESTROY"/>
</gfe:local-region-template>
<gfe:local-region id="TemplateBasedLocalRegion" template="LocalRegionTemplate"/>
</beans>