DATAGEODE-231 - The 'gemfireDataSourcePostProcessor' bean should be a BeanPostProcessor.
Also, under no circumstances should the BeanPostProcessor have a dependency on the GemFireCache!
This commit is contained in:
@@ -29,11 +29,15 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.data.gemfire.client.function.ListRegionsOnServerFunction;
|
||||
import org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -56,40 +60,43 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see ListRegionsOnServerFunction
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor {
|
||||
public class GemfireDataSourcePostProcessor implements BeanFactoryAware, BeanPostProcessor {
|
||||
|
||||
private static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = ClientRegionShortcut.PROXY;
|
||||
|
||||
private final ClientCache clientCache;
|
||||
private ClientRegionShortcut clientRegionShortcut;
|
||||
|
||||
private ClientRegionShortcut clientRegionShortcut = DEFAULT_CLIENT_REGION_SHORTCUT;
|
||||
private ConfigurableBeanFactory beanFactory;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* Constructs an instance of the {@link GemfireDataSourcePostProcessor} {@link BeanFactoryPostProcessor} class
|
||||
* initialized * with the specified {@link ClientCache} instance for creating client {@link Region Regions}
|
||||
* for all data {@link Region Regions} configured in the cluster.
|
||||
* Set a reference to the {@link BeanFactory}.
|
||||
*
|
||||
* @param clientCache reference to the {@link ClientCache} instance.
|
||||
* @throws IllegalArgumentException if {@link ClientCache} is {@literal null}.
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @param beanFactory reference to the {@link BeanFactory}.
|
||||
* @throws BeansException if the {@link BeanFactory} is not a {@link ConfigurableBeanFactory}.
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
*/
|
||||
public GemfireDataSourcePostProcessor(ClientCache clientCache) {
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
|
||||
Assert.notNull(clientCache, "ClientCache must not be null");
|
||||
|
||||
this.clientCache = clientCache;
|
||||
if (beanFactory instanceof ConfigurableBeanFactory) {
|
||||
this.beanFactory = (ConfigurableBeanFactory) beanFactory;
|
||||
}
|
||||
else {
|
||||
throw new TypeMismatchException(beanFactory, ConfigurableBeanFactory.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the {@link ClientCache}.
|
||||
* Returns a reference to the configured {@link ConfigurableBeanFactory}.
|
||||
*
|
||||
* @return a reference to the {@link ClientCache}.
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @return a reference to the configured {@link ConfigurableBeanFactory}.
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
|
||||
*/
|
||||
protected ClientCache getClientCache() {
|
||||
return this.clientCache;
|
||||
public Optional<ConfigurableBeanFactory> getBeanFactory() {
|
||||
return Optional.ofNullable(this.beanFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,6 +122,17 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor
|
||||
return Optional.ofNullable(this.clientRegionShortcut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the {@link ClientRegionShortcut} used to configure and create client {@link Region Regions}.
|
||||
*
|
||||
* @return the resolved {@link ClientRegionShortcut}.
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see #getClientRegionShortcut()
|
||||
*/
|
||||
protected ClientRegionShortcut resolveClientRegionShortcut() {
|
||||
return getClientRegionShortcut().orElse(DEFAULT_CLIENT_REGION_SHORTCUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the configured {@link Logger} used to log messages.
|
||||
*
|
||||
@@ -125,27 +143,31 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor
|
||||
return this.logger;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
|
||||
* #postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
createClientProxyRegions(beanFactory, regionNames());
|
||||
@Nullable @Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof ClientCache) {
|
||||
|
||||
ClientCache clientCache = (ClientCache) bean;
|
||||
|
||||
getBeanFactory().ifPresent(it -> createClientProxyRegions(it, clientCache, regionNames(clientCache)));
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
// TODO: remove this logic and delegate to o.s.d.g.config.remote.GemfireAdminOperations
|
||||
Iterable<String> regionNames() {
|
||||
Iterable<String> regionNames(ClientCache clientCache) {
|
||||
|
||||
try {
|
||||
return execute(new ListRegionsOnServerFunction());
|
||||
return execute(clientCache, new ListRegionsOnServerFunction());
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
|
||||
try {
|
||||
|
||||
Object results = execute(new GetRegionsFunction());
|
||||
Object results = execute(clientCache, new GetRegionsFunction());
|
||||
|
||||
List<String> regionNames = Collections.emptyList();
|
||||
|
||||
@@ -163,15 +185,14 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor
|
||||
return regionNames;
|
||||
}
|
||||
catch (Exception cause) {
|
||||
logDebug("Failed to determine the Regions available on the Server: %n%1$s", cause);
|
||||
logDebug("Failed to determine the Regions available on the Server: %n%s", cause);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T execute(Function gemfireFunction, Object... arguments) {
|
||||
return new GemfireOnServersFunctionTemplate(getClientCache()).executeAndExtract(gemfireFunction, arguments);
|
||||
<T> T execute(ClientCache clientCache, Function gemfireFunction, Object... arguments) {
|
||||
return new GemfireOnServersFunctionTemplate(clientCache).executeAndExtract(gemfireFunction, arguments);
|
||||
}
|
||||
|
||||
boolean containsRegionInformation(Object results) {
|
||||
@@ -180,15 +201,15 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor
|
||||
&& ((Object[]) results)[0] instanceof RegionInformation;
|
||||
}
|
||||
|
||||
void createClientProxyRegions(ConfigurableListableBeanFactory beanFactory, Iterable<String> regionNames) {
|
||||
void createClientProxyRegions(ConfigurableBeanFactory beanFactory, ClientCache clientCache,
|
||||
Iterable<String> regionNames) {
|
||||
|
||||
if (regionNames.iterator().hasNext()) {
|
||||
|
||||
ClientRegionShortcut resolvedClientRegionShortcut = getClientRegionShortcut()
|
||||
.orElse(DEFAULT_CLIENT_REGION_SHORTCUT);
|
||||
ClientRegionShortcut resolvedClientRegionShortcut = resolveClientRegionShortcut();
|
||||
|
||||
ClientRegionFactory<?, ?> clientRegionFactory =
|
||||
this.clientCache.createClientRegionFactory(resolvedClientRegionShortcut);
|
||||
clientCache.createClientRegionFactory(resolvedClientRegionShortcut);
|
||||
|
||||
for (String regionName : regionNames) {
|
||||
|
||||
@@ -235,7 +256,16 @@ public class GemfireDataSourcePostProcessor implements BeanFactoryPostProcessor
|
||||
}
|
||||
|
||||
public GemfireDataSourcePostProcessor using(ClientRegionShortcut clientRegionShortcut) {
|
||||
|
||||
setClientRegionShortcut(clientRegionShortcut);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public GemfireDataSourcePostProcessor using(BeanFactory beanFactory) {
|
||||
|
||||
setBeanFactory(beanFactory);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,10 @@ public class ListRegionsOnServerFunction implements Function {
|
||||
* @see org.apache.geode.cache.execute.Function#execute(org.apache.geode.cache.execute.FunctionContext)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute(FunctionContext functionContext) {
|
||||
List<String> regionNames = new ArrayList<String>();
|
||||
|
||||
List<String> regionNames = new ArrayList<>();
|
||||
|
||||
for (Region<?, ?> region : getCache().rootRegions()) {
|
||||
regionNames.add(region.getName());
|
||||
@@ -55,7 +57,6 @@ public class ListRegionsOnServerFunction implements Function {
|
||||
functionContext.getResultSender().lastResult(regionNames);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
Cache getCache() {
|
||||
return CacheFactory.getAnyInstance();
|
||||
}
|
||||
|
||||
@@ -23,15 +23,19 @@ import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
|
||||
import org.apache.shiro.util.Assert;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor;
|
||||
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
|
||||
import org.springframework.data.gemfire.util.CacheUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* The {@link ClusterDefinedRegionsConfiguration} class configures client Proxy-based {@link Region Regions}
|
||||
@@ -83,10 +87,17 @@ public class ClusterDefinedRegionsConfiguration extends AbstractAnnotationConfig
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GemfireDataSourcePostProcessor gemfireDataSourcePostProcessor(GemFireCache gemfireCache) {
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 1000000)
|
||||
public GemfireDataSourcePostProcessor gemfireDataSourcePostProcessor() {
|
||||
return new GemfireDataSourcePostProcessor().using(getBeanFactory()).using(resolveClientRegionShortcut());
|
||||
}
|
||||
|
||||
Assert.isTrue(CacheUtils.isClient(gemfireCache), "GemFireCache must be an instance of ClientCache");
|
||||
@Bean
|
||||
Object nullCacheDependentBean(GemFireCache cache) {
|
||||
|
||||
return new GemfireDataSourcePostProcessor((ClientCache) gemfireCache).using(resolveClientRegionShortcut());
|
||||
Assert.isTrue(CacheUtils.isClient(cache), String.format("GemFireCache [%s] must be a %s",
|
||||
ObjectUtils.nullSafeClassName(cache), ClientCache.class.getName()));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
* 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.config.xml;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -18,23 +17,33 @@ import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
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.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Bean definition parser for the <gfe-data:datasource> SDG XML namespace (XSD) element.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.w3c.dom.Element
|
||||
* @see org.springframework.beans.factory.config.BeanDefinition
|
||||
* @see org.springframework.beans.factory.support.AbstractBeanDefinition
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
|
||||
* @see org.springframework.beans.factory.xml.ParserContext
|
||||
* @see org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor
|
||||
* @see ClientCacheParser
|
||||
* @see PoolParser
|
||||
* @see org.springframework.data.gemfire.config.xml.ClientCacheParser
|
||||
* @see org.springframework.data.gemfire.config.xml.PoolParser
|
||||
*/
|
||||
class GemfireDataSourceParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
@@ -51,11 +60,12 @@ class GemfireDataSourceParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
parseAndRegisterClientCache(element, parserContext);
|
||||
parseAndRegisterPool(element, parserContext);
|
||||
registerGemFireDataSourcePostProcessor(parserContext);
|
||||
registerGemFireDataSourceBeanPostProcessor(parserContext);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void parseAndRegisterClientCache(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanDefinition clientCacheDefinition = new ClientCacheParser().parse(element, parserContext);
|
||||
@@ -69,6 +79,7 @@ class GemfireDataSourceParser extends AbstractBeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private void parseAndRegisterPool(Element element, ParserContext parserContext) {
|
||||
|
||||
BeanDefinition poolDefinition = new PoolParser().parse(element, parserContext);
|
||||
@@ -82,13 +93,29 @@ class GemfireDataSourceParser extends AbstractBeanDefinitionParser {
|
||||
parserContext.getRegistry().registerBeanDefinition(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, poolDefinition);
|
||||
}
|
||||
|
||||
private void registerGemFireDataSourcePostProcessor(ParserContext parserContext) {
|
||||
private void registerGemFireDataSourceBeanPostProcessor(@NonNull ParserContext parserContext) {
|
||||
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GemfireDataSourcePostProcessor.class);
|
||||
BeanFactory beanFactory = resolveBeanFactory(parserContext);
|
||||
|
||||
builder.addConstructorArgReference(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
if (beanFactory != null) {
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GemfireDataSourcePostProcessor.class);
|
||||
|
||||
builder.addPropertyValue("beanFactory", beanFactory);
|
||||
|
||||
BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable BeanFactory resolveBeanFactory(@NonNull ParserContext parserContext) {
|
||||
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
return registry instanceof ConfigurableApplicationContext
|
||||
? ((ConfigurableApplicationContext) registry).getBeanFactory()
|
||||
: registry instanceof BeanFactory
|
||||
? (BeanFactory) registry
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.repository.config;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -23,6 +22,7 @@ import java.util.Collections;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Region;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
@@ -89,6 +89,18 @@ public class GemfireRepositoryConfigurationExtension extends RepositoryConfigura
|
||||
return GemfireRepositoryFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(BeanDefinitionBuilder, RepositoryConfigurationSource)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
|
||||
|
||||
super.postProcess(builder, source);
|
||||
|
||||
builder.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource)
|
||||
|
||||
@@ -17,9 +17,11 @@ package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
@@ -28,6 +30,7 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -73,6 +76,8 @@ public class GemfireRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private GemFireCache cache;
|
||||
|
||||
private Iterable<Region<?, ?>> regions;
|
||||
|
||||
private MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> mappingContext;
|
||||
@@ -96,14 +101,19 @@ public class GemfireRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
|
||||
this.regions = Collections.unmodifiableSet(applicationContext.getBeansOfType(Region.class).entrySet().stream()
|
||||
Map<String, Region> regionBeans = applicationContext.getBeansOfType(Region.class);
|
||||
|
||||
Set<Region<?, ?>> regions = new HashSet<>(Collections.unmodifiableSet(regionBeans.entrySet().stream()
|
||||
.<Region<?, ?>>map(Map.Entry::getValue)
|
||||
.collect(Collectors.toSet()));
|
||||
.collect(Collectors.toSet())));
|
||||
|
||||
getCache().map(GemFireCache::rootRegions).ifPresent(regions::addAll);
|
||||
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,6 +127,26 @@ public class GemfireRepositoryFactoryBean<T extends Repository<S, ID>, S, ID>
|
||||
return Optional.ofNullable(this.applicationContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a reference to the {@link GemFireCache}.
|
||||
*
|
||||
* @param cache reference to the {@link GemFireCache}.
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
*/
|
||||
public void setCache(GemFireCache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Optional} reference to the configured {@link GemFireCache}.
|
||||
*
|
||||
* @return an {@link Optional} reference to the configured {@link GemFireCache}.
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
*/
|
||||
protected Optional<GemFireCache> getCache() {
|
||||
return Optional.ofNullable(this.cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link MappingContext} used to perform application domain object type to data store mappings.
|
||||
*
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -85,8 +84,7 @@ public class GemFireDataSourceIntegrationTest extends ClientServerIntegrationTes
|
||||
arguments.add(GemFireDataSourceIntegrationTest.class.getName()
|
||||
.replace(".", "/").concat("-server-context.xml"));
|
||||
|
||||
gemfireServer = run(serverWorkingDirectory, ServerProcess.class,
|
||||
arguments.toArray(new String[arguments.size()]));
|
||||
gemfireServer = run(serverWorkingDirectory, ServerProcess.class, arguments.toArray(new String[0]));
|
||||
|
||||
waitForServerToStart(DEFAULT_HOSTNAME, availablePort);
|
||||
|
||||
@@ -138,7 +136,6 @@ public class GemFireDataSourceIntegrationTest extends ClientServerIntegrationTes
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void clientProxyRegionBeansExist() {
|
||||
|
||||
assertRegion(clientOnlyRegion, "ClientOnlyRegion");
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
* 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.assertj.core.api.Assertions.assertThat;
|
||||
@@ -105,14 +104,11 @@ public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTe
|
||||
Pool pool = this.applicationContext.getBean("gemfirePool", Pool.class);
|
||||
|
||||
assertThat(pool).isNotNull();
|
||||
assertThat(pool.getSubscriptionEnabled()).isTrue();
|
||||
|
||||
List<String> regionList = Arrays.asList(this.applicationContext.getBeanNamesForType(Region.class));
|
||||
|
||||
assertThat(regionList).hasSize(3);
|
||||
assertThat(regionList.contains("r1")).isTrue();
|
||||
assertThat(regionList.contains("r2")).isTrue();
|
||||
assertThat(regionList.contains("simple")).isTrue();
|
||||
assertThat(regionList).containsExactlyInAnyOrder("r1", "r2", "simple");
|
||||
|
||||
Region<?, ?> simple = this.applicationContext.getBean("simple", Region.class);
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import java.io.File;
|
||||
@@ -172,7 +171,6 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void clientProxyRegionBeansExist() {
|
||||
|
||||
assertRegion(localRegion, "LocalRegion");
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -31,13 +30,13 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@@ -57,7 +56,9 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.data.gemfire.client.function.ListRegionsOnServerFunction;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
|
||||
@@ -68,9 +69,12 @@ import org.springframework.data.gemfire.util.RegionUtils;
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.RegionAttributes
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.ClientRegionFactory
|
||||
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
|
||||
* @see org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor
|
||||
* @see org.springframework.data.gemfire.client.function.ListRegionsOnServerFunction
|
||||
* @since 1.7.0
|
||||
@@ -78,6 +82,9 @@ import org.springframework.data.gemfire.util.RegionUtils;
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GemfireDataSourcePostProcessorTest {
|
||||
|
||||
@Mock
|
||||
private ConfigurableBeanFactory mockBeanFactory;
|
||||
|
||||
@Mock
|
||||
private ClientCache mockClientCache;
|
||||
|
||||
@@ -105,64 +112,144 @@ public class GemfireDataSourcePostProcessorTest {
|
||||
@Test
|
||||
public void constructGemfireDataSourcePostProcessor() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(mockClientCache);
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor();
|
||||
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getClientCache()).isEqualTo(this.mockClientCache);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.PROXY);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isNull();
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.PROXY);
|
||||
assertThat(postProcessor.getLogger()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetBeanFactory() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor();
|
||||
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isNull();
|
||||
|
||||
postProcessor.setBeanFactory(this.mockBeanFactory);
|
||||
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isSameAs(this.mockBeanFactory);
|
||||
}
|
||||
|
||||
@Test(expected = TypeMismatchException.class)
|
||||
public void setBeanFactoryToIncompatibleTypeThrowsBeansException() {
|
||||
new GemfireDataSourcePostProcessor().setBeanFactory(mock(BeanFactory.class));
|
||||
}
|
||||
|
||||
@Test(expected = TypeMismatchException.class)
|
||||
public void setBeanFactoryToNullThrowsBeansException() {
|
||||
new GemfireDataSourcePostProcessor().setBeanFactory(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAndGetClientRegionShortcut() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache);
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor();
|
||||
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.PROXY);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isNull();
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.PROXY);
|
||||
|
||||
postProcessor.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY);
|
||||
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null))
|
||||
.isEqualTo(ClientRegionShortcut.CACHING_PROXY);
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY);
|
||||
|
||||
postProcessor.setClientRegionShortcut(ClientRegionShortcut.LOCAL);
|
||||
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.LOCAL);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null))
|
||||
.isEqualTo(ClientRegionShortcut.LOCAL);
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.LOCAL);
|
||||
|
||||
postProcessor.setClientRegionShortcut(null);
|
||||
|
||||
assertThat(postProcessor.getClientRegionShortcut().isPresent()).isFalse();
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isNull();
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.PROXY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessBeanFactoryCallsCreateClientRegionProxiesWithRegionNames() {
|
||||
public void usingBeanFactory() {
|
||||
|
||||
AtomicBoolean createClientRegionProxiesCalled = new AtomicBoolean(false);
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
ConfigurableListableBeanFactory mockBeanFactory =
|
||||
mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory");
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isNull();
|
||||
assertThat(postProcessor.using(this.mockBeanFactory)).isSameAs(postProcessor);
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isSameAs(this.mockBeanFactory);
|
||||
|
||||
verify(postProcessor, times(1)).setBeanFactory(eq(this.mockBeanFactory));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usingClientRegionShortcut() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor())
|
||||
.using(ClientRegionShortcut.LOCAL_PERSISTENT);
|
||||
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.LOCAL_PERSISTENT);
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.LOCAL_PERSISTENT);
|
||||
assertThat(postProcessor.using(ClientRegionShortcut.LOCAL_OVERFLOW)).isSameAs(postProcessor);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.LOCAL_OVERFLOW);
|
||||
assertThat(postProcessor.resolveClientRegionShortcut()).isEqualTo(ClientRegionShortcut.LOCAL_OVERFLOW);
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.setClientRegionShortcut(eq(ClientRegionShortcut.LOCAL_PERSISTENT));
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.setClientRegionShortcut(eq(ClientRegionShortcut.LOCAL_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void postProcessAfterInitializationCallsCreateClientRegionProxiesWithRegionNames() {
|
||||
|
||||
String[] testRegionNames = { "Test" };
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache) {
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
@Override
|
||||
Iterable<String> regionNames() {
|
||||
return Arrays.asList(testRegionNames);
|
||||
}
|
||||
postProcessor.setBeanFactory(this.mockBeanFactory);
|
||||
|
||||
@Override
|
||||
void createClientProxyRegions(ConfigurableListableBeanFactory beanFactory, Iterable<String> regionNames) {
|
||||
assertThat(beanFactory).isSameAs(mockBeanFactory);
|
||||
assertThat(regionNames).containsExactly(testRegionNames);
|
||||
createClientRegionProxiesCalled.compareAndSet(false, true);
|
||||
}
|
||||
};
|
||||
doReturn(Arrays.asList(testRegionNames)).when(postProcessor).regionNames(any(ClientCache.class));
|
||||
|
||||
postProcessor.postProcessBeanFactory(mockBeanFactory);
|
||||
doAnswer(invocation -> {
|
||||
|
||||
assertThat(createClientRegionProxiesCalled.get()).isTrue();
|
||||
ConfigurableBeanFactory beanFactory = invocation.getArgument(0);
|
||||
ClientCache clientCache = invocation.getArgument(1);
|
||||
Iterable<String> regionNames = invocation.getArgument(2);
|
||||
|
||||
assertThat(beanFactory).isSameAs(this.mockBeanFactory);
|
||||
assertThat(clientCache).isSameAs(this.mockClientCache);
|
||||
assertThat(regionNames).containsExactly(testRegionNames);
|
||||
|
||||
return null;
|
||||
|
||||
}).when(postProcessor)
|
||||
.createClientProxyRegions(any(ConfigurableBeanFactory.class), any(ClientCache.class), any(Iterable.class));
|
||||
|
||||
postProcessor.postProcessAfterInitialization(this.mockClientCache, "mockClientCache");
|
||||
|
||||
verify(postProcessor, times(1)).regionNames(eq(this.mockClientCache));
|
||||
verify(postProcessor, times(1))
|
||||
.createClientProxyRegions(eq(this.mockBeanFactory), eq(this.mockClientCache), isA(Iterable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void postProcessAfterInitializationWithNoBeanFactoryDoesNothing() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isNull();
|
||||
|
||||
postProcessor.postProcessAfterInitialization(this.mockClientCache, "mockClientCache");
|
||||
|
||||
verify(postProcessor, never()).regionNames(any(ClientCache.class));
|
||||
verify(postProcessor, never()).createClientProxyRegions(any(ConfigurableBeanFactory.class),
|
||||
any(ClientCache.class), any(Iterable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -170,28 +257,30 @@ public class GemfireDataSourcePostProcessorTest {
|
||||
|
||||
String[] expectedRegionNames = { "ExampleOne", "ExampleTwo" };
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor(this.mockClientCache));
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
doReturn(Arrays.asList(expectedRegionNames)).when(postProcessor)
|
||||
.execute(isA(ListRegionsOnServerFunction.class), any());
|
||||
.execute(isA(ClientCache.class), isA(ListRegionsOnServerFunction.class), any());
|
||||
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames();
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames(this.mockClientCache);
|
||||
|
||||
assertThat(actualRegionNames).containsExactly(expectedRegionNames);
|
||||
|
||||
verify(postProcessor, times(1)).execute(isA(ListRegionsOnServerFunction.class));
|
||||
verify(postProcessor, never()).execute(any(GetRegionsFunction.class));
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(ListRegionsOnServerFunction.class));
|
||||
|
||||
verify(postProcessor, never()).execute(any(ClientCache.class), any(GetRegionsFunction.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void regionNamesWithGetRegionsFunction() {
|
||||
|
||||
String[] expectedRegionNames = { "ExampleOne", "ExampleTwo" };
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor(this.mockClientCache));
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
doThrow(new RuntimeException("fail")).when(postProcessor).execute(isA(ListRegionsOnServerFunction.class), any());
|
||||
doThrow(new RuntimeException("FAIL")).when(postProcessor)
|
||||
.execute(isA(ClientCache.class), isA(ListRegionsOnServerFunction.class), any());
|
||||
|
||||
doAnswer(invocation ->
|
||||
Arrays.stream(expectedRegionNames)
|
||||
@@ -199,103 +288,110 @@ public class GemfireDataSourcePostProcessorTest {
|
||||
.map(this::newRegionInformation)
|
||||
.collect(Collectors.toList())
|
||||
.toArray()
|
||||
).when(postProcessor).execute(isA(GetRegionsFunction.class), any());
|
||||
).when(postProcessor).execute(isA(ClientCache.class), isA(GetRegionsFunction.class), any());
|
||||
|
||||
List<String> actualRegionNames =
|
||||
StreamSupport.stream(postProcessor.regionNames().spliterator(), false).collect(Collectors.toList());
|
||||
StreamSupport.stream(postProcessor.regionNames(this.mockClientCache).spliterator(), false)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(actualRegionNames).containsExactly(expectedRegionNames);
|
||||
|
||||
verify(postProcessor, times(1)).execute(isA(ListRegionsOnServerFunction.class));
|
||||
verify(postProcessor, times(1)).execute(isA(GetRegionsFunction.class));
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(ListRegionsOnServerFunction.class));
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(GetRegionsFunction.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionNamesWithGetRegionsFunctionReturningNoResults() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor(this.mockClientCache));
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
doThrow(new RuntimeException("fail")).when(postProcessor).execute(isA(ListRegionsOnServerFunction.class), any());
|
||||
doReturn(null).when(postProcessor).execute(isA(GetRegionsFunction.class), any());
|
||||
doThrow(new RuntimeException("FAIL")).when(postProcessor)
|
||||
.execute(any(ClientCache.class), isA(ListRegionsOnServerFunction.class), any());
|
||||
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames();
|
||||
doReturn(null).when(postProcessor)
|
||||
.execute(any(ClientCache.class), isA(GetRegionsFunction.class), any());
|
||||
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames(this.mockClientCache);
|
||||
|
||||
assertThat(actualRegionNames).isNotNull();
|
||||
assertThat(actualRegionNames).isEmpty();
|
||||
|
||||
verify(postProcessor, times(1)).execute(isA(ListRegionsOnServerFunction.class));
|
||||
verify(postProcessor, times(1)).execute(isA(GetRegionsFunction.class));
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(ListRegionsOnServerFunction.class));
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(GetRegionsFunction.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionNamesWithGetRegionsFunctionThrowingException() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor(this.mockClientCache));
|
||||
GemfireDataSourcePostProcessor postProcessor = spy(new GemfireDataSourcePostProcessor());
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
Function function = invocation.getArgument(0);
|
||||
|
||||
throw new IllegalArgumentException(String.format("Function [%1$s] with ID [%2$s] not registered",
|
||||
function.getClass().getName(), function.getId()));
|
||||
throw newIllegalArgumentException("Function [%1$s] with ID [%2$s] not registered",
|
||||
function.getClass().getName(), function.getId());
|
||||
|
||||
}).when(postProcessor).execute(any(Function.class), any());
|
||||
}).when(postProcessor).execute(any(ClientCache.class), any(Function.class), any());
|
||||
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames();
|
||||
Iterable<String> actualRegionNames = postProcessor.regionNames(this.mockClientCache);
|
||||
|
||||
assertThat(actualRegionNames).isNotNull();
|
||||
assertThat(actualRegionNames).isEmpty();
|
||||
|
||||
verify(postProcessor, times(1)).execute(isA(ListRegionsOnServerFunction.class));
|
||||
verify(postProcessor, times(1)).execute(isA(GetRegionsFunction.class));
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(ListRegionsOnServerFunction.class));
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.execute(eq(this.mockClientCache), isA(GetRegionsFunction.class));
|
||||
|
||||
verify(postProcessor, times(1))
|
||||
.logDebug(startsWith("Failed to determine the Regions available on the Server:"), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsRegionInformationIsTrue() {
|
||||
assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache)
|
||||
assertThat(new GemfireDataSourcePostProcessor()
|
||||
.containsRegionInformation(new Object[] { newRegionInformation(mockRegion("Example")) }))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsRegionInformationWithEmptyArrayIsFalse() {
|
||||
assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache)
|
||||
.containsRegionInformation(new Object[0]))
|
||||
.isFalse();
|
||||
assertThat(new GemfireDataSourcePostProcessor().containsRegionInformation(new Object[0])).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsRegionInformationWithListOfRegionInformationIsFalse() {
|
||||
assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache)
|
||||
assertThat(new GemfireDataSourcePostProcessor()
|
||||
.containsRegionInformation(Collections.singletonList(newRegionInformation(mockRegion("Example")))))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsRegionInformationWithNonEmptyArrayContainingNonRegionInformationIsFalse() {
|
||||
assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache)
|
||||
.containsRegionInformation(new Object[] { "test" }))
|
||||
.isFalse();
|
||||
assertThat(new GemfireDataSourcePostProcessor().containsRegionInformation(new Object[] { "TEST" })).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsRegionInformationWithNullIsFalse() {
|
||||
assertThat(new GemfireDataSourcePostProcessor(this.mockClientCache).containsRegionInformation(null))
|
||||
.isFalse();
|
||||
assertThat(new GemfireDataSourcePostProcessor().containsRegionInformation(null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void createClientProxyRegionsIsSuccessful() {
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache");
|
||||
ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class);
|
||||
|
||||
ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, "MockGemFireClientRegionFactory");
|
||||
|
||||
when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY))).thenReturn(
|
||||
mockClientRegionFactory);
|
||||
when(this.mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY)))
|
||||
.thenReturn(mockClientRegionFactory);
|
||||
|
||||
Region mockRegionOne = mock(Region.class, "MockGemFireRegionOne");
|
||||
Region mockRegionTwo = mock(Region.class, "MockGemFireRegionTwo");
|
||||
@@ -315,60 +411,39 @@ public class GemfireDataSourcePostProcessorTest {
|
||||
|
||||
}).when(mockClientRegionFactory).create(any(String.class));
|
||||
|
||||
ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory");
|
||||
|
||||
when(mockBeanFactory.containsBean(any(String.class))).thenReturn(false);
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(mockClientCache);
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor();
|
||||
|
||||
postProcessor.createClientProxyRegions(mockBeanFactory, regionMap.keySet());
|
||||
postProcessor.createClientProxyRegions(this.mockBeanFactory, this.mockClientCache, regionMap.keySet());
|
||||
|
||||
verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY));
|
||||
verify(this.mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY));
|
||||
verify(mockClientRegionFactory, times(1)).create(eq("RegionOne"));
|
||||
verify(mockClientRegionFactory, times(1)).create(eq("RegionTwo"));
|
||||
verify(mockBeanFactory, times(1)).registerSingleton(eq("RegionOne"), same(mockRegionOne));
|
||||
verify(mockBeanFactory, times(1)).registerSingleton(eq("RegionTwo"), same(mockRegionTwo));
|
||||
verify(this.mockBeanFactory, times(1)).registerSingleton(eq("RegionOne"), same(mockRegionOne));
|
||||
verify(this.mockBeanFactory, times(1)).registerSingleton(eq("RegionTwo"), same(mockRegionTwo));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void createClientProxyRegionsWhenRegionBeanExists() {
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, "MockGemFireClientCache");
|
||||
ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class);
|
||||
|
||||
ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, "MockGemFireClientRegionFactory");
|
||||
when(this.mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY)))
|
||||
.thenReturn(mockClientRegionFactory);
|
||||
|
||||
when(mockClientCache.createClientRegionFactory(eq(ClientRegionShortcut.PROXY))).thenReturn(
|
||||
mockClientRegionFactory);
|
||||
Region mockRegion = mock(Region.class);
|
||||
|
||||
Region mockRegion = mock(Region.class, "MockGemFireRegion");
|
||||
when(this.mockBeanFactory.containsBean(any(String.class))).thenReturn(true);
|
||||
when(this.mockBeanFactory.getBean(eq("Example"))).thenReturn(mockRegion);
|
||||
|
||||
ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class, "MockSpringBeanFactory");
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor();
|
||||
|
||||
when(mockBeanFactory.containsBean(any(String.class))).thenReturn(true);
|
||||
when(mockBeanFactory.getBean(eq("Example"))).thenReturn(mockRegion);
|
||||
postProcessor.createClientProxyRegions(this.mockBeanFactory, this.mockClientCache, Collections.singletonList("Example"));
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(mockClientCache);
|
||||
|
||||
postProcessor.createClientProxyRegions(mockBeanFactory, Collections.singletonList("Example"));
|
||||
|
||||
verify(mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY));
|
||||
verify(this.mockClientCache, times(1)).createClientRegionFactory(eq(ClientRegionShortcut.PROXY));
|
||||
verify(mockClientRegionFactory, never()).create(any(String.class));
|
||||
verify(mockBeanFactory, never()).registerSingleton(any(String.class), any(Region.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usingIsCorrect() {
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = new GemfireDataSourcePostProcessor(this.mockClientCache)
|
||||
.using(ClientRegionShortcut.LOCAL);
|
||||
|
||||
assertThat(postProcessor).isNotNull();
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null)).isEqualTo(ClientRegionShortcut.LOCAL);
|
||||
assertThat(postProcessor.using(ClientRegionShortcut.CACHING_PROXY)).isEqualTo(postProcessor);
|
||||
assertThat(postProcessor.getClientRegionShortcut()
|
||||
.orElse(null)).isEqualTo(ClientRegionShortcut.CACHING_PROXY);
|
||||
assertThat(postProcessor.using(null)).isEqualTo(postProcessor);
|
||||
assertThat(postProcessor.getClientRegionShortcut().isPresent()).isFalse();
|
||||
verify(this.mockBeanFactory, never()).registerSingleton(any(String.class), any(Region.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.config.annotation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -25,12 +24,16 @@ import javax.annotation.Resource;
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -41,6 +44,7 @@ import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.process.ProcessWrapper;
|
||||
import org.springframework.data.gemfire.support.ConnectionEndpoint;
|
||||
import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.CacheUtils;
|
||||
import org.springframework.data.gemfire.util.RegionUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
@@ -88,6 +92,9 @@ public class EnableClusterDefinedRegionsIntegrationTests extends ClientServerInt
|
||||
stop(gemfireServer);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ClientCache cache;
|
||||
|
||||
@Resource(name = "LocalRegion")
|
||||
private Region<?, ?> localClientProxyRegion;
|
||||
|
||||
@@ -106,6 +113,13 @@ public class EnableClusterDefinedRegionsIntegrationTests extends ClientServerInt
|
||||
assertThat(region.getAttributes().getDataPolicy()).isEqualTo(DataPolicy.EMPTY);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
assertThat(this.cache).isNotNull();
|
||||
assertThat(CacheUtils.isClient(this.cache));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clusterRegionsExistOnClient() {
|
||||
|
||||
@@ -130,10 +144,14 @@ public class EnableClusterDefinedRegionsIntegrationTests extends ClientServerInt
|
||||
return (bean, clientCacheFactoryBean) -> clientCacheFactoryBean.setServers(
|
||||
Collections.singletonList(new ConnectionEndpoint("localhost", port)));
|
||||
}
|
||||
|
||||
@Bean("TestBean")
|
||||
Object testBean(@Qualifier("LocalRegion") Region<?, ?> localRegion) {
|
||||
return "TEST";
|
||||
}
|
||||
}
|
||||
|
||||
@CacheServerApplication(name = "EnableClusterDefinedRegionsIntegrationTests",
|
||||
logLevel = GEMFIRE_LOG_LEVEL)
|
||||
@CacheServerApplication(name = "EnableClusterDefinedRegionsIntegrationTests", logLevel = GEMFIRE_LOG_LEVEL)
|
||||
static class ServerTestConfiguration {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.config.annotation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -24,11 +23,13 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.gemfire.client.GemfireDataSourcePostProcessor;
|
||||
|
||||
@@ -93,27 +94,33 @@ public class EnableClusterDefinedRegionsUnitTests {
|
||||
@Test
|
||||
public void configureGemfireDataSourcePostProcessor() {
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class);
|
||||
ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class);
|
||||
|
||||
ClusterDefinedRegionsConfiguration configuration = new ClusterDefinedRegionsConfiguration();
|
||||
|
||||
configuration.setBeanFactory(mockBeanFactory);
|
||||
configuration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY);
|
||||
|
||||
GemfireDataSourcePostProcessor postProcessor = configuration.gemfireDataSourcePostProcessor(mockClientCache);
|
||||
GemfireDataSourcePostProcessor postProcessor = configuration.gemfireDataSourcePostProcessor();
|
||||
|
||||
assertThat(postProcessor.getBeanFactory().orElse(null)).isEqualTo(mockBeanFactory);
|
||||
assertThat(postProcessor.getClientRegionShortcut().orElse(null))
|
||||
.isEqualTo(ClientRegionShortcut.CACHING_PROXY);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void configureGemfireDataSourcePostProcessorWithNullCache() {
|
||||
public void configuresSpringApplicationWithGenericCache() {
|
||||
|
||||
GemFireCache mockCache = mock(GemFireCache.class);
|
||||
|
||||
try {
|
||||
new ClusterDefinedRegionsConfiguration().gemfireDataSourcePostProcessor(null);
|
||||
new ClusterDefinedRegionsConfiguration().nullCacheDependentBean(mockCache);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("GemFireCache must be an instance of ClientCache");
|
||||
assertThat(expected).hasMessage("GemFireCache [%s] must be a %s",
|
||||
mockCache.getClass().getName(), ClientCache.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
@@ -121,17 +128,33 @@ public class EnableClusterDefinedRegionsUnitTests {
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void configureGemfireDataSourcePostProcessorWithPeerCache() {
|
||||
public void configuresSpringApplicationWithNullCache() {
|
||||
|
||||
try {
|
||||
|
||||
Cache mockPeerCache = mock(Cache.class);
|
||||
|
||||
new ClusterDefinedRegionsConfiguration().gemfireDataSourcePostProcessor(mockPeerCache);
|
||||
new ClusterDefinedRegionsConfiguration().nullCacheDependentBean(null);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("GemFireCache must be an instance of ClientCache");
|
||||
assertThat(expected).hasMessage("GemFireCache [null] must be a %s", ClientCache.class.getName());
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void configuresSpringApplicationWithPeerCache() {
|
||||
|
||||
Cache mockCache = mock(Cache.class);
|
||||
|
||||
try {
|
||||
new ClusterDefinedRegionsConfiguration().nullCacheDependentBean(mockCache);
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
|
||||
assertThat(expected).hasMessage("GemFireCache [%s] must be a %s",
|
||||
mockCache.getClass().getName(), ClientCache.class.getName());
|
||||
|
||||
assertThat(expected).hasNoCause();
|
||||
|
||||
throw expected;
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:gfe="http://www.springframework.org/schema/geode"
|
||||
xmlns:gfe-data="http://www.springframework.org/schema/data/geode"
|
||||
xmlns:repo="http://www.springframework.org/schema/data/repository"
|
||||
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 https://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/geode https://www.springframework.org/schema/geode/spring-geode.xsd
|
||||
http://www.springframework.org/schema/data/geode https://www.springframework.org/schema/data/geode/spring-data-geode.xsd
|
||||
http://www.springframework.org/schema/data/repository https://www.springframework.org/schema/data/repository/spring-repository.xsd
|
||||
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<context:property-placeholder/>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.MethodInvokingBean">
|
||||
<property name="targetClass" value="java.lang.System"/>
|
||||
<property name="targetMethod" value="setProperty"/>
|
||||
<property name="arguments">
|
||||
<list>
|
||||
<value>gemfire.log-level</value>
|
||||
<value>warning</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
<util:properties id="gemfireProperties">
|
||||
<prop key="name">RepositoryClientRegionIntegrationTests</prop>
|
||||
<prop key="log-level">error</prop>
|
||||
</util:properties>
|
||||
|
||||
<gfe-data:datasource>
|
||||
<gfe-data:server host="localhost" port="${spring.data.gemfire.cache.server.port:40404}"/>
|
||||
</gfe-data:datasource>
|
||||
<gfe:client-cache properties-ref="gemfireProperties"/>
|
||||
|
||||
<gfe:pool>
|
||||
<gfe:server host="localhost" port="${spring.data.gemfire.cache.server.port:40404}"/>
|
||||
</gfe:pool>
|
||||
|
||||
<gfe:client-region id="simple" shortcut="PROXY"/>
|
||||
|
||||
<gfe-data:repositories base-package="org.springframework.data.gemfire.repository.sample">
|
||||
<repo:include-filter type="assignable" expression="org.springframework.data.gemfire.repository.sample.PersonRepository"/>
|
||||
|
||||
Reference in New Issue
Block a user