DATAGEODE-198 - Change the generic signature of the Configurer interface.

This commit is contained in:
John Blum
2019-06-08 13:00:19 -07:00
parent 29443fdb50
commit cc987bdbd6
19 changed files with 304 additions and 151 deletions

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
@@ -23,10 +22,10 @@ import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIter
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.StreamSupport;
import org.apache.geode.cache.Region;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
@@ -57,6 +56,12 @@ public abstract class ConfigurableRegionFactoryBean<K, V> extends ResolvableRegi
nullSafeCollection(regionConfigurers)
.forEach(regionConfigurer -> regionConfigurer.configure(beanName, bean));
}
@Override
public void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) {
nullSafeCollection(regionConfigurers)
.forEach(regionConfigurer -> regionConfigurer.configure(beanName, bean));
}
};
/**
@@ -92,7 +97,10 @@ public abstract class ConfigurableRegionFactoryBean<K, V> extends ResolvableRegi
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
*/
public void setRegionConfigurers(List<RegionConfigurer> regionConfigurers) {
this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList);
this.regionConfigurers = regionConfigurers != null
? regionConfigurers
: Collections.emptyList();
}
/**
@@ -135,13 +143,13 @@ public abstract class ConfigurableRegionFactoryBean<K, V> extends ResolvableRegi
*/
protected void applyRegionConfigurers(String regionName, Iterable<RegionConfigurer> regionConfigurers) {
if (this instanceof PeerRegionFactoryBean) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, (PeerRegionFactoryBean<K, V>) this));
}
else if (this instanceof ClientRegionFactoryBean) {
if (this instanceof ClientRegionFactoryBean) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, (ClientRegionFactoryBean<K, V>) this));
}
else if (this instanceof PeerRegionFactoryBean) {
StreamSupport.stream(nullSafeIterable(regionConfigurers).spliterator(), false)
.forEach(regionConfigurer -> regionConfigurer.configure(regionName, (PeerRegionFactoryBean<K, V>) this));
}
}
}

View File

@@ -13,16 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.client;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeCollection;
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
@@ -42,11 +38,11 @@ import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.client.PoolManager;
import org.apache.geode.compression.Compressor;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.gemfire.ConfigurableRegionFactoryBean;
import org.springframework.data.gemfire.GemfireUtils;
import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
import org.springframework.data.gemfire.config.xml.GemfireConstants;
import org.springframework.data.gemfire.eviction.EvictingRegionFactoryBean;
import org.springframework.data.gemfire.expiration.ExpiringRegionFactoryBean;
@@ -126,19 +122,8 @@ public class ClientRegionFactoryBean<K, V> extends ConfigurableRegionFactoryBean
private Float loadFactor;
private List<RegionConfigurer> regionConfigurers = Collections.emptyList();
private RegionAttributes<K, V> attributes;
private RegionConfigurer compositeRegionConfigurer = new RegionConfigurer() {
@Override
public void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) {
nullSafeCollection(regionConfigurers)
.forEach(regionConfigurer -> regionConfigurer.configure(beanName, bean));
}
};
private String diskStoreName;
private String poolName;
@@ -154,7 +139,7 @@ public class ClientRegionFactoryBean<K, V> extends ConfigurableRegionFactoryBean
* @see org.apache.geode.cache.Region
*/
@Override
protected Region<K, V> createRegion(GemFireCache gemfireCache, String regionName) throws Exception {
protected Region<K, V> createRegion(GemFireCache gemfireCache, String regionName) {
applyRegionConfigurers(regionName);
@@ -186,7 +171,7 @@ public class ClientRegionFactoryBean<K, V> extends ConfigurableRegionFactoryBean
logInfo("Creating client sub-Region [%1$s] with parent Region [%2$s]",
regionName, parent.getName());
return clientRegionFactory.<K, V>createSubregion(parent, regionName);
return clientRegionFactory.createSubregion(parent, regionName);
}
else {
logInfo("Creating client Region [%s]", regionName);

View File

@@ -22,18 +22,21 @@ import org.springframework.data.gemfire.config.annotation.support.Configurer;
import org.springframework.data.gemfire.server.CacheServerFactoryBean;
/**
* The {@link CacheServerConfigurer} interface defines a contract for implementations to customize the configuration
* of a {@link CacheServerFactoryBean} used to construct, configure and initialize an instance of a {@link CacheServer}.
* The {@link CacheServerConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of a {@link CacheServerFactoryBean} used to construct, configure and initialize
* an instance of {@link CacheServer}.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.server.CacheServer
* @see org.springframework.data.gemfire.config.annotation.CacheServerApplication
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServers
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServer
* @see org.springframework.data.gemfire.config.annotation.EnableCacheServers
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @see org.springframework.data.gemfire.server.CacheServerFactoryBean
* @since 1.9.0
* @since 2.0.0
*/
@FunctionalInterface
public interface CacheServerConfigurer extends Configurer<CacheServerFactoryBean> {
}

View File

@@ -22,16 +22,19 @@ import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
/**
* The {@link ClientCacheConfigurer} interface defines a contract for implementations to customize the configuration
* of a {@link ClientCacheFactoryBean} used to construct, configure and initialize an instance of a {@link ClientCache}.
* The {@link ClientCacheConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of a {@link ClientCacheFactoryBean} used to construct, configure and initialize
* an instance of a {@link ClientCache}.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.client.ClientCache
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @since 1.9.0
* @since 2.0.0
*/
@FunctionalInterface
public interface ClientCacheConfigurer extends Configurer<ClientCacheFactoryBean> {
}

View File

@@ -13,17 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.config.annotation;
import static java.util.Arrays.stream;
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@@ -31,10 +28,10 @@ import java.util.stream.Collectors;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.query.CqQuery;
import org.apache.geode.cache.query.QueryService;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
@@ -135,6 +132,7 @@ public class ContinuousQueryConfiguration extends AbstractAnnotationConfigSuppor
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ContinuousQueryListenerContainer) {
this.container = (ContinuousQueryListenerContainer) bean;
this.continuousQueryDefinitions.forEach(this.container::addListener);
this.continuousQueryDefinitions.clear();
@@ -216,21 +214,8 @@ public class ContinuousQueryConfiguration extends AbstractAnnotationConfigSuppor
protected List<ContinuousQueryListenerContainerConfigurer> resolveContinuousQueryListenerContainerConfigurers() {
return Optional.ofNullable(this.configurers)
.filter(configurers -> !configurers.isEmpty())
.orElseGet(() ->
Optional.of(this.getBeanFactory())
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
.map(beanFactory -> {
Map<String, ContinuousQueryListenerContainerConfigurer> beansOfType =
((ListableBeanFactory) beanFactory).getBeansOfType(ContinuousQueryListenerContainerConfigurer.class,
true, false);
return nullSafeMap(beansOfType).values().stream().collect(Collectors.toList());
})
.orElseGet(Collections::emptyList)
);
Collections.singletonList(LazyResovlingComposableContinuousQueryListenerContainerConfigurer.create(getBeanFactory())));
}
protected Optional<ErrorHandler> resolveErrorHandler() {

View File

@@ -13,29 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.gemfire.config.annotation;
import org.apache.geode.cache.client.ClientCache;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer;
/**
* The {@link ContinuousQueryListenerContainerConfigurer} interfaces defines a contract for implementations to customize
* the configuration of SDG's {@link ContinuousQueryListenerContainer} when enabling Continuous Query (CQ) functionality
* in Spring Boot, GemFire/Geode cache client applications.
* The {@link ContinuousQueryListenerContainerConfigurer} interfaces defines a contract for implementing {@link Object Objects}
* in order to customize the configuration of a {@link ContinuousQueryListenerContainer} when enabling Continuous Query
* (CQ) functionality in a Spring Boot, Apache Geode/Pivotal GemFire {@link ClientCache} applications.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.client.ClientCache
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @see org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer
* @since 2.0.0
*/
public interface ContinuousQueryListenerContainerConfigurer {
/**
* Applies addditional configuration to the declared/defined {@link ContinuousQueryListenerContainer}.
*
* @param beanName {@link String name} of the {@link ContinuousQueryListenerContainer} bean definition.
* @param container reference to the {@link ContinuousQueryListenerContainer} instance.
* @see org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer
*/
void configure(String beanName, ContinuousQueryListenerContainer container);
@FunctionalInterface
public interface ContinuousQueryListenerContainerConfigurer extends Configurer<ContinuousQueryListenerContainer> {
}

View File

@@ -21,10 +21,12 @@ import org.springframework.data.gemfire.DiskStoreFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
/**
* The {@link DiskStoreConfigurer} interface defines a contract for implementations to customize the configuration
* of a {@link DiskStoreFactoryBean} used to construct, configure and initialize a {@link DiskStore}.
* The {@link DiskStoreConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of a {@link DiskStoreFactoryBean} used to construct, configure and initialize
* a {@link DiskStore}.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.DiskStore
* @see org.springframework.data.gemfire.DiskStoreFactoryBean
* @see org.springframework.data.gemfire.config.annotation.EnableDiskStore
@@ -32,6 +34,7 @@ import org.springframework.data.gemfire.config.annotation.support.Configurer;
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @since 2.0.0
*/
@FunctionalInterface
public interface DiskStoreConfigurer extends Configurer<DiskStoreFactoryBean> {
}

View File

@@ -24,9 +24,9 @@ import org.springframework.data.gemfire.config.annotation.support.Configurer;
import org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean;
/**
* The {@link IndexConfigurer} interface defines a contract for implementations to customize the configuration
* of Entity-defined {@link Index Indexes} when a user annotates her Spring application {@link Configuration}
* class with {@link EnableIndexing}.
* The {@link IndexConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of Entity-defined {@link Index Indexes} when a user annotates her Spring application
* {@link Configuration} {@link Class} with {@link EnableIndexing}.
*
* @author John Blum
* @see org.apache.geode.cache.lucene.LuceneIndex
@@ -44,7 +44,7 @@ public interface IndexConfigurer extends Configurer<IndexFactoryBean> {
* Configuration callback method providing a reference to a {@link IndexFactoryBean} used to construct, configure
* and initialize an instance of a peer {@link Index}.
*
* @param beanName name of {@link Index} bean declared in the Spring application context.
* @param beanName name of the {@link Index} bean declared in the Spring application context.
* @param bean reference to the {@link IndexFactoryBean}.
* @see org.springframework.data.gemfire.IndexFactoryBean
*/
@@ -54,7 +54,7 @@ public interface IndexConfigurer extends Configurer<IndexFactoryBean> {
* Configuration callback method providing a reference to a {@link LuceneIndexFactoryBean} used to construct,
* configure and initialize an instance of a peer {@link LuceneIndex}.
*
* @param beanName name of {@link LuceneIndex} bean declared in the Spring application context.
* @param beanName name of the {@link LuceneIndex} bean declared in the Spring application context.
* @param bean reference to the {@link LuceneIndexFactoryBean}.
* @see org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean
*/

View File

@@ -16,6 +16,7 @@
package org.springframework.data.gemfire.config.annotation;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.data.gemfire.ConfigurableRegionFactoryBean;
import org.springframework.data.gemfire.PeerRegionFactoryBean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.AbstractLazyResolvingComposableConfigurer;
@@ -25,6 +26,8 @@ import org.springframework.lang.Nullable;
* Composition for {@link RegionConfigurer}.
*
* @author John Blum
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.data.gemfire.ConfigurableRegionFactoryBean
* @see org.springframework.data.gemfire.PeerRegionFactoryBean
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
@@ -32,7 +35,7 @@ import org.springframework.lang.Nullable;
* @since 2.2.0
*/
public class LazyResolvingComposableRegionConfigurer
extends AbstractLazyResolvingComposableConfigurer<ClientRegionFactoryBean<?, ?>, RegionConfigurer>
extends AbstractLazyResolvingComposableConfigurer<ConfigurableRegionFactoryBean<?, ?>, RegionConfigurer>
implements RegionConfigurer {
public static LazyResolvingComposableRegionConfigurer create() {
@@ -49,9 +52,12 @@ public class LazyResolvingComposableRegionConfigurer
}
@Override
public void configure(String beanName, PeerRegionFactoryBean<?, ?> peerRegionFactoryBean) {
public void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) {
resolveConfigurers().forEach(configurer -> configurer.configure(beanName, bean));
}
resolveConfigurers().forEach(configurer ->
configurer.configure(beanName, peerRegionFactoryBean));
@Override
public void configure(String beanName, PeerRegionFactoryBean<?, ?> peerRegionFactoryBean) {
resolveConfigurers().forEach(configurer -> configurer.configure(beanName, peerRegionFactoryBean));
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2018 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
*
* https://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.config.annotation;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.data.gemfire.config.annotation.support.AbstractLazyResolvingComposableConfigurer;
import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer;
import org.springframework.lang.Nullable;
/**
* Composition of {@link ContinuousQueryListenerContainerConfigurer}.
*
* @author John Blum
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.data.gemfire.config.annotation.ContinuousQueryListenerContainerConfigurer
* @see org.springframework.data.gemfire.config.annotation.support.AbstractLazyResolvingComposableConfigurer
* @see org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer
* @since 2.2.0
*/
public class LazyResovlingComposableContinuousQueryListenerContainerConfigurer
extends AbstractLazyResolvingComposableConfigurer<ContinuousQueryListenerContainer, ContinuousQueryListenerContainerConfigurer>
implements ContinuousQueryListenerContainerConfigurer {
public static LazyResovlingComposableContinuousQueryListenerContainerConfigurer create() {
return create(null);
}
public static LazyResovlingComposableContinuousQueryListenerContainerConfigurer create(@Nullable BeanFactory beanFactory) {
return new LazyResovlingComposableContinuousQueryListenerContainerConfigurer().with(beanFactory);
}
@Override
protected Class<ContinuousQueryListenerContainerConfigurer> getConfigurerType() {
return ContinuousQueryListenerContainerConfigurer.class;
}
}

View File

@@ -22,16 +22,19 @@ import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
/**
* The {@link PeerCacheConfigurer} interface defines a contract for implementations to customize the configuration
* of a {@link CacheFactoryBean} used to construct, configure and initialize an instance of a peer {@link Cache}.
* The {@link PeerCacheConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of a {@link CacheFactoryBean} used to construct, configure and initialize
* an instance of a peer {@link Cache}.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.Cache
* @see org.springframework.data.gemfire.CacheFactoryBean
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @since 1.9.0
*/
@FunctionalInterface
public interface PeerCacheConfigurer extends Configurer<CacheFactoryBean> {
}

View File

@@ -16,23 +16,24 @@
package org.springframework.data.gemfire.config.annotation;
import org.apache.geode.cache.client.Pool;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
/**
* The {@link PoolConfigurer} interface defines a contract for implementations to customize the configuration
* of a {@link PoolFactoryBean} used to construct, configure and initialize a {@link Pool}.
* The {@link PoolConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of a {@link PoolFactoryBean} used to construct, configure and initialize a {@link Pool}.
*
* @author John Blum
* @see java.lang.FunctionalInterface
* @see org.apache.geode.cache.client.Pool
* @see org.springframework.data.gemfire.client.PoolFactoryBean
* @see org.springframework.data.gemfire.config.annotation.AddPoolConfiguration
* @see org.springframework.data.gemfire.config.annotation.AddPoolsConfiguration
* @see org.springframework.data.gemfire.config.annotation.EnablePool
* @see org.springframework.data.gemfire.config.annotation.EnablePools
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @since 1.1.0
* @since 2.0.0
*/
@FunctionalInterface
public interface PoolConfigurer extends Configurer<PoolFactoryBean> {
}

View File

@@ -18,15 +18,15 @@ package org.springframework.data.gemfire.config.annotation;
import org.apache.geode.cache.Region;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.ConfigurableRegionFactoryBean;
import org.springframework.data.gemfire.PeerRegionFactoryBean;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean;
import org.springframework.data.gemfire.config.annotation.support.Configurer;
/**
* The {@link RegionConfigurer} interface defines a contract for implementations to customize the configuration
* of Entity-defined {@link Region Regions} when a user annotates her Spring application {@link Configuration}
* class with {@link EnableEntityDefinedRegions}.
* The {@link RegionConfigurer} interface defines a contract for implementing {@link Object Objects} in order to
* customize the configuration of Entity-defined {@link Region Regions} when a user annotates her Spring application
* {@link Configuration} {@link Class} with {@link EnableEntityDefinedRegions} or {@link EnableCachingDefinedRegions}.
*
* @author John Blum
* @see org.apache.geode.cache.Region
@@ -35,29 +35,49 @@ import org.springframework.data.gemfire.config.annotation.support.Configurer;
* @see org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @see CacheTypeAwareRegionFactoryBean
* @see org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean
* @since 2.0.0
*/
public interface RegionConfigurer extends Configurer<ClientRegionFactoryBean<?, ?>> {
public interface RegionConfigurer extends Configurer<ConfigurableRegionFactoryBean<?, ?>> {
/**
* Configuration callback method providing a reference to a {@link PeerRegionFactoryBean} used to construct, configure
* and initialize an instance of a peer {@link Region}.
* Applies additional user-defined configuration to the {@link ConfigurableRegionFactoryBean}.
*
* @param beanName name of {@link Region} bean declared in the Spring application context.
* @param bean reference to the {@link PeerRegionFactoryBean}.
* @see PeerRegionFactoryBean
* @param beanName {@link String} containing the name of the Spring bean (component).
* @param bean Spring component used to construct, configure and initialize the Apache Geode or Pivotal GemFire
* @see org.springframework.data.gemfire.ConfigurableRegionFactoryBean
* @see #configure(String, ClientRegionFactoryBean)
* @see #configure(String, PeerRegionFactoryBean)
*/
default void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) { }
@Override
default void configure(String beanName, ConfigurableRegionFactoryBean<?, ?> bean) {
if (bean instanceof ClientRegionFactoryBean) {
configure(beanName, (ClientRegionFactoryBean<?, ?>) bean);
}
else {
configure(beanName, (PeerRegionFactoryBean<?, ?>) bean);
}
}
/**
* Configuration callback method providing a reference to a {@link ClientRegionFactoryBean} used to construct,
* configure and initialize an instance of a client {@link Region}.
*
* @param beanName name of {@link Region} bean declared in the Spring application context.
* @param bean reference to the {@link ClientRegionFactoryBean}.
* @param bean reference to the {@link ClientRegionFactoryBean} used to create the client {@link Region}.
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
*/
default void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) { }
/**
* Configuration callback method providing a reference to a {@link PeerRegionFactoryBean} used to construct,
* configure and initialize an instance of a peer {@link Region}.
*
* @param beanName name of {@link Region} bean declared in the Spring application context.
* @param bean reference to the {@link PeerRegionFactoryBean} used to create the peer {@link Region}.
* @see org.springframework.data.gemfire.PeerRegionFactoryBean
*/
default void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) { }
}

View File

@@ -14,7 +14,6 @@
* limitations under the License.
*
*/
package org.springframework.data.gemfire.config.annotation.support;
import static org.springframework.data.gemfire.util.CollectionUtils.asSet;
@@ -33,6 +32,7 @@ import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
@@ -151,6 +151,7 @@ public abstract class AbstractAnnotationConfigSupport
* @see #newEvaluationContext(BeanFactory)
*/
public AbstractAnnotationConfigSupport(BeanFactory beanFactory) {
this.evaluationContext = newEvaluationContext(beanFactory);
this.log = newLog();
}

View File

@@ -25,23 +25,24 @@ import java.util.stream.Stream;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.core.OrderComparator;
import org.springframework.lang.Nullable;
/**
* Abstract base class for {@link Configurer} interface implementations, encapsulating logic and functionality
* common to all {@link Configurer} implementations
* common to all lazy resolving, composable {@link Configurer} implementations.
*
* @author John Blum
* @param <T> {@link Class} type of the configurable Spring component processed by this {@link Configurer}.
* @param <C> {@link Class sub-Class} type of {@link Configurer}.
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.core.OrderComparator
* @see org.springframework.data.gemfire.config.annotation.support.Configurer
* @since 2.2.0
*/
public abstract class AbstractLazyResolvingComposableConfigurer<T extends FactoryBean<?>, C extends Configurer<T>>
public abstract class AbstractLazyResolvingComposableConfigurer<T, C extends Configurer<T>>
implements BeanFactoryAware, Configurer<T> {
private BeanFactory beanFactory;
@@ -109,18 +110,18 @@ public abstract class AbstractLazyResolvingComposableConfigurer<T extends Factor
}
/**
* Applies the configuration from the composition of {@link Configurer Configurers} composed by this
* {@link Configurer} to the given {@link FactoryBean}.
* Applies the configuration from the composition of {@link Configurer Configurers} composed by
* this {@link Configurer} to the given Spring component (bean).
*
* @param beanName {@link String} containing the name of the Spring bean.
* @param factoryBean {@link FactoryBean} used to construct, configure and initialize the {@link Object}
* @param bean Spring component used to construct, configure and initialize the {@link Object}.
* @see #resolveConfigurers()
*/
@Override
public synchronized void configure(String beanName, T factoryBean) {
public synchronized void configure(String beanName, T bean) {
resolveConfigurers().forEach(configurer ->
configurer.configure(beanName, factoryBean));
configurer.configure(beanName, bean));
}
/**

View File

@@ -15,35 +15,38 @@
*/
package org.springframework.data.gemfire.config.annotation.support;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.core.Ordered;
/**
* The {@link Configurer} interface defines a contract for implementing objects that can modify
* some aspect of configuration given a reference to the Spring {@link FactoryBean} responsible
* for the configuration of some {@link Object} or Spring bean.
* The {@link Configurer} interface defines a contract for implementing objects that can modify some aspect
* of configuration given a reference to the Spring component responsible for the configuration of some
* Apache Geode or Pivotal GemFire {@link Object} declared as a bean in the Spring container.
*
* @author John Blum
* @see org.springframework.beans.factory.FactoryBean
* @param <T> {@link Class} type of the configurable Spring component processed by this {@link Configurer}.
* @see org.springframework.core.Ordered
* @since 2.2.0
*/
@FunctionalInterface
public interface Configurer<T extends FactoryBean<?>> extends Ordered {
public interface Configurer<T> extends Ordered {
/**
* Applies additional configuration to the given Spring {@link FactoryBean}.
* Applies additional user-defined configuration to the given Spring component.
*
* @param beanName {@link String} containing the name of the Spring bean.
* @param factoryBean {@link FactoryBean} used to construct, configure and initialize the {@link Object}
* or Spring Bean.
* @param beanName {@link String} containing the name of the Spring bean (component).
* @param bean Spring component used to construct, configure and initialize the Apache Geode or Pivotal GemFire
* {@link Object} declared as a bean in the Spring container.
*/
void configure(String beanName, T factoryBean);
void configure(String beanName, T bean);
/**
* Defines the {@literal order} of this {@link Configurer} bean relative to other {@link Configurer Configurers}.
* Determines the {@literal order} of this {@link Configurer} bean relative to other {@link Configurer Configurers}
* of the same {@link Class type}.
*
* Returns {@literal 0} by default.
*
* @return the {@literal order} in which this {@link Configurer} is applied.
* @see org.springframework.core.Ordered#getOrder()
*/
@Override
default int getOrder() {

View File

@@ -62,7 +62,7 @@ import org.springframework.util.StringUtils;
*/
@SuppressWarnings("unused")
public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnotationConfigSupport
implements ImportBeanDefinitionRegistrar {
implements ImportBeanDefinitionRegistrar {
public static final Integer DEFAULT_PORT = 0;
public static final String DEFAULT_HOST = "localhost";
@@ -81,13 +81,14 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
*/
@SuppressWarnings("unchecked")
protected <T extends AbstractCacheConfiguration> T getCacheConfiguration() {
return Optional.ofNullable((T) this.cacheConfiguration)
.orElseThrow(() -> newIllegalStateException("AbstractCacheConfiguration is required"));
}
@Override
public final void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
BeanDefinitionRegistry registry) {
if (isAnnotationPresent(importingClassMetadata)) {
Map<String, Object> annotationAttributes = getAnnotationAttributes(importingClassMetadata);
@@ -98,11 +99,12 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
@SuppressWarnings("unused")
protected void registerBeanDefinitions(AnnotationMetadata importingClassMetaData,
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
}
protected void setGemFireProperties(AnnotationMetadata importingClassMetadata,
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
Map<String, Object> annotationAttributes, BeanDefinitionRegistry registry) {
Properties gemfireProperties = toGemFireProperties(annotationAttributes);
@@ -125,7 +127,7 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
}
protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry,
Properties customGemFireProperties) {
Properties customGemFireProperties) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(GemFirePropertiesBeanPostProcessor.class);
@@ -142,7 +144,7 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
}
protected void registerClientGemFirePropertiesConfigurer(BeanDefinitionRegistry registry,
Properties gemfireProperties) {
Properties gemfireProperties) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(ClientGemFirePropertiesConfigurer.class);
@@ -153,7 +155,7 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
}
protected void registerPeerGemFirePropertiesConfigurer(BeanDefinitionRegistry registry,
Properties gemfireProperties) {
Properties gemfireProperties) {
BeanDefinitionBuilder builder =
BeanDefinitionBuilder.genericBeanDefinition(PeerGemFirePropertiesConfigurer.class);
@@ -165,8 +167,9 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
protected BeanDefinitionHolder newBeanDefinitionHolder(BeanDefinitionBuilder builder) {
return new BeanDefinitionHolder(builder.getBeanDefinition(),
generateBeanName(builder.getRawBeanDefinition().getBeanClass().getSimpleName()));
String beanName = generateBeanName(builder.getRawBeanDefinition().getBeanClass().getSimpleName());
return new BeanDefinitionHolder(builder.getBeanDefinition(), beanName);
}
protected String generateBeanName() {
@@ -221,7 +224,10 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
}
protected String resolveHost(String hostname, String defaultHostname) {
return Optional.ofNullable(hostname).filter(StringUtils::hasText).orElse(defaultHostname);
return Optional.ofNullable(hostname)
.filter(StringUtils::hasText)
.orElse(defaultHostname);
}
protected Integer resolvePort(Integer port) {
@@ -229,7 +235,9 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota
}
protected Integer resolvePort(Integer port, Integer defaultPort) {
return Optional.ofNullable(port).orElse(defaultPort);
return Optional.ofNullable(port)
.orElse(defaultPort);
}
protected static class AbstractGemFirePropertiesConfigurer {

View File

@@ -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;
@@ -22,11 +21,14 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.geode.cache.client.ClientCache;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.apache.geode.cache.client.ClientCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
@@ -41,17 +43,22 @@ import org.springframework.test.context.junit4.SpringRunner;
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.apache.geode.cache.client.ClientCache
* @see org.springframework.context.annotation.Bean
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication
* @see org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer
* @see org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor
* @see org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMockObjects
* @see org.springframework.test.context.junit4.SpringRunner
* @since 1.1.0
* @since 2.1.0
*/
@RunWith(SpringRunner.class)
@SuppressWarnings("unused")
public class ClientCacheConfigurerIntegrationTests {
private static final AtomicBoolean testClientCacheConfigurerThreeCalled = new AtomicBoolean(false);
private static final String GEMFIRE_LOG_LEVEL = "error";
@Autowired
private ClientCache clientCache;
@@ -86,8 +93,13 @@ public class ClientCacheConfigurerIntegrationTests {
assertClientCacheConfigurerInvokedSuccessfully(this.configurerTwo, "gemfireCache");
}
@Test
public void clientCacheConfigurerThreeCalledSuccessfully() {
assertThat(testClientCacheConfigurerThreeCalled.get()).isTrue();
}
@EnableGemFireMockObjects
@ClientCacheApplication(logLevel = "error")
@ClientCacheApplication(logLevel = GEMFIRE_LOG_LEVEL)
static class TestConfiguration {
@Bean
@@ -100,6 +112,11 @@ public class ClientCacheConfigurerIntegrationTests {
return new TestClientCacheConfigurer();
}
@Bean
ClientCacheConfigurer testClientCacheConfigurerThree() {
return (beanName, bean) -> testClientCacheConfigurerThreeCalled.set(true);
}
@Bean
String nonRelevantBean() {
return "test";

View File

@@ -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,9 +23,11 @@ import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import org.apache.geode.cache.GemFireCache;
import org.junit.After;
import org.junit.Test;
import org.apache.geode.cache.GemFireCache;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -42,6 +43,7 @@ import org.springframework.data.gemfire.mapping.annotation.LocalRegion;
import org.springframework.data.gemfire.mapping.annotation.PartitionRegion;
import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion;
import org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor;
import org.springframework.util.ReflectionUtils;
/**
* Integration tests for {@link RegionConfigurer}.
@@ -52,11 +54,13 @@ import org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor;
* @see org.apache.geode.cache.Region
* @see org.springframework.context.ConfigurableApplicationContext
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
* @see PeerRegionFactoryBean
* @see org.springframework.context.annotation.Bean
* @see org.springframework.data.gemfire.PartitionedRegionFactoryBean
* @see org.springframework.data.gemfire.PeerRegionFactoryBean
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
* @see org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor
* @since 1.1.0
* @since 2.1.0
*/
public class RegionConfigurerIntegrationTests {
@@ -64,34 +68,54 @@ public class RegionConfigurerIntegrationTests {
@After
public void tearDown() {
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
Optional.ofNullable(this.applicationContext)
.ifPresent(ConfigurableApplicationContext::close);
}
/* (non-Javadoc) */
private void assertRegionConfigurerInvocations(TestRegionConfigurer regionConfigurer, String... regionBeanNames) {
assertThat(regionConfigurer).isNotNull();
assertThat(regionConfigurer).contains(regionBeanNames);
assertThat(regionConfigurer).hasSize(regionBeanNames.length);
@SuppressWarnings("unchecked")
private Iterable<String> resolveBeanNames(Object target) {
return Optional.ofNullable(target)
.map(Object::getClass)
.map(type -> ReflectionUtils.findField(type, "beanNames"))
.map(beanNamesField -> {
ReflectionUtils.makeAccessible(beanNamesField);
return beanNamesField;
})
.map(beanNamesField -> (Set<String>) ReflectionUtils.getField(beanNamesField, target))
.orElseGet(() -> Collections.emptySet());
}
/* (non-Javadoc) */
private ConfigurableApplicationContext newApplicationContext(Class<?>... annotatedClasses) {
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(annotatedClasses);
applicationContext.registerShutdownHook();
return applicationContext;
}
private void assertRegionConfigurerInvocations(Iterable<String> actualRegionBeanNames,
String... expectedRegionBeanNames) {
assertThat(actualRegionBeanNames).isNotNull();
assertThat(actualRegionBeanNames).hasSize(expectedRegionBeanNames.length);
assertThat(actualRegionBeanNames).contains(expectedRegionBeanNames);
}
@Test
public void clientRegionConfigurersCalledSuccessfully() {
this.applicationContext = newApplicationContext(ClientTestConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("Test")).isTrue();
assertThat(this.applicationContext.containsBean("Sessions")).isTrue();
assertThat(this.applicationContext.containsBean("GenericRegionEntity")).isTrue();
assertThat(this.applicationContext.containsBean("Test")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerOne")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerTwo")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerThree")).isTrue();
assertRegionConfigurerInvocations(
this.applicationContext.getBean("testRegionConfigurerOne", TestRegionConfigurer.class),
@@ -100,6 +124,10 @@ public class RegionConfigurerIntegrationTests {
assertRegionConfigurerInvocations(
this.applicationContext.getBean("testRegionConfigurerTwo", TestRegionConfigurer.class),
"GenericRegionEntity", "Sessions");
assertRegionConfigurerInvocations(
resolveBeanNames(this.applicationContext.getBean("testRegionConfigurerThree", RegionConfigurer.class)),
"GenericRegionEntity", "Sessions");
}
@Test
@@ -108,11 +136,12 @@ public class RegionConfigurerIntegrationTests {
this.applicationContext = newApplicationContext(PeerTestConfiguration.class);
assertThat(this.applicationContext).isNotNull();
assertThat(this.applicationContext.containsBean("Customers")).isTrue();
assertThat(this.applicationContext.containsBean("GenericRegionEntity")).isTrue();
assertThat(this.applicationContext.containsBean("Test")).isTrue();
assertThat(this.applicationContext.containsBean("GenericRegionEntity")).isTrue();
assertThat(this.applicationContext.containsBean("Customers")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerOne")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerTwo")).isTrue();
assertThat(this.applicationContext.containsBean("testRegionConfigurerThree")).isTrue();
assertRegionConfigurerInvocations(
this.applicationContext.getBean("testRegionConfigurerOne", TestRegionConfigurer.class),
@@ -121,6 +150,10 @@ public class RegionConfigurerIntegrationTests {
assertRegionConfigurerInvocations(
this.applicationContext.getBean("testRegionConfigurerTwo", TestRegionConfigurer.class),
"Customers", "GenericRegionEntity");
assertRegionConfigurerInvocations(
resolveBeanNames(this.applicationContext.getBean("testRegionConfigurerThree", RegionConfigurer.class)),
"Customers", "GenericRegionEntity");
}
@SuppressWarnings("unused")
@@ -141,6 +174,25 @@ public class RegionConfigurerIntegrationTests {
return new TestRegionConfigurer();
}
@Bean
RegionConfigurer testRegionConfigurerThree() {
return new RegionConfigurer() {
private final Set<String> beanNames = new HashSet<>();
@Override
public void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) {
this.beanNames.add(beanName);
}
@Override
public void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) {
this.beanNames.add(beanName);
}
};
}
@Bean
String nonRelevantBean() {
return "test";
@@ -150,14 +202,19 @@ public class RegionConfigurerIntegrationTests {
@ClientCacheApplication
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = { LocalRegion.class, PartitionRegion.class, ReplicateRegion.class }))
classes = { LocalRegion.class, PartitionRegion.class, ReplicateRegion.class
})
)
@SuppressWarnings("unused")
static class ClientTestConfiguration extends AbstractTestConfiguration {
@Bean(name = "Test")
ClientRegionFactoryBean<Object, Object> testRegion(GemFireCache gemfireCache) {
ClientRegionFactoryBean<Object, Object> testRegionFactory = new ClientRegionFactoryBean<>();
testRegionFactory.setCache(gemfireCache);
return testRegionFactory;
}
}
@@ -176,8 +233,11 @@ public class RegionConfigurerIntegrationTests {
@Bean(name = "Test")
PartitionedRegionFactoryBean<Object, Object> testRegion(GemFireCache gemfireCache) {
PartitionedRegionFactoryBean<Object, Object> testRegionFactory = new PartitionedRegionFactoryBean<>();
testRegionFactory.setCache(gemfireCache);
return testRegionFactory;
}
}
@@ -187,12 +247,12 @@ public class RegionConfigurerIntegrationTests {
private final Set<String> beanNames = new HashSet<>();
@Override
public void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) {
public void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) {
this.beanNames.add(beanName);
}
@Override
public void configure(String beanName, ClientRegionFactoryBean<?, ?> bean) {
public void configure(String beanName, PeerRegionFactoryBean<?, ?> bean) {
this.beanNames.add(beanName);
}