diff --git a/src/main/java/org/springframework/data/gemfire/client/AbstractGemfireDataSource.java b/src/main/java/org/springframework/data/gemfire/client/AbstractGemfireDataSource.java deleted file mode 100644 index b1ff6fc7..00000000 --- a/src/main/java/org/springframework/data/gemfire/client/AbstractGemfireDataSource.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2002-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.client; - -import java.net.InetSocketAddress; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.data.gemfire.function.execution.GemfireFunctionOperations; -import org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate; -import org.springframework.data.gemfire.repository.support.ListRegionsOnServerFunction; - -import com.gemstone.gemfire.cache.Region; -import com.gemstone.gemfire.cache.client.ClientCache; -import com.gemstone.gemfire.cache.client.ClientCacheFactory; -import com.gemstone.gemfire.cache.client.ClientRegionFactory; -import com.gemstone.gemfire.cache.client.ClientRegionShortcut; -import com.gemstone.gemfire.cache.client.Pool; -import com.gemstone.gemfire.cache.query.QueryService; -import com.gemstone.gemfire.distributed.DistributedSystem; - -/** - * @author David Turanski - * - */ -public abstract class AbstractGemfireDataSource { - protected Log logger = LogFactory.getLog(getClass()); - protected ClientCache cache; - - public AbstractGemfireDataSource(ClientCacheFactory clientCacheFactory) { - this.cache = clientCacheFactory.create(); - } - - public AbstractGemfireDataSource(String host, int port, Properties properties) { - ClientCacheFactory clientCacheFactory = new ClientCacheFactory(); - addRemoteConnection(clientCacheFactory, host, port); - initializeClientCache(clientCacheFactory,properties); - this.cache = clientCacheFactory.create(); - createClientRegions(); - } - - public AbstractGemfireDataSource(List remoteConnections, Properties properties) { - - ClientCacheFactory clientCacheFactory = new ClientCacheFactory(); - for (InetSocketAddress remoteConnection: remoteConnections) { - addRemoteConnection(clientCacheFactory, remoteConnection.getHostName(), remoteConnection.getPort()); - } - initializeClientCache(clientCacheFactory,properties); - this.cache = clientCacheFactory.create(); - createClientRegions(); - } - - protected abstract void addRemoteConnection(ClientCacheFactory clientCacheFactory, String host, int port); - - public void connect() { - this.connect(); - } - - public String getName() { - return cache.getName(); - } - - public String getServerGroup() { - return cache.getDefaultPool().getServerGroup(); - } - - - public List getLocators() { - return cache.getDefaultPool().getLocators(); - } - - - public List getServers() { - return cache.getDefaultPool().getServers(); - } - - - - public QueryService getQueryService() { - return cache.getQueryService(); - } - - - public QueryService getQueryService(String poolName) { - return cache.getQueryService(poolName); - } - - - public QueryService getLocalQueryService() { - return cache.getLocalQueryService(); - } - - - public void close(boolean keepalive) { - cache.close(keepalive); - } - - public void readyForEvents() { - cache.readyForEvents(); - - } - - public Set getCurrentServers() { - return cache.getCurrentServers(); - } - - - public Pool getDefaultPool() { - return cache.getDefaultPool(); - } - - public DistributedSystem getDistributedSystem() { - return cache.getDistributedSystem(); - } - - - - public Region getRegion(String path) { - return cache.getRegion(path); - } - - - public Set> rootRegions() { - return cache.rootRegions(); - } - - - public void close() { - cache.close(); - } - - - public boolean isClosed() { - return cache.isClosed(); - } - - /** - * - */ - private void createClientRegions() { - GemfireFunctionOperations template = new GemfireOnServersFunctionTemplate(cache); - Iterable regionNames = template.executeAndExtract(new ListRegionsOnServerFunction()); - - ClientRegionFactory clientRegionFactory = null; - if (regionNames !=null && regionNames.iterator().hasNext()) { - clientRegionFactory = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); - } - - for (String regionName: regionNames) { - if (logger.isDebugEnabled()) { - logger.debug("creating client region for " + regionName); - clientRegionFactory.create(regionName); - } - } - - } - - /** - * @param clientCacheFactory - * @param properties - */ - private void initializeClientCache(ClientCacheFactory clientCacheFactory, Properties properties) { - // TODO Auto-generated method stub - - } - -} diff --git a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSource.java b/src/main/java/org/springframework/data/gemfire/client/GemfireDataSource.java deleted file mode 100644 index 495217c0..00000000 --- a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSource.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2002-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.client; - -import java.util.Set; - -import com.gemstone.gemfire.cache.Region; -import com.gemstone.gemfire.cache.client.Pool; -import com.gemstone.gemfire.cache.query.QueryService; -import com.gemstone.gemfire.distributed.DistributedSystem; - -/** - * @author David Turanski - * - */ -public interface GemfireDataSource { - - public void connect(); - - public String getName(); - - public String getServerGroup(); - - public QueryService getQueryService(); - - public QueryService getQueryService(String poolName); - - public QueryService getLocalQueryService(); - - public void readyForEvents(); - - public Pool getDefaultPool(); - - public DistributedSystem getDistributedSystem(); - - public Region getRegion(String path); - - public Set> rootRegions(); - - public void close(); - - public void close(boolean keepalive); - - public boolean isClosed(); -} diff --git a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java b/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java index a669c43d..d4197b2a 100644 --- a/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java +++ b/src/main/java/org/springframework/data/gemfire/client/GemfireDataSourcePostProcessor.java @@ -20,48 +20,63 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.data.gemfire.function.execution.GemfireFunctionOperations; import org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate; import org.springframework.data.gemfire.repository.support.ListRegionsOnServerFunction; +import org.springframework.util.Assert; +import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.client.ClientRegionFactory; import com.gemstone.gemfire.cache.client.ClientRegionShortcut; /** * @author David Turanski - * + * a {@link BeanFactoryPostProcessor} to register a Client Region bean, if necessary, for each Region accessible + * to a Gemfire data source. If the Region is already defined, the definition will not be overridden. */ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor { private static Log logger = LogFactory.getLog(GemfireDataSourcePostProcessor.class); private final ClientCache cache; - + public GemfireDataSourcePostProcessor(ClientCache cache) { this.cache = cache; } + /* (non-Javadoc) * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { createClientRegions(beanFactory); - + } - + private void createClientRegions(ConfigurableListableBeanFactory beanFactory) { GemfireFunctionOperations template = new GemfireOnServersFunctionTemplate(cache); Iterable regionNames = template.executeAndExtract(new ListRegionsOnServerFunction()); - - ClientRegionFactory clientRegionFactory = null; - if (regionNames !=null && regionNames.iterator().hasNext()) { + + ClientRegionFactory clientRegionFactory = null; + if (regionNames != null && regionNames.iterator().hasNext()) { clientRegionFactory = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); } - - for (String regionName: regionNames) { - if (logger.isDebugEnabled()) { - logger.debug("creating client region for " + regionName); - beanFactory.registerSingleton(regionName, - clientRegionFactory.create(regionName)); + + for (String regionName : regionNames) { + boolean createRegion = true; + if (beanFactory.containsBean(regionName)) { + Object existingBean = beanFactory.getBean(regionName); + Assert.isTrue(beanFactory.getBean(regionName) instanceof Region, String.format( + "cannot create a ClientRegion bean named %s. A bean with this name of type %s already exists.", + regionName, existingBean.getClass().getName())); + createRegion = false; + } + if (createRegion) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("creating client region for %s", regionName)); + } + beanFactory.registerSingleton(regionName, clientRegionFactory.create(regionName)); + } else { + if (logger.isDebugEnabled()) { + logger.debug(String.format("a region named %s is already defined",regionName)); + } } } - } - } diff --git a/src/main/java/org/springframework/data/gemfire/client/GemfireLocatorDataSource.java b/src/main/java/org/springframework/data/gemfire/client/GemfireLocatorDataSource.java deleted file mode 100644 index 3a235c3b..00000000 --- a/src/main/java/org/springframework/data/gemfire/client/GemfireLocatorDataSource.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2002-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.client; - -import java.net.InetSocketAddress; -import java.util.List; -import java.util.Properties; - -import com.gemstone.gemfire.cache.client.ClientCacheFactory; - -/** - * @author David Turanski - * - */ -public class GemfireLocatorDataSource extends AbstractGemfireDataSource { - - public GemfireLocatorDataSource(ClientCacheFactory clientCacheFactory) { - super(clientCacheFactory); - } - - public GemfireLocatorDataSource(String host, int port, Properties properties) { - super(host, port, properties); - } - - public GemfireLocatorDataSource(List remoteConnections, Properties properties) { - super(remoteConnections, properties); - } - - /* (non-Javadoc) - * @see org.springframework.data.gemfire.client.AbstractGemfireDataSource#addRemoteConnection(com.gemstone.gemfire.cache.client.ClientCacheFactory, java.lang.String, int) - */ - @Override - protected void addRemoteConnection(ClientCacheFactory clientCacheFactory, String host, int port) { - clientCacheFactory.addPoolLocator(host, port); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/client/GemfireServerDataSource.java b/src/main/java/org/springframework/data/gemfire/client/GemfireServerDataSource.java deleted file mode 100644 index 7ad783c9..00000000 --- a/src/main/java/org/springframework/data/gemfire/client/GemfireServerDataSource.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-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.client; - -import java.net.InetSocketAddress; -import java.util.List; -import java.util.Properties; - -import com.gemstone.gemfire.cache.client.ClientCacheFactory; - -/** - * @author David Turanski - * - */ -public class GemfireServerDataSource extends AbstractGemfireDataSource { - - public GemfireServerDataSource(ClientCacheFactory clientCacheFactory) { - super(clientCacheFactory); - } - - public GemfireServerDataSource(String host, int port, Properties properties) { - super(host, port, properties); - } - - public GemfireServerDataSource(List remoteConnections, Properties properties) { - super(remoteConnections, properties); - } - - /* (non-Javadoc) - * @see org.springframework.data.gemfire.client.AbstractGemfireDataSource#addRemoteConnection(com.gemstone.gemfire.cache.client.ClientCacheFactory, java.lang.String, int) - */ - @Override - protected void addRemoteConnection(ClientCacheFactory clientCacheFactory, String host, int port) { - clientCacheFactory.addPoolServer(host, port); - } -} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/config/GemfireDataSourceParser.java b/src/main/java/org/springframework/data/gemfire/config/GemfireDataSourceParser.java index 3e247b5a..8fa30d25 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireDataSourceParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireDataSourceParser.java @@ -12,18 +12,13 @@ */ package org.springframework.data.gemfire.config; -import javax.management.Attribute; - import org.springframework.beans.MutablePropertyValues; -import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor; -import org.springframework.util.Assert; -import org.w3c.dom.Attr; import org.w3c.dom.Element; /** diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java index 857302e5..e27179bb 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java @@ -31,6 +31,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.client.ClientCache; import com.gemstone.gemfire.cache.client.Pool; @@ -61,6 +62,9 @@ public class GemFireDataSourceTest { assertTrue(regionList.contains("r1")); assertTrue(regionList.contains("r2")); assertTrue(regionList.contains("simple")); + + Region simple = ctx.getBean("simple", Region.class); + assertEquals(DataPolicy.EMPTY, simple.getAttributes().getDataPolicy()); } diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java new file mode 100644 index 00000000..69082f26 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-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.client; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.ForkUtil; +import org.springframework.data.gemfire.fork.SpringCacheServerProcess; +import org.springframework.data.gemfire.repository.sample.Person; +import org.springframework.data.gemfire.repository.sample.PersonRepository; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.Pool; + +/** + * @author David Turanski + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("/org/springframework/data/gemfire/client/datasource-client-with-regions.xml") +public class GemFireDataSourceWithLocalRegionTest { + @Autowired + ApplicationContext ctx; + + @BeforeClass + public static void startUp() throws Exception { + ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " + + "/org/springframework/data/gemfire/client/datasource-server.xml"); + } + + + @Test + public void testRegionDefinitionNotOverridden() { + Region simple = ctx.getBean("simple",Region.class); + assertEquals(DataPolicy.NORMAL, + simple.getAttributes().getDataPolicy()); + } + + + + + @AfterClass + public static void cleanUp() { + ForkUtil.sendSignal(); + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml b/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml new file mode 100644 index 00000000..c74fc406 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml @@ -0,0 +1,18 @@ + + + + + + + + + + +