From d8dc9d4edbd83fcf380b5866cc50aae5944d7666 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 21 Jan 2014 18:27:22 -0800 Subject: [PATCH] Fully fixes JIRA issue SGF-236 involving the Subregion bean names requiring a prepended forward slash when using the high-level region XML namespace abstractions, like gfe:replicated-region, vs. the gfe:lookup-region element. --- .../reference/docbook/reference/region.xml | 159 ++++++++++++++++-- .../gemfire/config/LookupRegionParser.java | 1 - .../data/gemfire/lookupSubRegion.xml | 6 +- 3 files changed, 152 insertions(+), 14 deletions(-) diff --git a/docs/src/reference/docbook/reference/region.xml b/docs/src/reference/docbook/reference/region.xml index 91730401..f4f3a5f4 100644 --- a/docs/src/reference/docbook/reference/region.xml +++ b/docs/src/reference/docbook/reference/region.xml @@ -61,20 +61,20 @@ Using an externally configured Region For referencing regions already configured through GemFire native - configuration, e.g., a cache.xml file, use the + configuration, e.g. a cache.xml file, use the lookup-region element. Simply declare the target region - name with the name attribute; for example, to declare a - bean definition, named region-bean for an existing - region named orders one can use the following + name with thename attribute; for example, to declare a + bean definition named region-bean for an existing + region named Orders one can use the following bean definition: - <gfe:lookup-region id="region-bean" name="orders"/> + <gfe:lookup-region id="region-bean" name="Orders"/> If the name is not specified, the bean's id will be used. The example above becomes: - <!-- lookup for a region called 'orders' --> -<gfe:lookup-region id="orders"/> + <!-- lookup for a region called 'Orders' --> +<gfe:lookup-region id="Orders"/> If the region does not exist, an initialization exception will be @@ -82,13 +82,13 @@ sections below. - Note that in the previous examples, since no cache name was defined, + Note, in the previous examples, since no cache name was defined, the default naming convention (gemfireCache) was used. Alternately, one can reference the cache bean through the cache-ref attribute: <gfe:cache id="cache"/> -<gfe:lookup-region id="region-bean" name="orders" cache-ref="cache"/> +<gfe:lookup-region id="region-bean" name="Orders" cache-ref="cache"/> The lookup-region provides a simple way of retrieving existing, pre-configured regions without exposing the region @@ -118,7 +118,7 @@ Client Region <client-region> For a comprehensive description of region + url="http://pubs.vmware.com/vfabricNoSuite/topic/com.vmware.vfabric.gemfire.7.0/developing/region_options/region_types.html">Region types please consult the GemFire product documentation.
@@ -467,6 +467,145 @@
+
+ A Word of Caution on Regions, Subregions and Lookups + + One of the underlying properties of the high-level replicated-region, + partitioned-region, local-region and client-region + elements in Spring Data GemFire's XML namespace, which correspond to GemFire's Region types based on + Data Policy, is that these elements perform a lookup first before attempting to create the region. + This is done in case the region already exists, which might be the case if the region was defined + in GemFire's native configuration, e.g. cache.xml, thereby avoiding any errors. + This was by design, though subject to change. + + + The Spring team highly recommends that the replicated-region, + partitioned-region, local-region and client-region + elements be strictly used only for defining new regions. One of the problems with these elements + doing a lookup first is, if the developer assumed that defining a bean definition for a REPLICATE + region would create a new region, however, consequently a region with the same name already exists + having different semantics for eviction, expiration, subscription and/or other attributes, this + could adversely affect application logic and/or expectations thereby violating application + requirements. + + + + Recommended Practice - Only use the replicated-region, + partitioned-region, local-region and + client-region XML namespace elements for defining new regions. + + + However, because the high-level region elements perform a lookup first, this can cause problems for + dependency injected region resources to application code, like DAOs or Repositories. + + Take for instance the following native GemFire configuration file + (e.g. cachel.xml)... + + +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN" +"http://www.gemstone.com/dtd/cache7_0.dtd"> +<cache> + <region name="Customers" refid="REPLICATE"> + <region name="Accounts" refid="REPLICATE"> + <region name="Orders" refid="REPLICATE"> + <region name="Items" refid="REPLICATE"/> + </region> + </region> + </region> +</cache> + + + Also, consider that you might have defined a DAO as follows... + + +public class CustomerAccountDao extends GemDaoSupport { + + @Resource(name = "Customers/Accounts") + private Region customersAccounts; + + ... +} + + + Here, we are injecting a reference to the Customers/Accounts GemFire Region in + our DAO. As such, it is not uncommon for a developer to define beans for all or some of these regions in + Spring XML configuration meta-data as follows... + + +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:gfe="http://www.springframework.org/schema/gemfire" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" +http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd +http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd +"> + + <gfe:cache cache-xml-location="classpath:cache.xml"/> + + <gfe:lookup-region name="Customers/Accounts"/> + <gfe:lookup-region name="Customers/Accounts/Orders"/> +</beans> + + + Here the Customers/Accounts and Customers/Accounts/Orders + GemFire Regions are referenced as beans in the Spring context as "Customers/Accounts" + and "Customers/Accounts/Orders", respectively. The nice thing about using the + lookup-region element and the corresponding syntax above is that it allows + a developer to reference a subregion directly without unnecessarily defining a bean for the + parent region (e.g. Customers). + + However, if now the developer changes his/her configuration meta-data syntax to using + the nested format, like so... + + +<gfe:lookup-region name="Customers"> + <gfe:lookup-region name="Accounts"> + <gfe:lookup-region name="Orders"/> + </gfe:lookup-region> +</gfe:lookup-region> + + + Or, perhaps the developer erroneously chooses to use the high-level + replicated-region element, which will do a lookup first, as in... + + +<gfe:replicated-region name="Customers" persistent="true"> + <gfe:replicated-region name="Accounts" persistent="true"> + <gfe:replicated-region name="Orders" persistent="true"/> + </gfe:replicated-region> +</gfe:replicated-region> + + + Then the region beans defined in the Spring context will consist of the following: + { "Customers", "/Customers/Accounts", "/Customers/Accounts/Orders" }. + This means the dependency injected reference (i.e. @Resource(name = "Customers/Accounts")) + is now broken since no bean with name "Customers/Accounts" is defined. + + GemFire is flexible in referencing both parent regions and subregions. The parent can be + referenced as "/Customers" or "Customers" and the child as "/Customers/Accounts" or just + "Customers/Accounts". However, Spring Data GemFire is very specific when it comes to naming beans + after regions, typically always using the forward slash (/) to represents subregions + (e.g. "/Customers/Accounts"). + + Therefore, it is recommended that users use either the nested lookup-region + syntax as illustrated above, or define direct references with a leading forward slash (/) like so... + + +<gfe:lookup-region name="/Customers/Accounts"/> +<gfe:lookup-region name="/Customers/Accounts/Orders"/> + + + The example above where the nested replicated-region elements were used to + reference the subregions serves to illustrate the problem stated earlier. Are the Customers, Accounts + and Orders Regions/Subregions persistent or not? Not, since the regions were defined in native GemFire + configuration (i.e. cache.xml) and will exist by the time the cache is initialized, + or once the <gfe:cache> bean is created. Since the high-level region + XML namespace abstractions, like replicated-region, perform the lookup first, it + uses the regions as defined in the cache.xml configuration file. +
+
Data Persistence diff --git a/src/main/java/org/springframework/data/gemfire/config/LookupRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/LookupRegionParser.java index c7a271c9..2fc95712 100644 --- a/src/main/java/org/springframework/data/gemfire/config/LookupRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/LookupRegionParser.java @@ -19,7 +19,6 @@ package org.springframework.data.gemfire.config; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.data.gemfire.RegionLookupFactoryBean; -import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** diff --git a/src/test/resources/org/springframework/data/gemfire/lookupSubRegion.xml b/src/test/resources/org/springframework/data/gemfire/lookupSubRegion.xml index 6587c3ae..2ed2e4cf 100644 --- a/src/test/resources/org/springframework/data/gemfire/lookupSubRegion.xml +++ b/src/test/resources/org/springframework/data/gemfire/lookupSubRegion.xml @@ -4,7 +4,7 @@ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire-1.3.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd "> @@ -34,7 +34,7 @@ --> + + -->