SGF-688 - Add support for configuring client and server Region data management policies in Entity-defined Regions.
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.geode.cache.FixedPartitionAttributes;
|
||||
@@ -25,7 +27,7 @@ import org.apache.geode.cache.PartitionResolver;
|
||||
import org.apache.geode.cache.partition.PartitionListener;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.data.gemfire.support.AbstractFactoryBeanSupport;
|
||||
|
||||
/**
|
||||
* Spring {@link FactoryBean} for creating {@link PartitionAttributes}.
|
||||
@@ -35,101 +37,81 @@ import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see org.apache.geode.cache.FixedPartitionAttributes
|
||||
* @see org.apache.geode.cache.PartitionAttributes
|
||||
* @see org.apache.geode.cache.PartitionAttributesFactory
|
||||
* @see org.apache.geode.cache.PartitionResolver
|
||||
* @see org.apache.geode.cache.partition.PartitionListener
|
||||
* @see org.springframework.beans.factory.FactoryBean
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see org.springframework.data.gemfire.support.AbstractFactoryBeanSupport
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
|
||||
public class PartitionAttributesFactoryBean<K, V> implements FactoryBean<PartitionAttributes<K, V>>, InitializingBean {
|
||||
@SuppressWarnings("unused")
|
||||
public class PartitionAttributesFactoryBean<K, V> extends AbstractFactoryBeanSupport<PartitionAttributes<K, V>>
|
||||
implements InitializingBean {
|
||||
|
||||
private List<PartitionListener> partitionListeners;
|
||||
|
||||
private PartitionAttributes<K, V> partitionAttributes;
|
||||
|
||||
private final PartitionAttributesFactory<K, V> partitionAttributesFactory =
|
||||
new PartitionAttributesFactory<>();
|
||||
private final PartitionAttributesFactory<K, V> partitionAttributesFactory = new PartitionAttributesFactory<>();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
for (PartitionListener listener : CollectionUtils.nullSafeList(partitionListeners)) {
|
||||
partitionAttributesFactory.addPartitionListener(listener);
|
||||
}
|
||||
|
||||
nullSafeList(partitionListeners).forEach(partitionAttributesFactory::addPartitionListener);
|
||||
this.partitionAttributes = partitionAttributesFactory.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public PartitionAttributes getObject() throws Exception {
|
||||
public PartitionAttributes<K, V> getObject() throws Exception {
|
||||
return this.partitionAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return (this.partitionAttributes != null ? this.partitionAttributes.getClass() : PartitionAttributes.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setColocatedWith(String collocatedWith) {
|
||||
partitionAttributesFactory.setColocatedWith(collocatedWith);
|
||||
this.partitionAttributesFactory.setColocatedWith(collocatedWith);
|
||||
}
|
||||
|
||||
public void setFixedPartitionAttributes(List<FixedPartitionAttributes> fixedPartitionAttributes) {
|
||||
for (FixedPartitionAttributes fixedPartitionAttributesElement :
|
||||
CollectionUtils.nullSafeList(fixedPartitionAttributes)) {
|
||||
|
||||
partitionAttributesFactory.addFixedPartitionAttributes(fixedPartitionAttributesElement);
|
||||
}
|
||||
nullSafeList(fixedPartitionAttributes).forEach(this.partitionAttributesFactory::addFixedPartitionAttributes);
|
||||
}
|
||||
|
||||
public void setLocalMaxMemory(int mb) {
|
||||
partitionAttributesFactory.setLocalMaxMemory(mb);
|
||||
this.partitionAttributesFactory.setLocalMaxMemory(mb);
|
||||
}
|
||||
|
||||
public void setPartitionListeners(List<PartitionListener> partitionListeners) {
|
||||
this.partitionListeners = partitionListeners;
|
||||
}
|
||||
|
||||
public void setPartitionResolver(PartitionResolver resolver) {
|
||||
partitionAttributesFactory.setPartitionResolver(resolver);
|
||||
public void setPartitionResolver(PartitionResolver<K, V> resolver) {
|
||||
this.partitionAttributesFactory.setPartitionResolver(resolver);
|
||||
}
|
||||
|
||||
public void setRecoveryDelay(long recoveryDelay) {
|
||||
partitionAttributesFactory.setRecoveryDelay(recoveryDelay);
|
||||
this.partitionAttributesFactory.setRecoveryDelay(recoveryDelay);
|
||||
}
|
||||
|
||||
public void setRedundantCopies(int redundantCopies) {
|
||||
partitionAttributesFactory.setRedundantCopies(redundantCopies);
|
||||
this.partitionAttributesFactory.setRedundantCopies(redundantCopies);
|
||||
}
|
||||
|
||||
public void setStartupRecoveryDelay(long startupRecoveryDelay) {
|
||||
partitionAttributesFactory.setStartupRecoveryDelay(startupRecoveryDelay);
|
||||
this.partitionAttributesFactory.setStartupRecoveryDelay(startupRecoveryDelay);
|
||||
}
|
||||
|
||||
public void setTotalMaxMemory(long mb) {
|
||||
partitionAttributesFactory.setTotalMaxMemory(mb);
|
||||
public void setTotalMaxMemory(long megabytes) {
|
||||
this.partitionAttributesFactory.setTotalMaxMemory(megabytes);
|
||||
}
|
||||
|
||||
public void setTotalNumBuckets(int numBuckets) {
|
||||
partitionAttributesFactory.setTotalNumBuckets(numBuckets);
|
||||
this.partitionAttributesFactory.setTotalNumBuckets(numBuckets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,35 +35,23 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
public class RegionAttributesFactoryBean extends AttributesFactory
|
||||
implements FactoryBean<RegionAttributes>, InitializingBean {
|
||||
|
||||
private RegionAttributes attributes;
|
||||
private RegionAttributes regionAttributes;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
attributes = super.create();
|
||||
this.regionAttributes = super.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public RegionAttributes getObject() throws Exception {
|
||||
return attributes;
|
||||
return this.regionAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return (attributes != null ? attributes.getClass() : RegionAttributes.class);
|
||||
return this.regionAttributes != null ? this.regionAttributes.getClass() : RegionAttributes.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
|
||||
@@ -23,7 +23,6 @@ import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIter
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -277,10 +276,11 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
protected RegionFactory<K, V> createRegionFactory(Cache cache) {
|
||||
|
||||
if (this.shortcut != null) {
|
||||
|
||||
RegionFactory<K, V> regionFactory =
|
||||
mergeRegionAttributes(cache.createRegionFactory(this.shortcut), this.attributes);
|
||||
|
||||
setDataPolicy(getDataPolicy(regionFactory));
|
||||
setDataPolicy(getDataPolicy(regionFactory, this.shortcut));
|
||||
|
||||
return regionFactory;
|
||||
}
|
||||
@@ -310,7 +310,7 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
|
||||
Optional.ofNullable(this.cacheWriter).ifPresent(regionFactory::setCacheWriter);
|
||||
|
||||
resolveDataPolicy(regionFactory, persistent, dataPolicy);
|
||||
resolveDataPolicy(regionFactory, this.persistent, this.dataPolicy);
|
||||
|
||||
Optional.ofNullable(this.diskStoreName)
|
||||
.filter(name -> isDiskStoreConfigurationAllowed())
|
||||
@@ -323,7 +323,7 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
|
||||
Optional.ofNullable(this.keyConstraint).ifPresent(regionFactory::setKeyConstraint);
|
||||
|
||||
Optional.ofNullable(this.scope).ifPresent(regionFactory::setScope);
|
||||
Optional.ofNullable(getScope()).ifPresent(regionFactory::setScope);
|
||||
|
||||
Optional.ofNullable(this.valueConstraint).ifPresent(regionFactory::setValueConstraint);
|
||||
|
||||
@@ -375,17 +375,26 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
*/
|
||||
@SuppressWarnings({ "deprecation", "unchecked" })
|
||||
DataPolicy getDataPolicy(RegionFactory regionFactory) {
|
||||
return ((RegionAttributes) getFieldValue(getFieldValue(regionFactory, "attrsFactory",
|
||||
AttributesFactory.class), "regionAttributes", null)).getDataPolicy();
|
||||
DataPolicy getDataPolicy(RegionFactory regionFactory, RegionShortcut regionShortcut) {
|
||||
|
||||
return getFieldValue(regionFactory, "attrsFactory", AttributesFactory.class)
|
||||
.flatMap(attributesFactory -> getFieldValue(attributesFactory,"regionAttributes", null))
|
||||
.map(regionAttributes -> ((RegionAttributes<K, V>) regionAttributes).getDataPolicy())
|
||||
.orElseGet(() -> RegionShortcutToDataPolicyConverter.INSTANCE.convert(regionShortcut));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T getFieldValue(Object source, String fieldName, Class<T> targetType) {
|
||||
Field field = ReflectionUtils.findField(source.getClass(), fieldName, targetType);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return (T) ReflectionUtils.getField(field, source);
|
||||
private <T> Optional<T> getFieldValue(Object source, String fieldName, Class<T> targetType) {
|
||||
|
||||
return Optional.ofNullable(source)
|
||||
.map(Object::getClass)
|
||||
.map(type -> ReflectionUtils.findField(type, fieldName, targetType))
|
||||
.map(field -> {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
return field;
|
||||
})
|
||||
.map(field -> (T) ReflectionUtils.getField(field, source));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,8 +421,8 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
if (regionAttributes != null) {
|
||||
// NOTE this validation may not be strictly required depending on how the RegionAttributes were "created",
|
||||
// but...
|
||||
|
||||
// NOTE: this validation may not be strictly necessary depending on how the RegionAttributes were "created",
|
||||
validateRegionAttributes(regionAttributes);
|
||||
|
||||
regionFactory.setCloningEnabled(regionAttributes.getCloningEnabled());
|
||||
@@ -428,7 +437,7 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
regionFactory.setEntryIdleTimeout(regionAttributes.getEntryIdleTimeout());
|
||||
regionFactory.setEntryTimeToLive(regionAttributes.getEntryTimeToLive());
|
||||
|
||||
// NOTE EvictionAttributes are created by certain RegionShortcuts; need the null check!
|
||||
// NOTE: EvictionAttributes are created by certain RegionShortcuts; need the null check!
|
||||
if (isUserSpecifiedEvictionAttributes(regionAttributes)) {
|
||||
regionFactory.setEvictionAttributes(regionAttributes.getEvictionAttributes());
|
||||
}
|
||||
@@ -464,9 +473,9 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
protected <K, V> void mergePartitionAttributes(RegionFactory<K, V> regionFactory,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
// NOTE PartitionAttributes are created by certain RegionShortcuts; need the null check since RegionAttributes
|
||||
// NOTE: PartitionAttributes are created by certain RegionShortcuts; need the null check since RegionAttributes
|
||||
// can technically return null!
|
||||
// NOTE most likely, the PartitionAttributes will never be null since the PartitionRegionFactoryBean always
|
||||
// NOTE: most likely, the PartitionAttributes will never be null since the PartitionRegionFactoryBean always
|
||||
// sets a PartitionAttributesFactoryBean BeanBuilder on the RegionAttributesFactoryBean "partitionAttributes"
|
||||
// property.
|
||||
if (regionAttributes.getPartitionAttributes() != null) {
|
||||
@@ -582,12 +591,12 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
|
||||
if (resolvedDataPolicy.withPersistence()) {
|
||||
Assert.isTrue(isPersistentUnspecified() || isPersistent(), String.format(
|
||||
"Data Policy [%1$s] is invalid when persistent is false.", resolvedDataPolicy));
|
||||
"Data Policy [%s] is invalid when persistent is false.", resolvedDataPolicy));
|
||||
}
|
||||
else {
|
||||
// NOTE otherwise, the Data Policy is not persistent, so...
|
||||
Assert.isTrue(isPersistentUnspecified() || isNotPersistent(), String.format(
|
||||
"Data Policy [%1$s] is invalid when persistent is true.", resolvedDataPolicy));
|
||||
"Data Policy [%s] is invalid when persistent is true.", resolvedDataPolicy));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,15 +639,17 @@ public abstract class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K,
|
||||
protected void resolveDataPolicy(RegionFactory<K, V> regionFactory, Boolean persistent, String dataPolicy) {
|
||||
|
||||
if (dataPolicy != null) {
|
||||
|
||||
DataPolicy resolvedDataPolicy = new DataPolicyConverter().convert(dataPolicy);
|
||||
|
||||
Assert.notNull(resolvedDataPolicy, String.format("Data Policy [%1$s] is invalid.", dataPolicy));
|
||||
Assert.notNull(resolvedDataPolicy, String.format("Data Policy [%s] is invalid.", dataPolicy));
|
||||
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
|
||||
|
||||
regionFactory.setDataPolicy(resolvedDataPolicy);
|
||||
setDataPolicy(resolvedDataPolicy);
|
||||
}
|
||||
else {
|
||||
|
||||
DataPolicy regionAttributesDataPolicy = getDataPolicy(getAttributes(), DataPolicy.DEFAULT);
|
||||
DataPolicy resolvedDataPolicy = (isPersistent() && DataPolicy.DEFAULT.equals(regionAttributesDataPolicy)
|
||||
? DataPolicy.PERSISTENT_REPLICATE : regionAttributesDataPolicy);
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Spring {@link Converter} to convert a {@link RegionShortcut} into a {@link DataPolicy}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.springframework.core.convert.converter.Converter
|
||||
* @see org.springframework.data.gemfire.RegionShortcutWrapper
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public class RegionShortcutToDataPolicyConverter implements Converter<RegionShortcut, DataPolicy> {
|
||||
|
||||
public static final RegionShortcutToDataPolicyConverter INSTANCE = new RegionShortcutToDataPolicyConverter();
|
||||
|
||||
/**
|
||||
* Converts the given {@link RegionShortcut} into a corresponding {@link DataPolicy}.
|
||||
*
|
||||
* @param regionShortcut {@link RegionShortcut} to convert.
|
||||
* @return a corresponding {@link DataPolicy} for the given {@link RegionShortcut}.
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
*/
|
||||
@Nullable @Override
|
||||
public DataPolicy convert(RegionShortcut regionShortcut) {
|
||||
|
||||
return Optional.ofNullable(RegionShortcutWrapper.valueOf(regionShortcut))
|
||||
.map(RegionShortcutWrapper::getDataPolicy)
|
||||
.orElse(DataPolicy.DEFAULT);
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,11 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public enum RegionShortcutWrapper {
|
||||
|
||||
LOCAL(RegionShortcut.LOCAL, DataPolicy.NORMAL),
|
||||
LOCAL_HEAP_LRU(RegionShortcut.LOCAL_HEAP_LRU, DataPolicy.NORMAL),
|
||||
LOCAL_OVERFLOW(RegionShortcut.LOCAL_OVERFLOW, DataPolicy.NORMAL),
|
||||
LOCAL_PERSISTENT(RegionShortcut.LOCAL_PERSISTENT, DataPolicy.NORMAL),
|
||||
LOCAL_PERSISTENT(RegionShortcut.LOCAL_PERSISTENT, DataPolicy.PERSISTENT_REPLICATE),
|
||||
LOCAL_PERSISTENT_OVERFLOW(RegionShortcut.LOCAL_PERSISTENT_OVERFLOW, DataPolicy.PERSISTENT_REPLICATE),
|
||||
PARTITION(RegionShortcut.PARTITION, DataPolicy.PARTITION),
|
||||
PARTITION_HEAP_LRU(RegionShortcut.PARTITION_HEAP_LRU, DataPolicy.PARTITION),
|
||||
@@ -65,6 +66,7 @@ public enum RegionShortcutWrapper {
|
||||
}
|
||||
|
||||
public static RegionShortcutWrapper valueOf(RegionShortcut regionShortcut) {
|
||||
|
||||
for (RegionShortcutWrapper wrapper : values()) {
|
||||
if (ObjectUtils.nullSafeEquals(wrapper.getRegionShortcut(), regionShortcut)) {
|
||||
return wrapper;
|
||||
|
||||
@@ -278,7 +278,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
else {
|
||||
// NOTE the DataPolicy validation is based on the ClientRegionShortcut initialization logic
|
||||
// in org.apache.geode.internal.cache.GemFireCacheImpl.initializeClientRegionShortcuts
|
||||
throw newIllegalArgumentException("Data Policy [%s] is not valid for the client Region", dataPolicy);
|
||||
throw newIllegalArgumentException("Data Policy [%s] is not valid for a client Region", dataPolicy);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Spring {@link Converter} to convert a {@link ClientRegionShortcut} into a {@link DataPolicy}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.springframework.core.convert.converter.Converter
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionShortcutWrapper
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public class ClientRegionShortcutToDataPolicyConverter implements Converter<ClientRegionShortcut, DataPolicy> {
|
||||
|
||||
public static final ClientRegionShortcutToDataPolicyConverter INSTANCE =
|
||||
new ClientRegionShortcutToDataPolicyConverter();
|
||||
|
||||
/**
|
||||
* Converts the given {@link ClientRegionShortcut} into a corresponding {@link DataPolicy}.
|
||||
*
|
||||
* @param regionShortcut {@link ClientRegionShortcut} to convert.
|
||||
* @return a corresponding {@link DataPolicy} for the given {@link ClientRegionShortcut}.
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
*/
|
||||
@Nullable @Override
|
||||
public DataPolicy convert(ClientRegionShortcut clientRegionShortcut) {
|
||||
|
||||
return Optional.ofNullable(ClientRegionShortcutWrapper.valueOf(clientRegionShortcut))
|
||||
.map(ClientRegionShortcutWrapper::getDataPolicy)
|
||||
.orElse(DataPolicy.DEFAULT);
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ public enum ClientRegionShortcutWrapper {
|
||||
private final DataPolicy dataPolicy;
|
||||
|
||||
public static ClientRegionShortcutWrapper valueOf(ClientRegionShortcut clientRegionShortcut) {
|
||||
|
||||
for (ClientRegionShortcutWrapper wrapper : values()) {
|
||||
if (ObjectUtils.nullSafeEquals(wrapper.getClientRegionShortcut(), clientRegionShortcut)) {
|
||||
return wrapper;
|
||||
|
||||
@@ -65,7 +65,7 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
|
||||
import org.springframework.data.gemfire.config.annotation.support.BeanDefinitionRegistryPostProcessorSupport;
|
||||
import org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -106,7 +106,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableCachingDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.BeanDefinitionRegistryPostProcessorSupport
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean
|
||||
* @see CacheTypeAwareRegionFactoryBean
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@@ -312,7 +312,7 @@ public class CachingDefinedRegionsConfiguration extends AbstractAnnotationConfig
|
||||
if (!registry.containsBeanDefinition(cacheName)) {
|
||||
|
||||
BeanDefinitionBuilder builder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GemFireCacheTypeAwareRegionFactoryBean.class);
|
||||
BeanDefinitionBuilder.genericBeanDefinition(CacheTypeAwareRegionFactoryBean.class);
|
||||
|
||||
builder.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
builder.addPropertyValue("clientRegionShortcut", resolveClientRegionShortcut());
|
||||
@@ -352,8 +352,8 @@ public class CachingDefinedRegionsConfiguration extends AbstractAnnotationConfig
|
||||
if (!beanFactory.containsBean(cacheName)) {
|
||||
try {
|
||||
|
||||
GemFireCacheTypeAwareRegionFactoryBean<?, ?> regionFactoryBean =
|
||||
new GemFireCacheTypeAwareRegionFactoryBean<>();
|
||||
CacheTypeAwareRegionFactoryBean<?, ?> regionFactoryBean =
|
||||
new CacheTypeAwareRegionFactoryBean<>();
|
||||
|
||||
GemFireCache gemfireCache =
|
||||
beanFactory.getBean(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, GemFireCache.class);
|
||||
|
||||
@@ -25,12 +25,15 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
|
||||
/**
|
||||
@@ -39,7 +42,14 @@ import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
* the application persistent entities.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see java.lang.annotation.Documented
|
||||
* @see java.lang.annotation.Inherited
|
||||
* @see java.lang.annotation.Retention
|
||||
* @see java.lang.annotation.Target
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.springframework.context.annotation.ComponentScan
|
||||
* @see org.springframework.context.annotation.ComponentScan.Filter
|
||||
* @see org.springframework.context.annotation.Import
|
||||
@@ -48,7 +58,7 @@ import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.config.annotation.IndexConfiguration
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean
|
||||
* @see CacheTypeAwareRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ClientRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.LocalRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.PartitionRegion
|
||||
@@ -61,6 +71,7 @@ import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
@Inherited
|
||||
@Documented
|
||||
@Import(IndexConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public @interface EnableEntityDefinedRegions {
|
||||
|
||||
/**
|
||||
@@ -120,15 +131,35 @@ public @interface EnableEntityDefinedRegions {
|
||||
ComponentScan.Filter[] includeFilters() default {};
|
||||
|
||||
/**
|
||||
* When this annotation is applied in a cache client application, the {@literal poolName} attribute refers to
|
||||
* the default name of the GemFire/Geode {@link Pool} assigned to the client {@link Region Region(s)}.
|
||||
* When this annotation is applied to a cache client application, the {@literal clientRegionShortcut} attribute
|
||||
* indicates the default data policy applied to client {@link Region Regions} where the persistent entities
|
||||
* are only annotated with the generic {@link org.springframework.data.gemfire.mapping.annotation.Region}
|
||||
* mapping annotation, or the non-data policy specific mapping annotation.
|
||||
*
|
||||
* This value can be overridden by annotating entities with th e{@link ClientRegion} annotation.
|
||||
* Defaults to {@link ClientRegionShortcut#PROXY}.
|
||||
*/
|
||||
ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY;
|
||||
|
||||
/**
|
||||
* When this annotation is applied to a cache client application, the {@literal poolName} attribute refers to
|
||||
* the default name of the GemFire/Geode {@link Pool} assigned to client {@link Region Region(s)}.
|
||||
*
|
||||
* This value can be overridden by annotating entities with the {@link ClientRegion} annotation.
|
||||
*
|
||||
* Defaults to {@literal DEFAULT}.
|
||||
*/
|
||||
String poolName() default ClientRegionFactoryBean.DEFAULT_POOL_NAME;
|
||||
|
||||
/**
|
||||
* When this annotation is applied to a peer cache application, the {@literal serverRegionShortcut} attribute
|
||||
* indicates the default data policy applied to server {@link Region Regions} where the persistent entities
|
||||
* are only annotated with the generic {@link org.springframework.data.gemfire.mapping.annotation.Region}
|
||||
* mapping annotation, or the non-data policy specific mapping annotation.
|
||||
*
|
||||
* Defaults to {@link RegionShortcut#PARTITION}.
|
||||
*/
|
||||
RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION;
|
||||
|
||||
/**
|
||||
* Determines whether the created {@link Region} will have strongly-typed key and value constraints
|
||||
* based on the ID and {@link Class} type of application persistent entity.
|
||||
|
||||
@@ -22,11 +22,10 @@ import static org.springframework.data.gemfire.util.ArrayUtils.defaultIfEmpty;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeMap;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.SpringUtils.safeGetValue;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -36,6 +35,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.Scope;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -55,16 +56,12 @@ import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
import org.springframework.core.type.filter.RegexPatternTypeFilter;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.data.gemfire.FixedPartitionAttributesFactoryBean;
|
||||
import org.springframework.data.gemfire.LocalRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.PartitionAttributesFactoryBean;
|
||||
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionAttributesFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionLookupFactoryBean;
|
||||
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.ScopeType;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
|
||||
import org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.GemFireComponentClassTypeScanner;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
@@ -100,7 +97,7 @@ import org.springframework.util.StringUtils;
|
||||
* @see org.springframework.data.gemfire.RegionAttributesFactoryBean
|
||||
* @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean
|
||||
* @see CacheTypeAwareRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireComponentClassTypeScanner
|
||||
* @see org.springframework.data.gemfire.mapping.GemfireMappingContext
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
@@ -115,21 +112,11 @@ import org.springframework.util.StringUtils;
|
||||
public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigSupport
|
||||
implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
protected static final Class<? extends RegionLookupFactoryBean> DEFAULT_REGION_FACTORY_BEAN_CLASS =
|
||||
GemFireCacheTypeAwareRegionFactoryBean.class;
|
||||
protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = ClientRegionShortcut.PROXY;
|
||||
|
||||
protected static final Map<Class<? extends Annotation>, Class<? extends RegionLookupFactoryBean>> regionAnnotationToRegionFactoryBeanClass =
|
||||
new HashMap<>();
|
||||
|
||||
static {
|
||||
regionAnnotationToRegionFactoryBeanClass.put(ClientRegion.class, ClientRegionFactoryBean.class);
|
||||
regionAnnotationToRegionFactoryBeanClass.put(LocalRegion.class, LocalRegionFactoryBean.class);
|
||||
regionAnnotationToRegionFactoryBeanClass.put(PartitionRegion.class, PartitionedRegionFactoryBean.class);
|
||||
regionAnnotationToRegionFactoryBeanClass.put(ReplicateRegion.class, ReplicatedRegionFactoryBean.class);
|
||||
regionAnnotationToRegionFactoryBeanClass.put(org.springframework.data.gemfire.mapping.annotation.Region.class,
|
||||
DEFAULT_REGION_FACTORY_BEAN_CLASS);
|
||||
}
|
||||
protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = RegionShortcut.PARTITION;
|
||||
|
||||
@Autowired(required = false)
|
||||
private GemfireMappingContext mappingContext;
|
||||
|
||||
@Autowired(required = false)
|
||||
@@ -167,17 +154,17 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
|
||||
AnnotationAttributes enableEntityDefinedRegionsAttributes = getAnnotationAttributes(importingClassMetadata);
|
||||
|
||||
String poolName = enableEntityDefinedRegionsAttributes.getString("poolName");
|
||||
|
||||
boolean strict = enableEntityDefinedRegionsAttributes.getBoolean("strict");
|
||||
|
||||
newGemFireComponentClassTypeScanner(importingClassMetadata, enableEntityDefinedRegionsAttributes).scan()
|
||||
.forEach(persistentEntityClass -> {
|
||||
.forEach(persistentEntityType -> {
|
||||
|
||||
GemfirePersistentEntity persistentEntity = getPersistentEntity(persistentEntityClass);
|
||||
RegionBeanDefinitionMetadata regionMetadata =
|
||||
RegionBeanDefinitionMetadata.with(getPersistentEntity(persistentEntityType))
|
||||
.using(enableEntityDefinedRegionsAttributes);
|
||||
|
||||
registerRegionBeanDefinition(persistentEntity, poolName, strict, registry);
|
||||
postProcess(importingClassMetadata, registry, persistentEntity);
|
||||
registerRegionBeanDefinition(regionMetadata, registry);
|
||||
|
||||
postProcess(importingClassMetadata, registry,
|
||||
regionMetadata.getPersistentEntity().orElse(null));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -329,6 +316,7 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
protected GemfireMappingContext resolveMappingContext() {
|
||||
|
||||
return Optional.ofNullable(this.mappingContext).orElseGet(() -> {
|
||||
|
||||
try {
|
||||
this.mappingContext = getBeanFactory().getBean(GemfireMappingContext.class);
|
||||
}
|
||||
@@ -344,36 +332,24 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
* Registers an individual bean definition in the Spring container for the {@link Region} determined from
|
||||
* the application domain object, {@link GemfirePersistentEntity persistent entity}.
|
||||
*
|
||||
* @param persistentEntity {@link GemfirePersistentEntity} from which to the resolve the {@link Region}.
|
||||
* @param strict boolean value indicating whether the key and value constraints on the {@link Region} should be set.
|
||||
* @param regionMetadata {@link RegionBeanDefinitionMetadata} used to configure the {@link Region} bean definition.
|
||||
* @param registry {@link BeanDefinitionRegistry} used to register the {@link Region} bean definition
|
||||
* in the Spring context.
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
*/
|
||||
protected void registerRegionBeanDefinition(GemfirePersistentEntity persistentEntity, String poolName,
|
||||
boolean strict, BeanDefinitionRegistry registry) {
|
||||
protected void registerRegionBeanDefinition(RegionBeanDefinitionMetadata regionMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
BeanDefinitionBuilder regionFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(resolveRegionFactoryBeanClass(persistentEntity))
|
||||
BeanDefinitionBuilder.genericBeanDefinition(CacheTypeAwareRegionFactoryBean.class)
|
||||
.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME)
|
||||
.addPropertyValue("regionConfigurers", resolveRegionConfigurers())
|
||||
.addPropertyValue("close", false);
|
||||
.addPropertyValue("close", false)
|
||||
.addPropertyValue("regionConfigurers", resolveRegionConfigurers());
|
||||
|
||||
setRegionAttributes(persistentEntity, regionFactoryBeanBuilder, poolName, strict);
|
||||
setRegionAttributes(regionFactoryBeanBuilder, regionMetadata);
|
||||
|
||||
registry.registerBeanDefinition(persistentEntity.getRegionName(),
|
||||
regionFactoryBeanBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<? extends RegionLookupFactoryBean> resolveRegionFactoryBeanClass(
|
||||
GemfirePersistentEntity persistentEntity) {
|
||||
|
||||
return Optional.<Class<? extends RegionLookupFactoryBean>>ofNullable(
|
||||
regionAnnotationToRegionFactoryBeanClass.get(persistentEntity.getRegionAnnotationType()))
|
||||
.orElse(DEFAULT_REGION_FACTORY_BEAN_CLASS);
|
||||
registry.registerBeanDefinition(regionMetadata.getRegionName(), regionFactoryBeanBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -385,34 +361,37 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
Optional.of(getBeanFactory())
|
||||
.filter(beanFactory -> beanFactory instanceof ListableBeanFactory)
|
||||
.map(beanFactory -> {
|
||||
|
||||
Map<String, RegionConfigurer> beansOfType = ((ListableBeanFactory) beanFactory)
|
||||
.getBeansOfType(RegionConfigurer.class, true, true);
|
||||
|
||||
return nullSafeMap(beansOfType).values().stream().collect(Collectors.toList());
|
||||
|
||||
})
|
||||
.orElseGet(Collections::emptyList)
|
||||
);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected BeanDefinitionBuilder setRegionAttributes(GemfirePersistentEntity persistentEntity,
|
||||
BeanDefinitionBuilder regionFactoryBeanBuilder, String poolName, boolean strict) {
|
||||
protected BeanDefinitionBuilder setRegionAttributes(BeanDefinitionBuilder regionFactoryBeanBuilder,
|
||||
RegionBeanDefinitionMetadata regionMetadata) {
|
||||
|
||||
Optional.ofNullable(persistentEntity.getRegionAnnotation()).ifPresent(regionAnnotation -> {
|
||||
Optional.<Annotation>ofNullable(regionMetadata.getRegionAnnotation()).ifPresent(regionAnnotation -> {
|
||||
|
||||
AnnotationAttributes regionAnnotationAttributes = getAnnotationAttributes(regionAnnotation);
|
||||
|
||||
if (strict) {
|
||||
regionFactoryBeanBuilder.addPropertyValue("keyConstraint", resolveIdType(persistentEntity));
|
||||
regionFactoryBeanBuilder.addPropertyValue("valueConstraint", resolveDomainType(persistentEntity));
|
||||
}
|
||||
regionFactoryBeanBuilder.addPropertyValue("clientRegionShortcut",
|
||||
resolveClientRegionShortcut(regionMetadata, regionAnnotation, regionAnnotationAttributes));
|
||||
|
||||
regionFactoryBeanBuilder.addPropertyValue("serverRegionShortcut",
|
||||
resolveServerRegionShortcut(regionMetadata, regionAnnotation, regionAnnotationAttributes));
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("diskStoreName")) {
|
||||
|
||||
String diskStoreName = regionAnnotationAttributes.getString("diskStoreName");
|
||||
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "diskStoreName", diskStoreName,
|
||||
"");
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "diskStoreName",
|
||||
diskStoreName, "");
|
||||
|
||||
if (StringUtils.hasText(diskStoreName)) {
|
||||
regionFactoryBeanBuilder.addDependsOn(diskStoreName);
|
||||
@@ -424,13 +403,19 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
regionAnnotationAttributes.getBoolean("ignoreIfExists"));
|
||||
}
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("persistent")) {
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "persistent",
|
||||
regionAnnotationAttributes.getBoolean("persistent"), false);
|
||||
if (regionMetadata.isStrict()) {
|
||||
regionFactoryBeanBuilder.addPropertyValue("keyConstraint",
|
||||
regionMetadata.getRegionKeyConstraint());
|
||||
|
||||
regionFactoryBeanBuilder.addPropertyValue("valueConstraint",
|
||||
regionMetadata.getRegionValueConstraint());
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder regionAttributesFactoryBeanBuilder =
|
||||
resolveRegionAttributesFactoryBeanBuilder(regionAnnotation, regionFactoryBeanBuilder);
|
||||
BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
|
||||
|
||||
regionFactoryBeanBuilder.addPropertyValue("attributes",
|
||||
regionAttributesFactoryBeanBuilder.getBeanDefinition());
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("diskSynchronous")) {
|
||||
setPropertyValueIfNotDefault(regionAttributesFactoryBeanBuilder, "diskSynchronous",
|
||||
@@ -442,85 +427,70 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
regionAnnotationAttributes.getBoolean("ignoreJta"), false);
|
||||
}
|
||||
|
||||
setClientRegionAttributes(regionAnnotationAttributes, poolName, regionFactoryBeanBuilder);
|
||||
setClientRegionAttributes(regionMetadata, regionAnnotationAttributes, regionFactoryBeanBuilder);
|
||||
|
||||
setPartitionRegionAttributes(regionAnnotationAttributes, regionFactoryBeanBuilder,
|
||||
setPartitionRegionAttributes(regionMetadata, regionAnnotationAttributes, regionFactoryBeanBuilder,
|
||||
regionAttributesFactoryBeanBuilder);
|
||||
|
||||
setReplicateRegionAttributes(regionAnnotationAttributes, regionFactoryBeanBuilder);
|
||||
setReplicateRegionAttributes(regionMetadata, regionAnnotationAttributes, regionFactoryBeanBuilder);
|
||||
});
|
||||
|
||||
return regionFactoryBeanBuilder;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Class<?> resolveDomainType(GemfirePersistentEntity persistentEntity) {
|
||||
return persistentEntity.getType();
|
||||
protected ClientRegionShortcut resolveClientRegionShortcut(RegionBeanDefinitionMetadata regionMetadata,
|
||||
Annotation regionAnnotation, AnnotationAttributes regionAnnotationAttributes) {
|
||||
|
||||
return ClientRegion.class.equals(regionAnnotation.annotationType())
|
||||
? regionAnnotationAttributes.getEnum("shortcut")
|
||||
: regionMetadata.resolveClientRegionShortcut(DEFAULT_CLIENT_REGION_SHORTCUT);
|
||||
}
|
||||
|
||||
protected RegionShortcut resolveServerRegionShortcut(RegionBeanDefinitionMetadata regionMetadata,
|
||||
Annotation regionAnnotation, AnnotationAttributes regionAnnotationAttributes) {
|
||||
|
||||
Class<? extends Annotation> regionAnnotationType = regionAnnotation.annotationType();
|
||||
|
||||
boolean persistent = (regionAnnotationAttributes.containsKey("persistent")
|
||||
&& regionAnnotationAttributes.getBoolean("persistent"));
|
||||
|
||||
return LocalRegion.class.equals(regionAnnotationType)
|
||||
? (persistent ? RegionShortcut.LOCAL_PERSISTENT : RegionShortcut.LOCAL)
|
||||
: PartitionRegion.class.equals(regionAnnotationType)
|
||||
? (persistent ? RegionShortcut.PARTITION_PERSISTENT : RegionShortcut.PARTITION)
|
||||
: ReplicateRegion.class.equals(regionAnnotationType)
|
||||
? (persistent ? RegionShortcut.REPLICATE_PERSISTENT : RegionShortcut.REPLICATE)
|
||||
: regionMetadata.resolveServerRegionShortcut(DEFAULT_SERVER_REGION_SHORTCUT);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<?> resolveIdType(GemfirePersistentEntity persistentEntity) {
|
||||
protected BeanDefinitionBuilder setClientRegionAttributes(RegionBeanDefinitionMetadata regionMetadata,
|
||||
AnnotationAttributes regionAnnotationAttributes, BeanDefinitionBuilder regionFactoryBeanBuilder) {
|
||||
|
||||
return Optional.ofNullable(persistentEntity.getIdProperty())
|
||||
.map(idProperty -> ((GemfirePersistentProperty) idProperty).getActualType())
|
||||
.orElse((Class) Object.class);
|
||||
}
|
||||
String resolvedPoolName = regionAnnotationAttributes.containsKey("poolName")
|
||||
? regionAnnotationAttributes.getString("poolName")
|
||||
: regionMetadata.getPoolName().orElse(ClientRegionFactoryBean.DEFAULT_POOL_NAME);
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected BeanDefinitionBuilder resolveRegionAttributesFactoryBeanBuilder(Annotation regionAnnotation,
|
||||
BeanDefinitionBuilder regionFactoryBeanBuilder) {
|
||||
|
||||
BeanDefinitionBuilder regionAttributesFactoryBeanBuilder = regionFactoryBeanBuilder;
|
||||
|
||||
if (!ClientRegion.class.isAssignableFrom(regionAnnotation.annotationType())) {
|
||||
regionAttributesFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class);
|
||||
|
||||
regionFactoryBeanBuilder.addPropertyValue("attributes",
|
||||
regionAttributesFactoryBeanBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
return regionAttributesFactoryBeanBuilder;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected BeanDefinitionBuilder setClientRegionAttributes(AnnotationAttributes regionAnnotationAttributes,
|
||||
String poolName, BeanDefinitionBuilder regionFactoryBeanBuilder) {
|
||||
|
||||
if (isPoolNameConfigured(regionAnnotationAttributes, poolName)) {
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "poolName",
|
||||
regionAnnotationAttributes.getString("poolName"), null);
|
||||
}
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("shortcut")) {
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "shortcut",
|
||||
regionAnnotationAttributes.getEnum("shortcut"), ClientRegionShortcut.PROXY);
|
||||
}
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "poolName",
|
||||
resolvedPoolName, ClientRegionFactoryBean.DEFAULT_POOL_NAME);
|
||||
|
||||
return regionFactoryBeanBuilder;
|
||||
}
|
||||
|
||||
private boolean isPoolNameConfigured(AnnotationAttributes regionAnnotationAttributes, String poolName) {
|
||||
return (regionAnnotationAttributes.containsKey("poolName")
|
||||
|| !ClientRegionFactoryBean.DEFAULT_POOL_NAME.equals(poolName));
|
||||
}
|
||||
|
||||
private String resolvePoolName(AnnotationAttributes regionAnnotationAttributes, String poolName) {
|
||||
return safeGetValue(() -> regionAnnotationAttributes.getString("poolName"), poolName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected BeanDefinitionBuilder setPartitionRegionAttributes(AnnotationAttributes regionAnnotationAttributes,
|
||||
BeanDefinitionBuilder regionFactoryBeanBuilder, BeanDefinitionBuilder regionAttributesFactoryBeanBuilder) {
|
||||
protected BeanDefinitionBuilder setPartitionRegionAttributes(RegionBeanDefinitionMetadata regionMetadata,
|
||||
AnnotationAttributes regionAnnotationAttributes, BeanDefinitionBuilder regionFactoryBeanBuilder,
|
||||
BeanDefinitionBuilder regionAttributesFactoryBeanBuilder) {
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("redundantCopies")) {
|
||||
|
||||
BeanDefinitionBuilder partitionAttributesFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(PartitionAttributesFactoryBean.class);
|
||||
|
||||
String collocatedWith = regionAnnotationAttributes.getString("collocatedWith");
|
||||
|
||||
setPropertyValueIfNotDefault(partitionAttributesFactoryBeanBuilder, "colocatedWith", collocatedWith, "");
|
||||
setPropertyValueIfNotDefault(partitionAttributesFactoryBeanBuilder, "colocatedWith",
|
||||
collocatedWith, "");
|
||||
|
||||
if (StringUtils.hasText(collocatedWith)) {
|
||||
regionFactoryBeanBuilder.addDependsOn(collocatedWith);
|
||||
@@ -554,10 +524,12 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
new ManagedList<BeanDefinition>(fixedPartitions.length);
|
||||
|
||||
for (PartitionRegion.FixedPartition fixedPartition : fixedPartitions) {
|
||||
|
||||
BeanDefinitionBuilder fixedPartitionAttributesFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(FixedPartitionAttributesFactoryBean.class);
|
||||
|
||||
fixedPartitionAttributesFactoryBeanBuilder.addPropertyValue("partitionName", fixedPartition.name());
|
||||
fixedPartitionAttributesFactoryBeanBuilder.addPropertyValue("partitionName",
|
||||
fixedPartition.name());
|
||||
|
||||
setPropertyValueIfNotDefault(fixedPartitionAttributesFactoryBeanBuilder, "primary",
|
||||
fixedPartition.primary(), false);
|
||||
@@ -565,25 +537,25 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
setPropertyValueIfNotDefault(fixedPartitionAttributesFactoryBeanBuilder, "numBuckets",
|
||||
fixedPartition.numBuckets(), 1);
|
||||
|
||||
fixedPartitionAttributesFactoryBeans.add(
|
||||
fixedPartitionAttributesFactoryBeanBuilder.getBeanDefinition());
|
||||
fixedPartitionAttributesFactoryBeans
|
||||
.add(fixedPartitionAttributesFactoryBeanBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
partitionAttributesFactoryBeanBuilder.addPropertyValue("fixedPartitionAttributes",
|
||||
fixedPartitionAttributesFactoryBeans);
|
||||
partitionAttributesFactoryBeanBuilder
|
||||
.addPropertyValue("fixedPartitionAttributes", fixedPartitionAttributesFactoryBeans);
|
||||
}
|
||||
|
||||
return partitionAttributesFactoryBeanBuilder;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected BeanDefinitionBuilder setReplicateRegionAttributes(AnnotationAttributes regionAnnotationAttributes,
|
||||
BeanDefinitionBuilder regionFactoryBeanBuilder) {
|
||||
protected BeanDefinitionBuilder setReplicateRegionAttributes(RegionBeanDefinitionMetadata regionMetadata,
|
||||
AnnotationAttributes regionAnnotationAttributes, BeanDefinitionBuilder regionFactoryBeanBuilder) {
|
||||
|
||||
if (regionAnnotationAttributes.containsKey("scope")) {
|
||||
setPropertyValueIfNotDefault(regionFactoryBeanBuilder, "scope",
|
||||
regionAnnotationAttributes.<ScopeType>getEnum("scope").getScope(),
|
||||
ScopeType.DISTRIBUTED_NO_ACK);
|
||||
Scope.DISTRIBUTED_NO_ACK);
|
||||
}
|
||||
|
||||
return regionFactoryBeanBuilder;
|
||||
@@ -624,4 +596,125 @@ public class EntityDefinedRegionsConfiguration extends AbstractAnnotationConfigS
|
||||
|
||||
return persistentEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link RegionBeanDefinitionMetadata} class encapsulates details for creating a {@link Region}
|
||||
* from application persistent entities. The details are captured during a persistent entity component scan.
|
||||
*
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
*/
|
||||
protected static class RegionBeanDefinitionMetadata {
|
||||
|
||||
/**
|
||||
* Factory method used to construct a new instance of the {@link RegionBeanDefinitionMetadata}.
|
||||
*
|
||||
* @return a new instance of {@link RegionBeanDefinitionMetadata}.
|
||||
*/
|
||||
protected static RegionBeanDefinitionMetadata with(GemfirePersistentEntity<?> persistentEntity) {
|
||||
return new RegionBeanDefinitionMetadata(persistentEntity);
|
||||
}
|
||||
|
||||
private boolean strict;
|
||||
|
||||
private ClientRegionShortcut clientRegionShortcut;
|
||||
|
||||
private GemfirePersistentEntity<?> persistentEntity;
|
||||
|
||||
private RegionShortcut serverRegionShortcut;
|
||||
|
||||
private String poolName;
|
||||
|
||||
protected RegionBeanDefinitionMetadata(GemfirePersistentEntity<?> persistentEntity) {
|
||||
this.persistentEntity = Optional.ofNullable(persistentEntity)
|
||||
.orElseThrow(() -> newIllegalArgumentException("GemfirePeristentEntity is required"));
|
||||
}
|
||||
|
||||
protected boolean isStrict() {
|
||||
return this.strict;
|
||||
}
|
||||
|
||||
protected Optional<ClientRegionShortcut> getClientRegionShortcut() {
|
||||
return Optional.ofNullable(this.clientRegionShortcut);
|
||||
}
|
||||
|
||||
protected ClientRegionShortcut resolveClientRegionShortcut(ClientRegionShortcut defaultClientRegionShortcut) {
|
||||
return getClientRegionShortcut().orElse(defaultClientRegionShortcut);
|
||||
}
|
||||
|
||||
protected Optional<GemfirePersistentEntity<?>> getPersistentEntity() {
|
||||
return Optional.ofNullable(this.persistentEntity);
|
||||
}
|
||||
|
||||
protected GemfirePersistentEntity<?> resolvePersistentEntity() {
|
||||
return getPersistentEntity().orElseThrow(() ->
|
||||
newIllegalStateException("GemfirePersistentEntity could not be resolved"));
|
||||
}
|
||||
|
||||
protected Optional<String> getPoolName() {
|
||||
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
protected <T extends Annotation> T getRegionAnnotation() {
|
||||
return resolvePersistentEntity().getRegionAnnotation();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<?> getRegionKeyConstraint() {
|
||||
|
||||
return Optional.ofNullable(resolvePersistentEntity().getIdProperty())
|
||||
.map(idProperty -> ((GemfirePersistentProperty) idProperty).getActualType())
|
||||
.orElse((Class) Object.class);
|
||||
}
|
||||
|
||||
protected String getRegionName() {
|
||||
return resolvePersistentEntity().getRegionName();
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
protected Class<?> getRegionValueConstraint() {
|
||||
|
||||
return Optional.ofNullable(resolvePersistentEntity().getType())
|
||||
.orElse((Class) Object.class);
|
||||
}
|
||||
|
||||
protected Optional<RegionShortcut> getServerRegionShortcut() {
|
||||
return Optional.ofNullable(this.serverRegionShortcut);
|
||||
}
|
||||
|
||||
protected RegionShortcut resolveServerRegionShortcut(RegionShortcut defaultServerRegionShortcut) {
|
||||
return getServerRegionShortcut().orElse(defaultServerRegionShortcut);
|
||||
}
|
||||
|
||||
protected RegionBeanDefinitionMetadata is(boolean strict) {
|
||||
this.strict = strict;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected RegionBeanDefinitionMetadata using(AnnotationAttributes enableEntityDefinedRegionsAttributes) {
|
||||
|
||||
return Optional.ofNullable(enableEntityDefinedRegionsAttributes)
|
||||
.map(it ->
|
||||
this.using(it.<ClientRegionShortcut>getEnum("clientRegionShortcut"))
|
||||
.using(it.getString("poolName"))
|
||||
.using(it.<RegionShortcut>getEnum("serverRegionShortcut"))
|
||||
.is(it.getBoolean("strict"))
|
||||
)
|
||||
.orElse(this);
|
||||
}
|
||||
|
||||
protected RegionBeanDefinitionMetadata using(ClientRegionShortcut clientRegionShortcut) {
|
||||
this.clientRegionShortcut = clientRegionShortcut;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected RegionBeanDefinitionMetadata using(RegionShortcut serverRegionShortcut) {
|
||||
this.serverRegionShortcut = serverRegionShortcut;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected RegionBeanDefinitionMetadata using(String poolName) {
|
||||
this.poolName = poolName;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.apache.geode.cache.Region;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.gemfire.RegionFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.support.CacheTypeAwareRegionFactoryBean;
|
||||
|
||||
/**
|
||||
* The {@link RegionConfigurer} interface defines a contract for implementations to customize the configuration
|
||||
@@ -31,7 +32,7 @@ import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
* @see org.springframework.data.gemfire.RegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireCacheTypeAwareRegionFactoryBean
|
||||
* @see CacheTypeAwareRegionFactoryBean
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface RegionConfigurer {
|
||||
|
||||
@@ -24,38 +24,55 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.Scope;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.GenericRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.LocalRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionLookupFactoryBean;
|
||||
import org.springframework.data.gemfire.RegionShortcutWrapper;
|
||||
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.config.annotation.RegionConfigurer;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* The {@link GemFireCacheTypeAwareRegionFactoryBean} class is a smart Spring {@link FactoryBean} that knows how to
|
||||
* create a client or server {@link Region} depending on whether the {@link GemFireCache} is
|
||||
* a {@link org.apache.geode.cache.client.ClientCache} or a peer {@link org.apache.geode.cache.Cache}.
|
||||
* The {@link CacheTypeAwareRegionFactoryBean} class is a smart Spring {@link FactoryBean} that knows how to
|
||||
* create a client or server {@link Region} depending on whether the {@link GemFireCache} is a {@link ClientCache}
|
||||
* or a peer {@link Cache}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.Cache
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.RegionAttributes
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.apache.geode.cache.Scope
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.RegionLookupFactoryBean
|
||||
* @see org.springframework.data.gemfire.LocalRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.PartitionedRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.RegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.RegionLookupFactoryBean
|
||||
* @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.RegionConfigurer
|
||||
* @since 1.9.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> {
|
||||
public class CacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> {
|
||||
|
||||
private GemFireCache gemfireCache;
|
||||
|
||||
@@ -74,6 +91,9 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
|
||||
private RegionShortcut serverRegionShortcut;
|
||||
|
||||
private Scope scope;
|
||||
|
||||
private String diskStoreName;
|
||||
private String poolName;
|
||||
private String regionName;
|
||||
|
||||
@@ -88,7 +108,7 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new client {@link Region} using the {@link ClientRegionFactoryBean}.
|
||||
* Constructs, configures and initialize\s a new client {@link Region} using the {@link ClientRegionFactoryBean}.
|
||||
*
|
||||
* @param gemfireCache reference to the {@link GemFireCache} used to create/initialize the factory
|
||||
* used to create the client {@link Region}.
|
||||
@@ -98,22 +118,25 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see #newClientRegionFactoryBean()
|
||||
*/
|
||||
protected Region<K, V> newClientRegion(GemFireCache gemfireCache, String regionName) throws Exception {
|
||||
|
||||
ClientRegionFactoryBean<K, V> clientRegionFactory = new ClientRegionFactoryBean<>();
|
||||
ClientRegionFactoryBean<K, V> clientRegionFactory = newClientRegionFactoryBean();
|
||||
|
||||
clientRegionFactory.setAttributes(getRegionAttributes());
|
||||
clientRegionFactory.setBeanFactory(getBeanFactory());
|
||||
clientRegionFactory.setCache(gemfireCache);
|
||||
clientRegionFactory.setClose(isClose());
|
||||
clientRegionFactory.setDiskStoreName(getDiskStoreName());
|
||||
clientRegionFactory.setKeyConstraint(getKeyConstraint());
|
||||
clientRegionFactory.setLookupEnabled(getLookupEnabled());
|
||||
clientRegionFactory.setRegionConfigurers(this.regionConfigurers);
|
||||
clientRegionFactory.setRegionName(regionName);
|
||||
clientRegionFactory.setShortcut(getClientRegionShortcut());
|
||||
clientRegionFactory.setValueConstraint(getValueConstraint());
|
||||
|
||||
resolvePoolName().ifPresent(clientRegionFactory::setPoolName);
|
||||
getPoolName().ifPresent(clientRegionFactory::setPoolName);
|
||||
|
||||
clientRegionFactory.afterPropertiesSet();
|
||||
|
||||
@@ -121,7 +144,20 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new server {@link Region} using the {@link GenericRegionFactoryBean}.
|
||||
* Constructs a new instance of the {@link ClientRegionFactoryBean}.
|
||||
*
|
||||
* @param <K> {@link Class type} of the created {@link Region Region's} key.
|
||||
* @param <V> {@link Class type} of the created {@link Region Region's} value.
|
||||
* @return a new instance of the {@link ClientRegionFactoryBean}.
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionFactoryBean
|
||||
*/
|
||||
protected <K, V> ClientRegionFactoryBean<K, V> newClientRegionFactoryBean() {
|
||||
return new ClientRegionFactoryBean<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs, configures and initializes a new server {@link Region} using a sub-class
|
||||
* of {@link RegionFactoryBean}.
|
||||
*
|
||||
* @param gemfireCache reference to the {@link GemFireCache} used to create/initialize the factory
|
||||
* used to create the server {@link Region}.
|
||||
@@ -131,17 +167,20 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
* @see org.springframework.data.gemfire.GenericRegionFactoryBean
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see #newRegionFactoryBean()
|
||||
*/
|
||||
protected Region<K, V> newServerRegion(GemFireCache gemfireCache, String regionName) throws Exception {
|
||||
|
||||
GenericRegionFactoryBean<K, V> serverRegionFactory = new GenericRegionFactoryBean<>();
|
||||
RegionFactoryBean<K, V> serverRegionFactory = newRegionFactoryBean();
|
||||
|
||||
serverRegionFactory.setAttributes(getRegionAttributes());
|
||||
serverRegionFactory.setBeanFactory(getBeanFactory());
|
||||
serverRegionFactory.setCache(gemfireCache);
|
||||
serverRegionFactory.setClose(isClose());
|
||||
serverRegionFactory.setDataPolicy(getDataPolicy());
|
||||
serverRegionFactory.setDiskStoreName(getDiskStoreName());
|
||||
serverRegionFactory.setKeyConstraint(getKeyConstraint());
|
||||
serverRegionFactory.setLookupEnabled(getLookupEnabled());
|
||||
serverRegionFactory.setRegionConfigurers(this.regionConfigurers);
|
||||
serverRegionFactory.setRegionName(regionName);
|
||||
serverRegionFactory.setShortcut(getServerRegionShortcut());
|
||||
@@ -152,6 +191,39 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
return serverRegionFactory.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link Class sub-type} of the {@link RegionFactoryBean} class based on
|
||||
* the {@link #getServerRegionShortcut()} and {@link #getDataPolicy()}.
|
||||
*
|
||||
* @return a new instance of the {@link RegionFactoryBean}.
|
||||
* @see org.springframework.data.gemfire.LocalRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.PartitionedRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean
|
||||
* @see org.springframework.data.gemfire.RegionFactoryBean
|
||||
*/
|
||||
protected RegionFactoryBean<K, V> newRegionFactoryBean() {
|
||||
|
||||
RegionShortcutWrapper regionShortcutWrapper = RegionShortcutWrapper.valueOf(getServerRegionShortcut());
|
||||
|
||||
DataPolicy resolvedDataPolicy = Optional.of(regionShortcutWrapper)
|
||||
.map(RegionShortcutWrapper::getDataPolicy)
|
||||
.orElseGet(this::getDataPolicy);
|
||||
|
||||
if (regionShortcutWrapper.isLocal()) {
|
||||
return new LocalRegionFactoryBean<>();
|
||||
}
|
||||
else if (resolvedDataPolicy.withPartitioning()) {
|
||||
return new PartitionedRegionFactoryBean<>();
|
||||
}
|
||||
else if (resolvedDataPolicy.withReplication()) {
|
||||
ReplicatedRegionFactoryBean<K, V> replicatedRegionFactoryBean = new ReplicatedRegionFactoryBean<>();
|
||||
replicatedRegionFactoryBean.setScope(getScope());
|
||||
return replicatedRegionFactoryBean;
|
||||
}
|
||||
|
||||
return new GenericRegionFactoryBean<>();
|
||||
}
|
||||
|
||||
public void setAttributes(RegionAttributes<K, V> regionAttributes) {
|
||||
this.regionAttributes = regionAttributes;
|
||||
}
|
||||
@@ -188,6 +260,14 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
return Optional.ofNullable(this.dataPolicy).orElse(DataPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
public void setDiskStoreName(String diskStoreName) {
|
||||
this.diskStoreName = diskStoreName;
|
||||
}
|
||||
|
||||
protected String getDiskStoreName() {
|
||||
return this.diskStoreName;
|
||||
}
|
||||
|
||||
public void setKeyConstraint(Class<K> keyConstraint) {
|
||||
this.keyConstraint = keyConstraint;
|
||||
}
|
||||
@@ -200,17 +280,12 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
protected String getPoolName() {
|
||||
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText)
|
||||
.orElse(ClientRegionFactoryBean.GEMFIRE_POOL_NAME);
|
||||
protected Optional<String> getPoolName() {
|
||||
return Optional.ofNullable(this.poolName).filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
protected Optional<String> resolvePoolName() {
|
||||
return Optional.of(getPoolName()).filter(this::isPoolResolvable);
|
||||
}
|
||||
|
||||
private boolean isPoolResolvable(String poolName) {
|
||||
return (getBeanFactory().containsBean(poolName) || (PoolManager.find(poolName) != null));
|
||||
protected String resolvePoolName() {
|
||||
return getPoolName().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,6 +313,14 @@ public class GemFireCacheTypeAwareRegionFactoryBean<K, V> extends RegionLookupFa
|
||||
this.regionConfigurers = Optional.ofNullable(regionConfigurers).orElseGet(Collections::emptyList);
|
||||
}
|
||||
|
||||
public void setScope(Scope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
protected Scope getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
public void setServerRegionShortcut(RegionShortcut shortcut) {
|
||||
this.serverRegionShortcut = shortcut;
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.springframework.data.gemfire.util.SpringUtils.defaultIfEmpty;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -30,6 +28,7 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link PersistentEntity} implementation adding custom GemFire persistent entity related metadata, such as the
|
||||
@@ -50,9 +49,11 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static Annotation resolveRegionAnnotation(Class<?> persistentEntityType) {
|
||||
|
||||
for (Class<? extends Annotation> regionAnnotationType : Region.REGION_ANNOTATION_TYPES) {
|
||||
Annotation regionAnnotation = AnnotatedElementUtils.getMergedAnnotation(
|
||||
persistentEntityType, regionAnnotationType);
|
||||
|
||||
Annotation regionAnnotation =
|
||||
AnnotatedElementUtils.getMergedAnnotation(persistentEntityType, regionAnnotationType);
|
||||
|
||||
if (regionAnnotation != null) {
|
||||
return regionAnnotation;
|
||||
@@ -64,11 +65,11 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static String resolveRegionName(Class<?> persistentEntityType, Annotation regionAnnotation) {
|
||||
String regionName = Optional.ofNullable(regionAnnotation)
|
||||
.map((annotation) -> getAnnotationAttributeStringValue(annotation, "value"))
|
||||
.orElse(null);
|
||||
|
||||
return defaultIfEmpty(regionName, persistentEntityType.getSimpleName());
|
||||
Optional<String> regionName = Optional.ofNullable(regionAnnotation)
|
||||
.map((annotation) -> getAnnotationAttributeStringValue(annotation, "value"));
|
||||
|
||||
return regionName.filter(StringUtils::hasText).orElse(persistentEntityType.getSimpleName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -86,6 +87,7 @@ public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, Gemfire
|
||||
* @see org.springframework.data.util.TypeInformation
|
||||
*/
|
||||
public GemfirePersistentEntity(TypeInformation<T> information) {
|
||||
|
||||
super(information);
|
||||
|
||||
Class<T> rawType = information.getType();
|
||||
|
||||
@@ -182,6 +182,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testAssertDataPolicyAndPersistentAttributesAreCompatible() {
|
||||
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
|
||||
factoryBean.setPersistent(null);
|
||||
@@ -199,6 +200,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAssertNonPersistentDataPolicyWithPersistentAttribute() {
|
||||
|
||||
try {
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
factoryBean.setPersistent(true);
|
||||
@@ -212,6 +214,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAssertPersistentDataPolicyWithNonPersistentAttribute() {
|
||||
|
||||
try {
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
factoryBean.setPersistent(false);
|
||||
@@ -226,6 +229,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testIsPersistent() {
|
||||
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
|
||||
assertFalse(factoryBean.isPersistent());
|
||||
@@ -241,6 +245,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testIsPersistentUnspecified() {
|
||||
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
|
||||
assertTrue(factoryBean.isPersistentUnspecified());
|
||||
@@ -260,6 +265,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testIsNotPersistent() {
|
||||
|
||||
RegionFactoryBean<?, ?> factoryBean = new TestRegionFactoryBean<>();
|
||||
|
||||
assertFalse(factoryBean.isNotPersistent());
|
||||
@@ -275,20 +281,22 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testCreateRegionFactoryWithShortcut() {
|
||||
|
||||
Cache mockCache = mock(Cache.class);
|
||||
|
||||
RegionAttributes mockRegionAttributes = mock(RegionAttributes.class);
|
||||
|
||||
final RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
when(mockCache.createRegionFactory(eq(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW)))
|
||||
.thenReturn(mockRegionFactory);
|
||||
|
||||
final AtomicBoolean setDataPolicyCalled = new AtomicBoolean(false);
|
||||
AtomicBoolean setDataPolicyCalled = new AtomicBoolean(false);
|
||||
|
||||
RegionFactoryBean factoryBean = new RegionFactoryBean() {
|
||||
|
||||
@Override
|
||||
DataPolicy getDataPolicy(final RegionFactory regionFactory) {
|
||||
DataPolicy getDataPolicy(RegionFactory regionFactory, RegionShortcut regionShortcut) {
|
||||
return DataPolicy.PERSISTENT_PARTITION;
|
||||
}
|
||||
|
||||
@@ -316,6 +324,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testCreateRegionFactoryWithAttributes() {
|
||||
|
||||
Cache mockCache = mock(Cache.class);
|
||||
|
||||
RegionAttributes mockRegionAttributes = mock(RegionAttributes.class);
|
||||
@@ -335,7 +344,9 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testCreateRegionFactory() {
|
||||
|
||||
Cache mockCache = mock(Cache.class);
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
when(mockCache.createRegionFactory()).thenReturn(mockRegionFactory);
|
||||
@@ -739,29 +750,39 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndDataPolicyUnspecified() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, (String) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.DEFAULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndDataPolicyUnspecified() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, (String) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.DEFAULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentAndDataPolicyUnspecified() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(true);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, true, (String) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWithBlankDataPolicyName() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -781,6 +802,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWithEmptyDataPolicyName() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -800,6 +822,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWithInvalidDataPolicyName() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -819,21 +842,28 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndNormalDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, "NORMAL");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.NORMAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndPreloadedDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, "PRELOADED");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PRELOADED));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenPersistentAndEmptyDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -854,20 +884,27 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, "PARTITION");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndPersistentPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, "PERSISTENT_PARTITION");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenNotPersistentAndPersistentPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -888,6 +925,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenPersistentAndPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -911,54 +949,70 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, "PARTITION");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PARTITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentAndPersistentPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(true);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, true, "PERSISTENT_PARTITION");
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndRegionAttributesPreloadedDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes(DataPolicy.PRELOADED));
|
||||
factoryBean.setDataPolicy((DataPolicy) null);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, (String) null);
|
||||
|
||||
verify(mockRegionFactory, times(1)).setDataPolicy(eq(DataPolicy.PRELOADED));
|
||||
assertEquals(DataPolicy.PRELOADED, factoryBean.getDataPolicy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndRegionAttributesPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes(DataPolicy.PARTITION));
|
||||
factoryBean.setDataPolicy((DataPolicy) null);
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, (String) null);
|
||||
|
||||
verify(mockRegionFactory, times(1)).setDataPolicy(eq(DataPolicy.PARTITION));
|
||||
assertEquals(DataPolicy.PARTITION, factoryBean.getDataPolicy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentAndRegionAttributesPersistentPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes(DataPolicy.PERSISTENT_PARTITION));
|
||||
factoryBean.setDataPolicy((DataPolicy) null);
|
||||
factoryBean.setPersistent(true);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, true, (String) null);
|
||||
|
||||
verify(mockRegionFactory, times(1)).setDataPolicy(eq(DataPolicy.PERSISTENT_PARTITION));
|
||||
assertEquals(DataPolicy.PERSISTENT_PARTITION, factoryBean.getDataPolicy());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenNotPersistentAndRegionAttributesPersistentPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -980,6 +1034,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenPersistentAndRegionAttributesPartitionDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -1001,47 +1056,63 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndUnspecifiedDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes());
|
||||
factoryBean.setPersistent(null);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, (DataPolicy) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.DEFAULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndUnspecifiedDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes());
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, (DataPolicy) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.DEFAULT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentAndUnspecifiedDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setAttributes(createMockRegionAttributes());
|
||||
factoryBean.setPersistent(true);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, true, (DataPolicy) null);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, DataPolicy.REPLICATE);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentUnspecifiedAndPersistentReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, null, DataPolicy.PERSISTENT_REPLICATE);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenNotPersistentAndPersistentReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -1063,6 +1134,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveDataPolicyWhenPersistentAndReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
try {
|
||||
@@ -1084,17 +1156,23 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTests {
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenNotPersistentAndReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(false);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, false, DataPolicy.REPLICATE);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.REPLICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveDataPolicyWhenPersistentAndPersistentReplicateDataPolicy() {
|
||||
|
||||
RegionFactory mockRegionFactory = createMockRegionFactory();
|
||||
|
||||
factoryBean.setPersistent(true);
|
||||
factoryBean.resolveDataPolicy(mockRegionFactory, true, DataPolicy.PERSISTENT_REPLICATE);
|
||||
|
||||
verify(mockRegionFactory).setDataPolicy(eq(DataPolicy.PERSISTENT_REPLICATE));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RegionShortcutToDataPolicyConverter}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.springframework.data.gemfire.RegionShortcutToDataPolicyConverter
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public class RegionShortcutToDataPolicyConverterUnitTests {
|
||||
|
||||
protected void assertDataPolicy(DataPolicy actual, DataPolicy expected) {
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyDefault(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyEmpty(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.EMPTY);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyNormal(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.NORMAL);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyPersistentPartition(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.PERSISTENT_PARTITION);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyPersistentReplicate(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.PERSISTENT_REPLICATE);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyPartition(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.PARTITION);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyReplicate(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.REPLICATE);
|
||||
}
|
||||
|
||||
protected DataPolicy convert(RegionShortcut regionShortcut) {
|
||||
return RegionShortcutToDataPolicyConverter.INSTANCE.convert(regionShortcut);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullRegionShortcutIsDataPolicyDefault() {
|
||||
assertDataPolicyDefault(convert(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutLocalIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(RegionShortcut.LOCAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutLocalHeapLruIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(RegionShortcut.LOCAL_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutLocalOverflowIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(RegionShortcut.LOCAL_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutLocalPersistentIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(RegionShortcut.LOCAL_PERSISTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutLocalPersistentOverflowIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(RegionShortcut.LOCAL_PERSISTENT_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionHeapLruIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionOverflowIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionPersistentIsDataPolicyPersistentPartition() {
|
||||
assertDataPolicyPersistentPartition(convert(RegionShortcut.PARTITION_PERSISTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionPersistentOverflowIsDataPolicyPersistentPartition() {
|
||||
assertDataPolicyPersistentPartition(convert(RegionShortcut.PARTITION_PERSISTENT_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionProxyIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_PROXY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionProxyRedundantIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_PROXY_REDUNDANT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionRedundantIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_REDUNDANT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionRedundantHeapLruIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_REDUNDANT_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionRedundantOverflowIsDataPolicyPartition() {
|
||||
assertDataPolicyPartition(convert(RegionShortcut.PARTITION_REDUNDANT_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionRedundantPersistentIsDataPolicyPartition() {
|
||||
assertDataPolicyPersistentPartition(convert(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutPartitionRedundantPersistentOverflowIsDataPolicyPartition() {
|
||||
assertDataPolicyPersistentPartition(convert(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicateIsDataPolicyReplicate() {
|
||||
assertDataPolicyReplicate(convert(RegionShortcut.REPLICATE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicateHeapLruIsDataPolicyReplicate() {
|
||||
assertDataPolicyReplicate(convert(RegionShortcut.REPLICATE_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicateOverflowIsDataPolicyReplicate() {
|
||||
assertDataPolicyReplicate(convert(RegionShortcut.REPLICATE_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicatePersistentIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(RegionShortcut.REPLICATE_PERSISTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicatePersistentOverflowIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regionShortcutReplicateProxyIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyEmpty(convert(RegionShortcut.REPLICATE_PROXY));
|
||||
}
|
||||
}
|
||||
@@ -587,7 +587,7 @@ public class ClientRegionFactoryBeanTest {
|
||||
}
|
||||
|
||||
protected <K> Interest<K> newInterest(K key) {
|
||||
return new Interest<K>(key);
|
||||
return new Interest<>(key);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ClientRegionShortcutToDataPolicyConverter}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.springframework.data.gemfire.client.ClientRegionShortcutToDataPolicyConverter
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public class ClientRegionShortcutToDataPolicyConverterUnitTests {
|
||||
|
||||
protected void assertDataPolicy(DataPolicy actual, DataPolicy expected) {
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyDefault(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyEmpty(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.EMPTY);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyNormal(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.NORMAL);
|
||||
}
|
||||
|
||||
protected void assertDataPolicyPersistentReplicate(DataPolicy actual) {
|
||||
assertDataPolicy(actual, DataPolicy.PERSISTENT_REPLICATE);
|
||||
}
|
||||
|
||||
protected DataPolicy convert(ClientRegionShortcut clientRegionShortcut) {
|
||||
return ClientRegionShortcutToDataPolicyConverter.INSTANCE.convert(clientRegionShortcut);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutCachingProxyIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.CACHING_PROXY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutCachingProxyHeapLruIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutCachingProxyOverflowIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.CACHING_PROXY_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.LOCAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalHeapLruIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.LOCAL_HEAP_LRU));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalOverflowIsDataPolicyNormal() {
|
||||
assertDataPolicyNormal(convert(ClientRegionShortcut.LOCAL_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalPersistentIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(ClientRegionShortcut.LOCAL_PERSISTENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalPersistentOverflowIsDataPolicyPersistentReplicate() {
|
||||
assertDataPolicyPersistentReplicate(convert(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientRegionShortcutLocalProxyIsDataPolicyEmpty() {
|
||||
assertDataPolicyEmpty(convert(ClientRegionShortcut.PROXY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullClientRegionShortcutIsDataPolicyDefault() {
|
||||
assertDataPolicyDefault(convert(null));
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class CacheServerPropertiesIntegrationTests {
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext newApplicationContext(PropertySource<?> testPropertySource,
|
||||
Class<?>... annotatedClasses) {
|
||||
Class<?>... annotatedClasses) {
|
||||
|
||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
|
||||
|
||||
@@ -17,24 +17,17 @@
|
||||
|
||||
package org.springframework.data.gemfire.config.annotation;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.length;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeList;
|
||||
import static org.springframework.data.gemfire.util.RegionUtils.toRegionPath;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.DiskStore;
|
||||
import org.apache.geode.cache.FixedPartitionAttributes;
|
||||
@@ -44,25 +37,21 @@ import org.apache.geode.cache.PartitionResolver;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.RegionExistsException;
|
||||
import org.apache.geode.cache.RegionFactory;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.Scope;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientRegionFactory;
|
||||
import org.apache.geode.cache.client.ClientRegionShortcut;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.gemfire.PartitionedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.client.ClientRegionShortcutWrapper;
|
||||
import org.springframework.data.gemfire.config.annotation.test.entities.ClientRegionEntity;
|
||||
import org.springframework.data.gemfire.config.annotation.test.entities.CollocatedPartitionRegionEntity;
|
||||
import org.springframework.data.gemfire.config.annotation.test.entities.GenericRegionEntity;
|
||||
@@ -74,6 +63,8 @@ import org.springframework.data.gemfire.mapping.annotation.ClientRegion;
|
||||
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.mock.MockObjectsSupport;
|
||||
import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMockObjects;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link EnableEntityDefinedRegions} annotation and {@link EntityDefinedRegionsConfiguration} class.
|
||||
@@ -81,43 +72,51 @@ import org.springframework.data.gemfire.mapping.annotation.ReplicateRegion;
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.data.gemfire.config.annotation.EnableEntityDefinedRegions
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ClientRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.LocalRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.PartitionRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ReplicateRegion
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.ReplicateRegion
|
||||
* @see org.springframework.data.gemfire.test.mock.MockObjectsSupport
|
||||
* @see org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMockObjects
|
||||
* @since 1.9.0
|
||||
*/
|
||||
public class EnableEntityDefinedRegionsUnitTests {
|
||||
|
||||
private static final AtomicInteger MOCK_ID = new AtomicInteger(0);
|
||||
|
||||
private static final Set<Region<?, ?>> cacheRegions = new HashSet<>();
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
Optional.ofNullable(this.applicationContext).ifPresent(ConfigurableApplicationContext::close);
|
||||
cacheRegions.clear();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertRegion(Region<?, ?> region, String name) {
|
||||
protected <K, V> void assertRegion(Region<K, V> region, String name) {
|
||||
assertRegion(region, name, toRegionPath(name), null, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected <K, V> void assertRegion(Region<?, ?> region, String name,
|
||||
protected <K, V> void assertRegion(Region<K, V> region, String name,
|
||||
Class<K> keyConstraint, Class<V> valueConstraint) {
|
||||
|
||||
assertRegion(region, name, toRegionPath(name), keyConstraint, valueConstraint);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertRegion(Region<?, ?> region, String name, String fullPath) {
|
||||
@SuppressWarnings("unused")
|
||||
protected <K, V> void assertRegion(Region<K, V> region, String name, String fullPath) {
|
||||
assertRegion(region, name, fullPath, null, null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected <K, V> void assertRegion(Region<?, ?> region, String name, String fullPath,
|
||||
protected <K, V> void assertRegion(Region<K, V> region, String name, String fullPath,
|
||||
Class<K> keyConstraint, Class<V> valueConstraint) {
|
||||
|
||||
assertThat(region).isNotNull();
|
||||
@@ -129,7 +128,17 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertRegionAttributes(RegionAttributes<?, ?> regionAttributes, DataPolicy dataPolicy,
|
||||
protected <K, V> void assertRegionWithAttributes(Region<K, V> region, String name, DataPolicy dataPolicy,
|
||||
String diskStoreName, Boolean diskSynchronous, Boolean ignoreJta, String poolName, Scope scope) {
|
||||
|
||||
assertRegion(region, name);
|
||||
assertThat(region.getAttributes()).isNotNull();
|
||||
assertRegionAttributes(region.getAttributes(), dataPolicy, diskStoreName, diskSynchronous, ignoreJta,
|
||||
poolName, scope);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected <K, V> void assertRegionAttributes(RegionAttributes<K, V> regionAttributes, DataPolicy dataPolicy,
|
||||
String diskStoreName, Boolean diskSynchronous, Boolean ignoreJta, String poolName, Scope scope) {
|
||||
|
||||
assertThat(regionAttributes).isNotNull();
|
||||
@@ -142,7 +151,7 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected void assertPartitionAttributes(PartitionAttributes<?, ?> partitionAttributes,
|
||||
protected <K, V> void assertPartitionAttributes(PartitionAttributes<K, V> partitionAttributes,
|
||||
String collocatedWith, PartitionResolver partitionResolver, Integer redundantCopies) {
|
||||
|
||||
assertThat(partitionAttributes).isNotNull();
|
||||
@@ -161,6 +170,14 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
assertThat(fixedPartitionAttributes.getNumBuckets()).isEqualTo(numBuckets);
|
||||
}
|
||||
|
||||
protected void assertUndefinedRegions(String... regionBeanNames) {
|
||||
|
||||
stream(nullSafeArray(regionBeanNames, String.class)).forEach(regionBeanName ->
|
||||
assertThat(this.applicationContext.containsBean(regionBeanName)).isFalse());
|
||||
|
||||
assertThat(this.applicationContext.getBeansOfType(Region.class)).hasSize(11 - length(regionBeanNames));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected FixedPartitionAttributes findFixedPartitionAttributes(PartitionAttributes partitionAttributes,
|
||||
@@ -191,40 +208,102 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityClientRegionsDefined() {
|
||||
|
||||
applicationContext = newApplicationContext(ClientPersistentEntitiesConfiguration.class);
|
||||
this.applicationContext = newApplicationContext(ClientPersistentEntitiesConfiguration.class);
|
||||
|
||||
Region<String, ClientRegionEntity> sessions = applicationContext.getBean("Sessions", Region.class);
|
||||
Region<String, ClientRegionEntity> sessions = this.applicationContext.getBean("Sessions", Region.class);
|
||||
|
||||
assertRegion(sessions, "Sessions", String.class, ClientRegionEntity.class);
|
||||
assertRegionAttributes(sessions.getAttributes(), DataPolicy.NORMAL, null, true,
|
||||
false, null, null);
|
||||
assertRegionAttributes(sessions.getAttributes(), DataPolicy.NORMAL,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<Long, GenericRegionEntity> genericRegionEntity =
|
||||
applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
assertRegion(genericRegionEntity, "GenericRegionEntity", Long.class, GenericRegionEntity.class);
|
||||
assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.EMPTY, null,
|
||||
true, false, null, null);
|
||||
assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.EMPTY,
|
||||
null, true, false, null, null);
|
||||
|
||||
assertThat(applicationContext.containsBean("CollocatedPartitionRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("ContactEvents")).isFalse();
|
||||
assertThat(applicationContext.containsBean("NonEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("Accounts")).isFalse();
|
||||
assertThat(applicationContext.containsBean("Customers")).isFalse();
|
||||
assertThat(applicationContext.containsBean("LocalRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("PartitionRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("ReplicateRegionEntity")).isFalse();
|
||||
assertUndefinedRegions("ClientRegionEntity", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "LocalRegionEntity", "NonEntity", "PartitionRegionEntity", "Customers",
|
||||
"ReplicateRegionEntity", "Accounts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityClientRegionsDefinedWithCustomConfiguration() {
|
||||
|
||||
this.applicationContext = newApplicationContext(ClientPersistentEntitiesWithCustomConfiguration.class);
|
||||
|
||||
Region<Object, Object> sessions = this.applicationContext.getBean("Sessions", Region.class);
|
||||
|
||||
assertRegionWithAttributes(sessions, "Sessions", DataPolicy.NORMAL,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<Object, Object> genericRegionEntity =
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
assertRegionWithAttributes(genericRegionEntity, "GenericRegionEntity", DataPolicy.NORMAL,
|
||||
null, true, false, "TestPool", null);
|
||||
|
||||
assertUndefinedRegions("ClientRegionEntity", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "LocalRegionEntity", "NonEntity", "PartitionRegionEntity", "Customers",
|
||||
"ReplicateRegionEntity", "Accounts");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityClientRegionsDefinedWithServerRegionMappingAnnotations() {
|
||||
|
||||
this.applicationContext =
|
||||
newApplicationContext(ClientPersistentEntitiesWithServerRegionMappingAnnotationsConfiguration.class);
|
||||
|
||||
Region<String, ClientRegionEntity> sessions = this.applicationContext.getBean("Sessions", Region.class);
|
||||
|
||||
assertRegion(sessions, "Sessions", String.class, ClientRegionEntity.class);
|
||||
assertRegionAttributes(sessions.getAttributes(), DataPolicy.NORMAL,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<Long, GenericRegionEntity> genericRegionEntity =
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
assertRegion(genericRegionEntity, "GenericRegionEntity", Long.class, GenericRegionEntity.class);
|
||||
assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.EMPTY,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<String, LocalRegionEntity> localRegionEntity =
|
||||
this.applicationContext.getBean("LocalRegionEntity", Region.class);
|
||||
|
||||
assertRegion(localRegionEntity, "LocalRegionEntity", String.class, LocalRegionEntity.class);
|
||||
assertRegionAttributes(localRegionEntity.getAttributes(), DataPolicy.EMPTY,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<Long, PartitionRegionEntity> customers =
|
||||
this.applicationContext.getBean("Customers", Region.class);
|
||||
|
||||
assertRegion(customers, "Customers", Long.class, PartitionRegionEntity.class);
|
||||
assertRegionAttributes(customers.getAttributes(), DataPolicy.EMPTY,
|
||||
null, true, false, null, null);
|
||||
|
||||
Region<Object, ReplicateRegionEntity> accounts =
|
||||
this.applicationContext.getBean("Accounts", Region.class);
|
||||
|
||||
assertRegion(accounts, "Accounts", Object.class, ReplicateRegionEntity.class);
|
||||
assertRegionAttributes(accounts.getAttributes(), DataPolicy.EMPTY,
|
||||
null, true, false, null, null);
|
||||
|
||||
assertUndefinedRegions("ClientRegionEntity", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "NonEntity", "PartitionRegionEntity", "ReplicateRegionEntity");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityPeerPartitionRegionsDefined() {
|
||||
applicationContext = newApplicationContext(PeerPartitionRegionPersistentEntitiesConfiguration.class);
|
||||
|
||||
Region<Object, Object> customers = applicationContext.getBean("Customers", Region.class);
|
||||
this.applicationContext = newApplicationContext(PeerPartitionRegionPersistentEntitiesConfiguration.class);
|
||||
|
||||
assertRegion(customers, "Customers");
|
||||
assertRegionAttributes(customers.getAttributes(), DataPolicy.PERSISTENT_PARTITION, null,
|
||||
Region<Object, Object> customers = this.applicationContext.getBean("Customers", Region.class);
|
||||
|
||||
assertRegionWithAttributes(customers, "Customers", DataPolicy.PERSISTENT_PARTITION, null,
|
||||
true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
assertPartitionAttributes(customers.getAttributes().getPartitionAttributes(), null,
|
||||
null, 1);
|
||||
@@ -233,30 +312,26 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
assertFixedPartitionAttributes(findFixedPartitionAttributes(customers.getAttributes().getPartitionAttributes(),
|
||||
"two"), "two", false, 21);
|
||||
|
||||
Region<Object, Object> contactEvents = applicationContext.getBean("ContactEvents", Region.class);
|
||||
Region<Object, Object> contactEvents = this.applicationContext.getBean("ContactEvents", Region.class);
|
||||
|
||||
assertRegion(contactEvents, "ContactEvents");
|
||||
assertRegionAttributes(contactEvents.getAttributes(), DataPolicy.PERSISTENT_PARTITION,
|
||||
assertRegionWithAttributes(contactEvents, "ContactEvents", DataPolicy.PERSISTENT_PARTITION,
|
||||
"mockDiskStore", false, true, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
assertPartitionAttributes(contactEvents.getAttributes().getPartitionAttributes(), "Customers",
|
||||
applicationContext.getBean("mockPartitionResolver", PartitionResolver.class), 2);
|
||||
this.applicationContext.getBean("mockPartitionResolver", PartitionResolver.class), 2);
|
||||
|
||||
assertThat(applicationContext.getBean("mockDiskStore")).isInstanceOf(DiskStore.class);
|
||||
assertThat(applicationContext.containsBean("ClientRegion")).isFalse();
|
||||
assertThat(applicationContext.containsBean("NonEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("Accounts")).isFalse();
|
||||
assertThat(applicationContext.containsBean("LocalRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("PartitionRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("ReplicateRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("Sessions")).isFalse();
|
||||
assertUndefinedRegions("ClientRegionEntity", "Sessions", "CollocatedPartitionRegionEntity",
|
||||
"GenericRegionEntity", "LocalRegionEntity", "NonEntity", "PartitionRegionEntity", "ReplicateRegionEntity",
|
||||
"Accounts");
|
||||
}
|
||||
|
||||
@Test(expected = RegionExistsException.class)
|
||||
public void entityPeerPartitionRegionAlreadyDefinedThrowsRegionExistsException() {
|
||||
public void entityPartitionRegionAlreadyDefinedThrowsRegionExistsException() {
|
||||
|
||||
try {
|
||||
applicationContext = newApplicationContext(ExistingPartitionRegionPersistentEntitiesConfiguration.class);
|
||||
this.applicationContext = newApplicationContext(ExistingPartitionRegionPersistentEntitiesConfiguration.class);
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
|
||||
assertThat(expected).hasCauseInstanceOf(RegionExistsException.class);
|
||||
assertThat(expected.getCause()).hasMessage("/Customers");
|
||||
|
||||
@@ -267,331 +342,209 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityReplicateRegionAlreadyDefinedIgnoresEntityDefinedRegionDefinition() {
|
||||
applicationContext = newApplicationContext(ExistingReplicateRegionPersistentEntitiesConfiguration.class);
|
||||
|
||||
Region<Object, Object> accounts = applicationContext.getBean("Accounts", Region.class);
|
||||
this.applicationContext = newApplicationContext(ExistingReplicateRegionPersistentEntitiesConfiguration.class);
|
||||
|
||||
assertRegion(accounts, "Accounts");
|
||||
assertRegionAttributes(accounts.getAttributes(), DataPolicy.REPLICATE, null, true,
|
||||
false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
Region<Object, Object> accounts = this.applicationContext.getBean("Accounts", Region.class);
|
||||
|
||||
assertRegionWithAttributes(accounts, "Accounts", DataPolicy.REPLICATE,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void entityServerRegionsDefined() {
|
||||
applicationContext = newApplicationContext(ServerPersistentEntitiesConfiguration.class);
|
||||
|
||||
Region<Object, Object> accounts = applicationContext.getBean("Accounts", Region.class);
|
||||
this.applicationContext = newApplicationContext(ServerPersistentEntitiesConfiguration.class);
|
||||
|
||||
assertRegion(accounts, "Accounts");
|
||||
assertRegionAttributes(accounts.getAttributes(), DataPolicy.REPLICATE, null, true,
|
||||
false, null, Scope.DISTRIBUTED_ACK);
|
||||
Region<Object, Object> accounts = this.applicationContext.getBean("Accounts", Region.class);
|
||||
|
||||
Region<Object, Object> customers = applicationContext.getBean("Customers", Region.class);
|
||||
assertRegionWithAttributes(accounts, "Accounts", DataPolicy.REPLICATE,
|
||||
null, true, false, null, Scope.DISTRIBUTED_ACK);
|
||||
|
||||
assertRegion(customers, "Customers");
|
||||
assertRegionAttributes(customers.getAttributes(), DataPolicy.PERSISTENT_PARTITION,
|
||||
Region<Object, Object> customers = this.applicationContext.getBean("Customers", Region.class);
|
||||
|
||||
assertRegionWithAttributes(customers, "Customers", DataPolicy.PERSISTENT_PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
assertPartitionAttributes(customers.getAttributes().getPartitionAttributes(), null,
|
||||
null, 1);
|
||||
|
||||
Region<Object, Object> localRegionEntity = applicationContext.getBean("LocalRegionEntity", Region.class);
|
||||
Region<Object, Object> localRegionEntity = this.applicationContext.getBean("LocalRegionEntity", Region.class);
|
||||
|
||||
assertRegion(localRegionEntity, "LocalRegionEntity");
|
||||
assertRegionAttributes(localRegionEntity.getAttributes(), DataPolicy.NORMAL,
|
||||
assertRegionWithAttributes(localRegionEntity, "LocalRegionEntity", DataPolicy.NORMAL,
|
||||
null, true, false, null, Scope.LOCAL);
|
||||
|
||||
Region<Object, Object> genericRegionEntity =
|
||||
applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
assertRegion(genericRegionEntity, "GenericRegionEntity");
|
||||
assertRegionAttributes(genericRegionEntity.getAttributes(), DataPolicy.NORMAL,
|
||||
assertRegionWithAttributes(genericRegionEntity, "GenericRegionEntity", DataPolicy.PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
assertThat(applicationContext.containsBean("CollocatedPartitionRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("ContactEvents")).isFalse();
|
||||
assertThat(applicationContext.containsBean("NonEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("PartitionRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("ReplicateRegionEntity")).isFalse();
|
||||
assertThat(applicationContext.containsBean("Sessions")).isFalse();
|
||||
assertUndefinedRegions("ClientRegionEntity", "Sessions", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "NonEntity", "PartitionRegionEntity", "ReplicateRegionEntity");
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static String mockName(String baseMockName) {
|
||||
return String.format("%s%d", baseMockName, MOCK_ID.incrementAndGet());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static <K, V> Cache mockCache() {
|
||||
Cache mockCache = mock(Cache.class);
|
||||
|
||||
Answer<RegionFactory<K, V>> createRegionFactory = invocation -> {
|
||||
RegionAttributes<K, V> defaultRegionAttributes = mockRegionAttributes(null,
|
||||
null, true, false, null, null,
|
||||
null, Scope.DISTRIBUTED_NO_ACK, null);
|
||||
|
||||
RegionAttributes<K, V> regionAttributes = (invocation.getArguments().length == 1
|
||||
? invocation.getArgument(0) : defaultRegionAttributes);
|
||||
|
||||
return mockRegionFactory(mockCache, regionAttributes);
|
||||
};
|
||||
|
||||
when(mockCache.createRegionFactory()).thenAnswer(createRegionFactory);
|
||||
when(mockCache.createRegionFactory(any(RegionAttributes.class))).thenAnswer(createRegionFactory);
|
||||
|
||||
return mockCache;
|
||||
}
|
||||
|
||||
protected static <K, V> ClientCache mockClientCache() {
|
||||
|
||||
ClientCache mockClientCache = mock(ClientCache.class, mockName("ClientCache"));
|
||||
|
||||
Answer<ClientRegionFactory<K, V>> createClientRegionFactory =
|
||||
invocation -> mockClientRegionFactory(invocation.getArgument(0));
|
||||
|
||||
when(mockClientCache.createClientRegionFactory(any(ClientRegionShortcut.class)))
|
||||
.thenAnswer(createClientRegionFactory);
|
||||
|
||||
return mockClientCache;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <K, V> ClientRegionFactory<K, V> mockClientRegionFactory(ClientRegionShortcut shortcut) {
|
||||
ClientRegionFactory<K, V> mockClientRegionFactory =
|
||||
mock(ClientRegionFactory.class, mockName("MockClientRegionFactory"));
|
||||
public void entityServerRegionsDefinedWithCustomConfiguration() {
|
||||
|
||||
AtomicReference<String> diskStoreName = new AtomicReference<>();
|
||||
AtomicReference<Boolean> diskSynchronous = new AtomicReference<>(true);
|
||||
AtomicReference<Class> keyConstraint = new AtomicReference<>(null);
|
||||
AtomicReference<String> poolName = new AtomicReference<>();
|
||||
AtomicReference<Class> valueConstraint = new AtomicReference<>(null);
|
||||
this.applicationContext = newApplicationContext(ServerPersistentEntitiesWithCustomConfiguration.class);
|
||||
|
||||
when(mockClientRegionFactory.setDiskStoreName(anyString())).thenAnswer(
|
||||
newSetter(String.class, diskStoreName, mockClientRegionFactory));
|
||||
Region<Object, Object> accounts = this.applicationContext.getBean("Sessions", Region.class);
|
||||
|
||||
when(mockClientRegionFactory.setDiskSynchronous(anyBoolean())).thenAnswer(
|
||||
newSetter(Boolean.TYPE, diskSynchronous, mockClientRegionFactory));
|
||||
assertRegionWithAttributes(accounts, "Sessions", DataPolicy.REPLICATE,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
when(mockClientRegionFactory.setKeyConstraint(any(Class.class))).thenAnswer(
|
||||
newSetter(Class.class, keyConstraint, mockClientRegionFactory));
|
||||
Region<Object, Object> genericRegionEntity =
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
when(mockClientRegionFactory.setPoolName(anyString())).thenAnswer(
|
||||
newSetter(String.class, poolName, mockClientRegionFactory));
|
||||
assertRegionWithAttributes(genericRegionEntity, "GenericRegionEntity", DataPolicy.REPLICATE,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
when(mockClientRegionFactory.setValueConstraint(any(Class.class))).thenAnswer(
|
||||
newSetter(Class.class, valueConstraint, mockClientRegionFactory));
|
||||
Region<Object, Object> localRegionEntity =
|
||||
this.applicationContext.getBean("LocalRegionEntity", Region.class);
|
||||
|
||||
RegionAttributes<K, V> mockRegionAttributes =
|
||||
mock(RegionAttributes.class, mockName("MockClientRegionAttributes"));
|
||||
assertRegionWithAttributes(localRegionEntity, "LocalRegionEntity", DataPolicy.NORMAL,
|
||||
null, true, false, null, Scope.LOCAL);
|
||||
|
||||
when(mockRegionAttributes.getDataPolicy()).thenReturn(
|
||||
ClientRegionShortcutWrapper.valueOf(shortcut).getDataPolicy());
|
||||
when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(diskStoreName));
|
||||
when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous));
|
||||
when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(keyConstraint));
|
||||
when(mockRegionAttributes.getPoolName()).thenAnswer(newGetter(poolName));
|
||||
when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(valueConstraint));
|
||||
Region<Object, Object> customers = this.applicationContext.getBean("Customers", Region.class);
|
||||
|
||||
when(mockClientRegionFactory.create(anyString())).thenAnswer(invocation -> {
|
||||
String regionName = invocation.getArgument(0);
|
||||
assertRegionWithAttributes(customers, "Customers", DataPolicy.PERSISTENT_PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
cacheRegions.stream().filter(region -> region.getName().equals(regionName)).findAny()
|
||||
.ifPresent(region -> { throw new RegionExistsException(region); });
|
||||
|
||||
Region<K, V> region = mockRegion(regionName, mockRegionAttributes);
|
||||
|
||||
cacheRegions.add(region);
|
||||
|
||||
return region;
|
||||
});
|
||||
|
||||
return mockClientRegionFactory;
|
||||
assertUndefinedRegions("ClientRegionEntity", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "NonEntity", "PartitionRegionEntity", "ReplicateRegionEntity", "Accounts");
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <K, V> RegionAttributes<K, V> mockRegionAttributes(DataPolicy dataPolicy,
|
||||
String diskStoreName, boolean diskSynchronous, boolean ignoreJta, Class<K> keyConstraint,
|
||||
PartitionAttributes<K, V> partitionAttributes, String poolName, Scope scope, Class<V> valueConstraint) {
|
||||
public void entityServerRegionsDefinedWithClientRegionMappingAnnotations() {
|
||||
|
||||
RegionAttributes<K, V> mockRegionAttributes =
|
||||
mock(RegionAttributes.class, mockName("MockRegionAttributes"));
|
||||
this.applicationContext =
|
||||
newApplicationContext(ServerPersistentEntitiesWithClientRegionMappingAnnotationsConfiguration.class);
|
||||
|
||||
when(mockRegionAttributes.getDataPolicy()).thenReturn(dataPolicy);
|
||||
when(mockRegionAttributes.getDiskStoreName()).thenReturn(diskStoreName);
|
||||
when(mockRegionAttributes.isDiskSynchronous()).thenReturn(diskSynchronous);
|
||||
when(mockRegionAttributes.getIgnoreJTA()).thenReturn(ignoreJta);
|
||||
when(mockRegionAttributes.getKeyConstraint()).thenReturn(keyConstraint);
|
||||
when(mockRegionAttributes.getPartitionAttributes()).thenReturn(partitionAttributes);
|
||||
when(mockRegionAttributes.getPoolName()).thenReturn(poolName);
|
||||
when(mockRegionAttributes.getScope()).thenReturn(scope);
|
||||
when(mockRegionAttributes.getValueConstraint()).thenReturn(valueConstraint);
|
||||
Region<Object, Object> sessions = this.applicationContext.getBean("Sessions", Region.class);
|
||||
|
||||
return mockRegionAttributes;
|
||||
assertRegionWithAttributes(sessions, "Sessions", DataPolicy.PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
Region<Object, Object> genericRegionEntity =
|
||||
this.applicationContext.getBean("GenericRegionEntity", Region.class);
|
||||
|
||||
assertRegionWithAttributes(genericRegionEntity, "GenericRegionEntity", DataPolicy.PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
Region<Object, Object> customers =
|
||||
this.applicationContext.getBean("Customers", Region.class);
|
||||
|
||||
assertRegionWithAttributes(customers, "Customers", DataPolicy.PERSISTENT_PARTITION,
|
||||
null, true, false, null, Scope.DISTRIBUTED_NO_ACK);
|
||||
|
||||
assertUndefinedRegions("ClientRegionEntity", "CollocatedPartitionRegionEntity",
|
||||
"ContactEvents", "LocalRegionEntity", "NonEntity", "PartitionRegionEntity", "ReplicateRegionEntity",
|
||||
"Accounts");
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <K, V> RegionFactory<K, V> mockRegionFactory(GemFireCache mockCache,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
RegionFactory<K, V> mockRegionFactory = mock(RegionFactory.class, mockName("MockRegionFactory"));
|
||||
|
||||
AtomicReference<DataPolicy> dataPolicy = new AtomicReference<>(regionAttributes.getDataPolicy());
|
||||
AtomicReference<String> diskStoreName = new AtomicReference<>(regionAttributes.getDiskStoreName());
|
||||
AtomicReference<Boolean> diskSynchronous = new AtomicReference<>(regionAttributes.isDiskSynchronous());
|
||||
AtomicReference<Boolean> ignoreJta = new AtomicReference<>(regionAttributes.getIgnoreJTA());
|
||||
AtomicReference<Class> keyConstraint = new AtomicReference<>(null);
|
||||
AtomicReference<PartitionAttributes> partitionAttributes =
|
||||
new AtomicReference<>(regionAttributes.getPartitionAttributes());
|
||||
AtomicReference<Scope> scope = new AtomicReference<>(regionAttributes.getScope());
|
||||
AtomicReference<Class> valueConstraint = new AtomicReference<>(null);
|
||||
|
||||
when(mockRegionFactory.setDataPolicy(any(DataPolicy.class))).thenAnswer(
|
||||
newSetter(DataPolicy.class, dataPolicy, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setDiskStoreName(anyString())).thenAnswer(
|
||||
newSetter(String.class, diskStoreName, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setDiskSynchronous(anyBoolean())).thenAnswer(
|
||||
newSetter(Boolean.TYPE, diskSynchronous, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setIgnoreJTA(anyBoolean())).thenAnswer(
|
||||
newSetter(Boolean.TYPE, ignoreJta, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setKeyConstraint(any(Class.class))).thenAnswer(
|
||||
newSetter(Class.class, keyConstraint, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setPartitionAttributes(any(PartitionAttributes.class))).thenAnswer(
|
||||
newSetter(PartitionAttributes.class, partitionAttributes, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setScope(any(Scope.class))).thenAnswer(
|
||||
newSetter(Scope.class, scope, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setValueConstraint(any(Class.class))).thenAnswer(
|
||||
newSetter(Class.class, valueConstraint, mockRegionFactory));
|
||||
|
||||
RegionAttributes<K, V> mockRegionAttributes =
|
||||
mock(RegionAttributes.class, mockName("MockRegionAttributes"));
|
||||
|
||||
when(mockRegionAttributes.getDataPolicy()).thenAnswer(newGetter(dataPolicy));
|
||||
when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(diskStoreName));
|
||||
when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous));
|
||||
when(mockRegionAttributes.getIgnoreJTA()).thenAnswer(newGetter(ignoreJta));
|
||||
when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(keyConstraint));
|
||||
when(mockRegionAttributes.getPartitionAttributes()).thenAnswer(newGetter(partitionAttributes));
|
||||
when(mockRegionAttributes.getScope()).thenAnswer(newGetter(scope));
|
||||
when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(valueConstraint));
|
||||
|
||||
when(mockRegionFactory.create(anyString())).thenAnswer(invocation -> {
|
||||
String regionName = invocation.getArgument(0);
|
||||
|
||||
cacheRegions.stream().filter(region -> region.getName().equals(regionName)).findAny()
|
||||
.ifPresent(region -> { throw new RegionExistsException(region); });
|
||||
|
||||
Region<K, V> mockRegion = mockRegion(regionName, mockRegionAttributes);
|
||||
|
||||
cacheRegions.add(mockRegion);
|
||||
|
||||
when(mockCache.getRegion(eq(regionName))).thenReturn((Region<Object, Object>) mockRegion);
|
||||
when(mockRegion.getRegionService()).thenReturn(mockCache);
|
||||
|
||||
return mockRegion;
|
||||
});
|
||||
|
||||
return mockRegionFactory;
|
||||
@ClientCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, strict = true, excludeFilters =
|
||||
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
|
||||
LocalRegion.class, PartitionRegion.class, ReplicateRegion.class
|
||||
})
|
||||
)
|
||||
static class ClientPersistentEntitiesConfiguration {
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static <K, V> Region<K, V> mockRegion(String name, RegionAttributes<K, V> regionAttributes) {
|
||||
Region<K, V> mockRegion = mock(Region.class, mockName(name));
|
||||
|
||||
when(mockRegion.getName()).thenReturn(name);
|
||||
when(mockRegion.getFullPath()).thenReturn(toRegionPath(name));
|
||||
when(mockRegion.getAttributes()).thenReturn(regionAttributes);
|
||||
|
||||
return mockRegion;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static <R> Answer<R> newGetter(AtomicReference<R> returnValue) {
|
||||
return invocation -> returnValue.get();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@ClientCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@SuppressWarnings("unused")
|
||||
protected static <T, R> Answer<R> newSetter(Class<T> parameterType, AtomicReference<T> argument, R returnValue) {
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, clientRegionShortcut = ClientRegionShortcut.LOCAL,
|
||||
poolName = "TestPool", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
|
||||
classes = { LocalRegion.class, PartitionRegion.class, ReplicateRegion.class })
|
||||
)
|
||||
static class ClientPersistentEntitiesWithCustomConfiguration {
|
||||
|
||||
return invocation -> {
|
||||
argument.set(invocation.getArgument(0));
|
||||
return returnValue;
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
static abstract class ClientCacheConfiguration {
|
||||
|
||||
@Bean
|
||||
ClientCache gemfireCache() {
|
||||
return mockClientCache();
|
||||
@Bean("TestPool")
|
||||
Pool testPool() {
|
||||
return mock(Pool.class, "TestPool");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ClientCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, serverRegionShortcut = RegionShortcut.LOCAL,
|
||||
strict = true, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
|
||||
classes = CollocatedPartitionRegionEntity.class)
|
||||
)
|
||||
static class ClientPersistentEntitiesWithServerRegionMappingAnnotationsConfiguration {
|
||||
}
|
||||
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@SuppressWarnings("unused")
|
||||
static abstract class ServerCacheConfiguration {
|
||||
|
||||
@Bean
|
||||
Cache gemfireCache() {
|
||||
return mockCache();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, strict = true,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
|
||||
classes = { LocalRegion.class, PartitionRegion.class, ReplicateRegion.class }))
|
||||
static class ClientPersistentEntitiesConfiguration extends ClientCacheConfiguration {
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,
|
||||
classes = { ClientRegion.class, LocalRegion.class, ReplicateRegion.class }))
|
||||
static class PeerPartitionRegionPersistentEntitiesConfiguration extends ServerCacheConfiguration {
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, excludeFilters = {
|
||||
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {
|
||||
ClientRegion.class, LocalRegion.class, ReplicateRegion.class
|
||||
}),
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = GenericRegionEntity.class)
|
||||
})
|
||||
static class PeerPartitionRegionPersistentEntitiesConfiguration {
|
||||
|
||||
@Bean @Lazy
|
||||
DiskStore mockDiskStore() {
|
||||
return mock(DiskStore.class, mockName("MockDiskStore"));
|
||||
return mock(DiskStore.class, MockObjectsSupport.mockObjectIdentifier("MockDiskStore"));
|
||||
}
|
||||
|
||||
@Bean @Lazy
|
||||
PartitionResolver mockPartitionResolver() {
|
||||
return mock(PartitionResolver.class, mockName("MockPartitionResolver"));
|
||||
return mock(PartitionResolver.class,
|
||||
MockObjectsSupport.mockObjectIdentifier("MockPartitionResolver"));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ClientRegion.class),
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = CollocatedPartitionRegionEntity.class) })
|
||||
static class ServerPersistentEntitiesConfiguration extends ServerCacheConfiguration {
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, excludeFilters = {
|
||||
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ClientRegion.class),
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = CollocatedPartitionRegionEntity.class)
|
||||
})
|
||||
static class ServerPersistentEntitiesConfiguration {
|
||||
}
|
||||
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, serverRegionShortcut = RegionShortcut.REPLICATE,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
CollocatedPartitionRegionEntity.class, ReplicateRegionEntity.class
|
||||
})
|
||||
)
|
||||
static class ServerPersistentEntitiesWithCustomConfiguration {
|
||||
}
|
||||
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, clientRegionShortcut = ClientRegionShortcut.LOCAL,
|
||||
poolName = "TestPool", excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
CollocatedPartitionRegionEntity.class, LocalRegionEntity.class, ReplicateRegionEntity.class
|
||||
})
|
||||
)
|
||||
static class ServerPersistentEntitiesWithClientRegionMappingAnnotationsConfiguration {
|
||||
}
|
||||
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, excludeFilters =
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, ReplicateRegionEntity.class
|
||||
})
|
||||
)
|
||||
static class ExistingPartitionRegionPersistentEntitiesConfiguration extends ServerCacheConfiguration {
|
||||
static class ExistingPartitionRegionPersistentEntitiesConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unused")
|
||||
PartitionedRegionFactoryBean<Long, PartitionRegionEntity> customersRegion(GemFireCache gemfireCache) {
|
||||
|
||||
PartitionedRegionFactoryBean<Long, PartitionRegionEntity> customers = new PartitionedRegionFactoryBean<>();
|
||||
|
||||
customers.setCache(gemfireCache);
|
||||
@@ -603,18 +556,20 @@ public class EnableEntityDefinedRegionsUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class,
|
||||
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
@PeerCacheApplication
|
||||
@EnableGemFireMockObjects
|
||||
@EnableEntityDefinedRegions(basePackageClasses = NonEntity.class, excludeFilters =
|
||||
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
ClientRegionEntity.class, CollocatedPartitionRegionEntity.class, GenericRegionEntity.class,
|
||||
LocalRegionEntity.class, PartitionRegionEntity.class
|
||||
})
|
||||
)
|
||||
static class ExistingReplicateRegionPersistentEntitiesConfiguration extends ServerCacheConfiguration {
|
||||
static class ExistingReplicateRegionPersistentEntitiesConfiguration {
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("unused")
|
||||
ReplicatedRegionFactoryBean<Long, ReplicateRegionEntity> accountsRegion(GemFireCache gemfireCache) {
|
||||
|
||||
ReplicatedRegionFactoryBean<Long, ReplicateRegionEntity> accounts = new ReplicatedRegionFactoryBean<>();
|
||||
|
||||
accounts.setCache(gemfireCache);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.gemfire.test.mock;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
@@ -29,11 +30,14 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeSet;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.NOT_SUPPORTED;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newUnsupportedOperationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
@@ -58,6 +62,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.geode.cache.Cache;
|
||||
import org.apache.geode.cache.CacheFactory;
|
||||
import org.apache.geode.cache.CacheListener;
|
||||
import org.apache.geode.cache.CacheLoader;
|
||||
import org.apache.geode.cache.CacheWriter;
|
||||
import org.apache.geode.cache.CustomExpiry;
|
||||
import org.apache.geode.cache.DataPolicy;
|
||||
import org.apache.geode.cache.DiskStore;
|
||||
@@ -66,9 +73,15 @@ import org.apache.geode.cache.EvictionAttributes;
|
||||
import org.apache.geode.cache.ExpirationAction;
|
||||
import org.apache.geode.cache.ExpirationAttributes;
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.cache.PartitionAttributes;
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.RegionAttributes;
|
||||
import org.apache.geode.cache.RegionExistsException;
|
||||
import org.apache.geode.cache.RegionFactory;
|
||||
import org.apache.geode.cache.RegionService;
|
||||
import org.apache.geode.cache.RegionShortcut;
|
||||
import org.apache.geode.cache.Scope;
|
||||
import org.apache.geode.cache.SubscriptionAttributes;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.ClientCacheFactory;
|
||||
import org.apache.geode.cache.client.ClientRegionFactory;
|
||||
@@ -85,6 +98,7 @@ import org.apache.geode.cache.query.QueryStatistics;
|
||||
import org.apache.geode.cache.server.CacheServer;
|
||||
import org.apache.geode.cache.server.ClientSubscriptionConfig;
|
||||
import org.apache.geode.compression.Compressor;
|
||||
import org.apache.geode.distributed.DistributedMember;
|
||||
import org.apache.geode.distributed.DistributedSystem;
|
||||
import org.apache.geode.internal.concurrent.ConcurrentHashSet;
|
||||
import org.apache.geode.pdx.PdxSerializer;
|
||||
@@ -132,6 +146,9 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
private static final String REPEATING_REGION_SEPARATOR = Region.SEPARATOR + "{2,}";
|
||||
|
||||
/**
|
||||
* Destroys all mock object state.
|
||||
*/
|
||||
public static void destroy() {
|
||||
singletonCache.set(null);
|
||||
diskStores.clear();
|
||||
@@ -139,27 +156,241 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
regionAttributes.clear();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Converts the given {@link ClientRegionShortcut} into a corresponding {@link DataPolicy}.
|
||||
*
|
||||
* @param clientRegionShortcut {@link ClientRegionShortcut} to convert.
|
||||
* @return a {@link DataPolicy} from the {@link ClientRegionShortcut}.
|
||||
* @see org.apache.geode.cache.client.ClientRegionShortcut
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static DataPolicy convert(ClientRegionShortcut clientRegionShortcut) {
|
||||
|
||||
return Optional.ofNullable(clientRegionShortcut).map(shortcut -> {
|
||||
|
||||
switch(shortcut) {
|
||||
case CACHING_PROXY:
|
||||
case CACHING_PROXY_HEAP_LRU:
|
||||
case CACHING_PROXY_OVERFLOW:
|
||||
case LOCAL:
|
||||
case LOCAL_HEAP_LRU:
|
||||
case LOCAL_OVERFLOW:
|
||||
return DataPolicy.NORMAL;
|
||||
case LOCAL_PERSISTENT:
|
||||
case LOCAL_PERSISTENT_OVERFLOW:
|
||||
return DataPolicy.PERSISTENT_REPLICATE;
|
||||
case PROXY:
|
||||
return DataPolicy.EMPTY;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}).orElse(DataPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link RegionShortcut} into a corresponding {@link DataPolicy}.
|
||||
*
|
||||
* @param regionShortcut {@link RegionShortcut} to convert.
|
||||
* @return a {@link DataPolicy} from the {@link RegionShortcut}.
|
||||
* @see org.apache.geode.cache.RegionShortcut
|
||||
* @see org.apache.geode.cache.DataPolicy
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static DataPolicy convert(RegionShortcut regionShortcut) {
|
||||
|
||||
return Optional.ofNullable(regionShortcut).map(shortcut -> {
|
||||
|
||||
switch (shortcut) {
|
||||
case LOCAL:
|
||||
case LOCAL_HEAP_LRU:
|
||||
case LOCAL_OVERFLOW:
|
||||
return DataPolicy.NORMAL;
|
||||
case PARTITION:
|
||||
case PARTITION_HEAP_LRU:
|
||||
case PARTITION_OVERFLOW:
|
||||
case PARTITION_PROXY:
|
||||
case PARTITION_PROXY_REDUNDANT:
|
||||
case PARTITION_REDUNDANT:
|
||||
case PARTITION_REDUNDANT_HEAP_LRU:
|
||||
case PARTITION_REDUNDANT_OVERFLOW:
|
||||
return DataPolicy.PARTITION;
|
||||
case PARTITION_PERSISTENT:
|
||||
case PARTITION_PERSISTENT_OVERFLOW:
|
||||
case PARTITION_REDUNDANT_PERSISTENT:
|
||||
case PARTITION_REDUNDANT_PERSISTENT_OVERFLOW:
|
||||
return DataPolicy.PERSISTENT_PARTITION;
|
||||
case REPLICATE:
|
||||
case REPLICATE_HEAP_LRU:
|
||||
case REPLICATE_OVERFLOW:
|
||||
return DataPolicy.REPLICATE;
|
||||
case LOCAL_PERSISTENT:
|
||||
case LOCAL_PERSISTENT_OVERFLOW:
|
||||
case REPLICATE_PERSISTENT:
|
||||
case REPLICATE_PERSISTENT_OVERFLOW:
|
||||
return DataPolicy.PERSISTENT_REPLICATE;
|
||||
case REPLICATE_PROXY:
|
||||
return DataPolicy.EMPTY;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
}).orElse(DataPolicy.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the given {@link IoExceptionThrowingOperation}, handling any {@link IOException IOExceptions} thrown
|
||||
* during normal IO processing.
|
||||
*
|
||||
* @param operation {@link IoExceptionThrowingOperation} to execute.
|
||||
* @return a boolean indicating whether the IO operation was successful, or {@literal false} if the IO operation
|
||||
* threw an {@link IOException}.
|
||||
* @see org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport.IoExceptionThrowingOperation
|
||||
* @see java.io.IOException
|
||||
*/
|
||||
private static boolean doSafeIo(IoExceptionThrowingOperation operation) {
|
||||
|
||||
try {
|
||||
operation.doIo();
|
||||
return true;
|
||||
}
|
||||
catch (IOException cause) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Region} is a root {@link Region}.
|
||||
*
|
||||
* @param region {@link Region} to evaluate.
|
||||
* @return a boolean value indicating whether the {@link Region} is a root {@link Region}.
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see #isRootRegion(String)
|
||||
*/
|
||||
private static boolean isRootRegion(Region<?, ?> region) {
|
||||
return isRootRegion(region.getFullPath());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Determines whether the {@link Region} identified by the given {@link String path} is a root {@link Region}.
|
||||
*
|
||||
* @param regionPath {@link String path} identifying the {@link Region} to evaluate.
|
||||
* @return a boolean value indicating whether the {@link Region} identified by the given {@link String path}
|
||||
* is a root {@link Region}.
|
||||
*/
|
||||
private static boolean isRootRegion(String regionPath) {
|
||||
return (regionPath.lastIndexOf(Region.SEPARATOR) <= 0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Normalizes the given {@link Region#getFullPath() Regon path} by removing all duplicate, repeating
|
||||
* {@link Region#SEPARATOR} characters between path segments as well as removing the trailing
|
||||
* {@link Region#SEPARATOR}.
|
||||
*
|
||||
* @param regionPath {@link Region#getFullPath()} to normalize.
|
||||
* @return a normalized version of the given {@link Region#getFullPath()}.
|
||||
*/
|
||||
private static String normalizeRegionPath(String regionPath) {
|
||||
|
||||
regionPath = regionPath.replaceAll(REPEATING_REGION_SEPARATOR, Region.SEPARATOR);
|
||||
|
||||
regionPath = regionPath.endsWith(Region.SEPARATOR)
|
||||
? regionPath.substring(0, regionPath.length() - 1) : regionPath;
|
||||
|
||||
return regionPath;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Remembers the given mock {@link GemFireCache} object, which may be a {@link ClientCache} or a peer {@link Cache}.
|
||||
*
|
||||
* @param <T> {@link Class sub-type} of the {@link GemFireCache} instance.
|
||||
* @param mockedGemFireCache {@link GemFireCache} to remember.
|
||||
* @param useSingletonCache boolean value indicating whether the {@link GemFireCache} is a Singleton.
|
||||
* @return the given {@link GemFireCache}.
|
||||
* @throws IllegalArgumentException if {@link GemFireCache} is {@literal null}.
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
*/
|
||||
private static <T extends GemFireCache> T rememberMockedGemFireCache(T mockedGemFireCache,
|
||||
boolean useSingletonCache) {
|
||||
|
||||
return Optional.ofNullable(mockedGemFireCache)
|
||||
.map(it -> {
|
||||
|
||||
if (useSingletonCache) {
|
||||
singletonCache.compareAndSet(null, it);
|
||||
}
|
||||
|
||||
return it;
|
||||
})
|
||||
.orElseThrow(() -> newIllegalArgumentException("GemFireCache is required"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remembers the given mock {@link Region}.
|
||||
*
|
||||
* @param <K> {@link Class type} of the {@link Region} key.
|
||||
* @param <V> {@link Class type} of the {@link Region} value.
|
||||
* @param mockRegion {@link Region} to remember.
|
||||
* @throws IllegalArgumentException if the given {@link Region} is {@literal null}.
|
||||
* @throws RegionExistsException if the given {@link Region} already exists.
|
||||
* @return the given {@link Region}.
|
||||
* @see org.apache.geode.cache.Region
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <K, V> Region<K, V> rememberMockedRegion(Region<K, V> mockRegion) {
|
||||
|
||||
String mockRegionPath = Optional.ofNullable(mockRegion).map(Region::getFullPath)
|
||||
.orElseThrow(() -> newIllegalArgumentException("Region is required"));
|
||||
|
||||
if (regions.putIfAbsent(mockRegionPath, (Region) mockRegion) != null) {
|
||||
throw new RegionExistsException(mockRegion);
|
||||
}
|
||||
|
||||
assertThat(regions).containsValue((Region) mockRegion);
|
||||
|
||||
return mockRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the single, remembered {@link GemFireCache} if using GemFire in Singleton-mode.
|
||||
*
|
||||
* @param <T> {@link Class sub-type} of the {@link GemFireCache} instance.
|
||||
* @param useSingletonCache boolean value indicating if mock infrastructure is using GemFire Singletons.
|
||||
* @return an {@link Optional}, single remembered instance of the {@link GemFireCache}.
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends GemFireCache> Optional<T> resolveMockedGemFireCache(boolean useSingletonCache) {
|
||||
return Optional.ofNullable((T) singletonCache.get()).filter(it -> useSingletonCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the {@link RegionAttributes} identified by the given {@link String id}.
|
||||
*
|
||||
* @param <K> {@link Class type} of the {@link Region} key.
|
||||
* @param <V> {@link Class type} of the {@link Region} value.
|
||||
* @param regionAttributesId {@link String id} identifying the {@link RegionAttributes} to resolve.
|
||||
* @return the resolved {@link RegionAttributes} identified by the given {@link String id}.
|
||||
* @throws IllegalStateException if {@link RegionAttributes} could not be resolved from the given {@link String id}.
|
||||
* @see org.apache.geode.cache.RegionAttributes
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <K, V> RegionAttributes<K, V> resolveRegionAttributes(String regionAttributesId) {
|
||||
|
||||
return (RegionAttributes<K, V>) Optional.ofNullable(regionAttributes.get(regionAttributesId)).orElseThrow(() ->
|
||||
newIllegalStateException("RegionAttributes with ID [%s] cannot be found", regionAttributesId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link String Region name} into a proper {@link Region#getName() Region name}.
|
||||
*
|
||||
* @param regionName {@link String Region name} to evaluate.
|
||||
* @return a proper {@link Region#getName() Region name} from the given {@link String Region name}.
|
||||
* @throws IllegalArgumentException if {@link String Region name} is {@literal null}
|
||||
* or {@link String#isEmpty() empty}.
|
||||
* @see java.lang.String
|
||||
*/
|
||||
private static String toRegionName(String regionName) {
|
||||
|
||||
return Optional.ofNullable(regionName)
|
||||
@@ -172,7 +403,15 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
.orElseThrow(() -> newIllegalArgumentException("Region name [%s] is required", regionName));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/**
|
||||
* Converts the given {@link String Region path} into a proper {@link Region#getFullPath() Region path}.
|
||||
*
|
||||
* @param regionPath {@link String Region path} to evaluate.
|
||||
* @return a proper {@link Region#getFullPath() Region path} from the given {@link String Region path}.
|
||||
* @throws IllegalArgumentException if {@link String Region path} is {@literal null}
|
||||
* or {@link String#isEmpty() empty}.
|
||||
* @see java.lang.String
|
||||
*/
|
||||
private static String toRegionPath(String regionPath) {
|
||||
|
||||
return Optional.ofNullable(regionPath)
|
||||
@@ -235,11 +474,13 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
String regionPath = invocation.getArgument(0);
|
||||
|
||||
Optional.ofNullable(regionPath).map(String::trim).filter(it -> !it.isEmpty())
|
||||
String resolvedRegionPath = Optional.ofNullable(regionPath)
|
||||
.map(String::trim)
|
||||
.filter(it -> !it.isEmpty())
|
||||
.map(MockGemFireObjectsSupport::toRegionPath)
|
||||
.orElseThrow(() -> newIllegalArgumentException("Region path [%s] is not valid", regionPath));
|
||||
|
||||
return regions.get(regionPath);
|
||||
return regions.get(resolvedRegionPath);
|
||||
});
|
||||
|
||||
when(mockRegionService.createPdxEnum(anyString(), anyString(), anyInt()))
|
||||
@@ -260,8 +501,11 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
doAnswer(newVoidAnswer(invocation -> mockClientCache.close())).when(mockClientCache).close(anyBoolean());
|
||||
|
||||
when(mockClientCache.createClientRegionFactory(any(ClientRegionShortcut.class)))
|
||||
.thenAnswer(invocation -> mockClientRegionFactory(mockClientCache));
|
||||
when(mockClientCache.createClientRegionFactory(any(ClientRegionShortcut.class))).thenAnswer(invocation ->
|
||||
mockClientRegionFactory(mockClientCache, invocation.<ClientRegionShortcut>getArgument(0)));
|
||||
|
||||
when(mockClientCache.createClientRegionFactory(anyString())).thenAnswer(invocation ->
|
||||
mockClientRegionFactory(mockClientCache, invocation.<String>getArgument(0)));
|
||||
|
||||
return mockQueryService(mockCacheApi(mockClientCache));
|
||||
}
|
||||
@@ -273,6 +517,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
return mockQueryService(mockCacheApi(mockGemFireCache));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Cache mockPeerCache() {
|
||||
|
||||
Cache mockCache = mock(Cache.class);
|
||||
@@ -306,6 +551,17 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
when(mockCache.getReconnectedCache()).thenAnswer(invocation -> mockPeerCache());
|
||||
when(mockCache.getSearchTimeout()).thenAnswer(newGetter(searchTimeout));
|
||||
|
||||
when(mockCache.createRegionFactory()).thenAnswer(invocation -> mockRegionFactory(mockCache));
|
||||
|
||||
when(mockCache.createRegionFactory(any(RegionAttributes.class))).thenAnswer(invocation ->
|
||||
mockRegionFactory(mockCache, invocation.<RegionAttributes<?, ?>>getArgument(0)));
|
||||
|
||||
when(mockCache.createRegionFactory(any(RegionShortcut.class))).thenAnswer(invocation ->
|
||||
mockRegionFactory(mockCache, invocation.<RegionShortcut>getArgument(0)));
|
||||
|
||||
when(mockCache.createRegionFactory(anyString())).thenAnswer(invocation ->
|
||||
mockRegionFactory(mockCache, invocation.<String>getArgument(0)));
|
||||
|
||||
return mockQueryService(mockCacheApi(mockCache));
|
||||
}
|
||||
|
||||
@@ -313,6 +569,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
CacheServer mockCacheServer = mock(CacheServer.class);
|
||||
|
||||
AtomicBoolean running = new AtomicBoolean(false);
|
||||
AtomicBoolean tcpNoDelay = new AtomicBoolean(CacheServer.DEFAULT_TCP_NO_DELAY);
|
||||
|
||||
AtomicInteger maxConnections = new AtomicInteger(CacheServer.DEFAULT_MAX_CONNECTIONS);
|
||||
@@ -361,27 +618,51 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
doAnswer(newSetter(tcpNoDelay, null))
|
||||
.when(mockCacheServer).setTcpNoDelay(anyBoolean());
|
||||
|
||||
when(mockCacheServer.isRunning()).thenAnswer(newGetter(running));
|
||||
when(mockCacheServer.getAllClientSessions()).thenReturn(Collections.emptySet());
|
||||
when(mockCacheServer.getBindAddress()).thenAnswer(newGetter(bindAddress));
|
||||
when(mockCacheServer.getClientSession(any(DistributedMember.class)))
|
||||
.thenThrow(newUnsupportedOperationException(NOT_SUPPORTED));
|
||||
when(mockCacheServer.getClientSession(anyString())).thenThrow(newUnsupportedOperationException(NOT_SUPPORTED));
|
||||
when(mockCacheServer.getHostnameForClients()).thenAnswer(newGetter(hostnameForClients));
|
||||
when(mockCacheServer.getInterestRegistrationListeners()).thenReturn(Collections.emptySet());
|
||||
when(mockCacheServer.getLoadPollInterval()).thenAnswer(newGetter(loadPollInterval));
|
||||
when(mockCacheServer.getLoadProbe()).thenThrow(newUnsupportedOperationException(NOT_SUPPORTED));
|
||||
when(mockCacheServer.getMaxConnections()).thenAnswer(newGetter(maxConnections));
|
||||
when(mockCacheServer.getMaximumMessageCount()).thenAnswer(newGetter(maxMessageCount));
|
||||
when(mockCacheServer.getMaxThreads()).thenAnswer(newGetter(maxThreads));
|
||||
when(mockCacheServer.getMaximumTimeBetweenPings()).thenAnswer(newGetter(maxTimeBetweenPings));
|
||||
when(mockCacheServer.getMaxThreads()).thenAnswer(newGetter(maxThreads));
|
||||
when(mockCacheServer.getMessageTimeToLive()).thenAnswer(newGetter(messageTimeToLive));
|
||||
when(mockCacheServer.getPort()).thenAnswer(newGetter(port));
|
||||
when(mockCacheServer.getSocketBufferSize()).thenAnswer(newGetter(socketBufferSize));
|
||||
when(mockCacheServer.getTcpNoDelay()).thenAnswer(newGetter(tcpNoDelay));
|
||||
|
||||
ClientSubscriptionConfig mockClientSubsriptionConfig = mockClientSubscriptionConfig();
|
||||
ClientSubscriptionConfig mockClientSubscriptionConfig = mockClientSubscriptionConfig();
|
||||
|
||||
when(mockCacheServer.getClientSubscriptionConfig()).thenReturn(mockClientSubsriptionConfig);
|
||||
when(mockCacheServer.getClientSubscriptionConfig()).thenReturn(mockClientSubscriptionConfig);
|
||||
|
||||
doSafeIo(() -> doAnswer(newSetter(running, true, null)).when(mockCacheServer).start());
|
||||
doAnswer(newSetter(running, false, null)).when(mockCacheServer).stop();
|
||||
|
||||
return mockCacheServer;
|
||||
}
|
||||
|
||||
public static <K, V> ClientRegionFactory<K, V> mockClientRegionFactory(ClientCache mockClientCache,
|
||||
ClientRegionShortcut clientRegionShortcut) {
|
||||
|
||||
return mockClientRegionFactory(mockClientCache, clientRegionShortcut, null);
|
||||
}
|
||||
|
||||
public static <K, V> ClientRegionFactory<K, V> mockClientRegionFactory(ClientCache mockClientCache,
|
||||
String regionAttributesId) {
|
||||
|
||||
return mockClientRegionFactory(mockClientCache, null,
|
||||
resolveRegionAttributes(regionAttributesId));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> ClientRegionFactory<K, V> mockClientRegionFactory(ClientCache mockClientCache) {
|
||||
public static <K, V> ClientRegionFactory<K, V> mockClientRegionFactory(ClientCache mockClientCache,
|
||||
ClientRegionShortcut clientRegionShortcut, RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
ClientRegionFactory<K, V> mockClientRegionFactory =
|
||||
mock(ClientRegionFactory.class, mockObjectIdentifier("MockClientRegionFactory"));
|
||||
@@ -389,28 +670,79 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
ExpirationAttributes DEFAULT_EXPIRATION_ATTRIBUTES =
|
||||
new ExpirationAttributes(0, ExpirationAction.INVALIDATE);
|
||||
|
||||
AtomicBoolean cloningEnabled = new AtomicBoolean(false);
|
||||
AtomicBoolean concurrencyChecksEnabled = new AtomicBoolean(false);
|
||||
AtomicBoolean diskSynchronous = new AtomicBoolean(true);
|
||||
AtomicBoolean statisticsEnabled = new AtomicBoolean(false);
|
||||
Optional<RegionAttributes<K, V>> optionalRegionAttributes = Optional.ofNullable(regionAttributes);
|
||||
|
||||
AtomicInteger concurrencyLevel = new AtomicInteger(16);
|
||||
AtomicInteger initialCapacity = new AtomicInteger(16);
|
||||
AtomicBoolean cloningEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCloningEnabled).orElse(false));
|
||||
|
||||
AtomicReference<Compressor> compressor = new AtomicReference<>(null);
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryIdleTimeout = new AtomicReference<>(null);
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryTimeToLive = new AtomicReference<>(null);
|
||||
AtomicReference<String> diskStoreName = new AtomicReference<>(null);
|
||||
AtomicReference<ExpirationAttributes> entryIdleTimeout = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
|
||||
AtomicReference<ExpirationAttributes> entryTimeToLive = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
|
||||
AtomicReference<EvictionAttributes> evictionAttributes =
|
||||
new AtomicReference<>(EvictionAttributes.createLRUEntryAttributes());
|
||||
AtomicReference<Class<K>> keyConstraint = new AtomicReference<>();
|
||||
AtomicReference<Float> loadFactor = new AtomicReference<>(0.75f);
|
||||
AtomicReference<String> poolName = new AtomicReference<>(null);
|
||||
AtomicReference<ExpirationAttributes> regionIdleTimeout = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
|
||||
AtomicReference<ExpirationAttributes> regionTimeToLive = new AtomicReference<>(DEFAULT_EXPIRATION_ATTRIBUTES);
|
||||
AtomicReference<Class<K>> valueConstraint = new AtomicReference<>();
|
||||
AtomicBoolean concurrencyChecksEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getConcurrencyChecksEnabled).orElse(false));
|
||||
|
||||
AtomicBoolean diskSynchronous = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::isDiskSynchronous).orElse(true));
|
||||
|
||||
AtomicBoolean statisticsEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getStatisticsEnabled).orElse(false));
|
||||
|
||||
AtomicInteger concurrencyLevel = new AtomicInteger(optionalRegionAttributes
|
||||
.map(RegionAttributes::getConcurrencyLevel).orElse(16));
|
||||
|
||||
AtomicInteger initialCapacity = new AtomicInteger(optionalRegionAttributes
|
||||
.map(RegionAttributes::getInitialCapacity).orElse(16));
|
||||
|
||||
AtomicReference<Compressor> compressor = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCompressor).orElse(null));
|
||||
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCustomEntryIdleTimeout).orElse(null));
|
||||
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCustomEntryTimeToLive).orElse(null));
|
||||
|
||||
AtomicReference<DataPolicy> dataPolicy = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getDataPolicy).orElseGet(() -> convert(clientRegionShortcut)));
|
||||
|
||||
AtomicReference<String> diskStoreName = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getDiskStoreName).orElse(null));
|
||||
|
||||
AtomicReference<ExpirationAttributes> entryIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEntryIdleTimeout).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<ExpirationAttributes> entryTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEntryTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<EvictionAttributes> evictionAttributes = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEvictionAttributes).orElseGet(() -> EvictionAttributes.createLRUEntryAttributes()));
|
||||
|
||||
AtomicReference<Class<K>> keyConstraint = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getKeyConstraint).orElse(null));
|
||||
|
||||
AtomicReference<Float> loadFactor = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getLoadFactor).orElse(0.75f));
|
||||
|
||||
AtomicReference<String> poolName = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getPoolName).orElse(null));
|
||||
|
||||
AtomicReference<ExpirationAttributes> regionIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getRegionIdleTimeout).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<ExpirationAttributes> regionTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getRegionTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<Class<V>> valueConstraint = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getValueConstraint).orElse(null));
|
||||
|
||||
List<CacheListener> cacheListeners = new ArrayList<>(Arrays.asList(nullSafeArray(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCacheListeners).orElse(null), CacheListener.class)));
|
||||
|
||||
when(mockClientRegionFactory.addCacheListener(any(CacheListener.class)))
|
||||
.thenAnswer(newAdder(cacheListeners, mockClientRegionFactory));
|
||||
|
||||
when(mockClientRegionFactory.initCacheListeners(any(CacheListener[].class))).thenAnswer(invocation -> {
|
||||
cacheListeners.clear();
|
||||
Collections.addAll(cacheListeners, invocation.getArgument(0));
|
||||
return mockClientRegionFactory;
|
||||
});
|
||||
|
||||
when(mockClientRegionFactory.setCloningEnabled(anyBoolean()))
|
||||
.thenAnswer(newSetter(cloningEnabled, mockClientRegionFactory));
|
||||
@@ -472,13 +804,16 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
RegionAttributes<K, V> mockRegionAttributes =
|
||||
mock(RegionAttributes.class, mockObjectIdentifier("MockRegionAttributes"));
|
||||
|
||||
when(mockRegionAttributes.getCacheListeners())
|
||||
.thenAnswer(newGetter(() -> cacheListeners.toArray(new CacheListener[cacheListeners.size()])));
|
||||
|
||||
when(mockRegionAttributes.getCloningEnabled()).thenAnswer(newGetter(cloningEnabled));
|
||||
when(mockRegionAttributes.getCompressor()).thenAnswer(newGetter(compressor));
|
||||
when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenAnswer(newGetter(concurrencyChecksEnabled));
|
||||
when(mockRegionAttributes.getConcurrencyLevel()).thenAnswer(newGetter(concurrencyLevel));
|
||||
when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenAnswer(newGetter(customEntryIdleTimeout));
|
||||
when(mockRegionAttributes.getCustomEntryTimeToLive()).thenAnswer(newGetter(customEntryTimeToLive));
|
||||
when(mockRegionAttributes.getDataPolicy()).thenReturn(DataPolicy.NORMAL);
|
||||
when(mockRegionAttributes.getDataPolicy()).thenAnswer(newGetter(dataPolicy));
|
||||
when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(diskStoreName));
|
||||
when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous));
|
||||
when(mockRegionAttributes.getEntryIdleTimeout()).thenAnswer(newGetter(entryIdleTimeout));
|
||||
@@ -871,7 +1206,9 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
}
|
||||
|
||||
private static CqQuery add(Collection<CqQuery> cqQueries, CqQuery cqQuery) {
|
||||
|
||||
cqQueries.add(cqQuery);
|
||||
|
||||
return cqQuery;
|
||||
}
|
||||
|
||||
@@ -1000,14 +1337,14 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
boolean recursive = invocation.getArgument(0);
|
||||
|
||||
return recursive ? subRegions.stream()
|
||||
.flatMap(subRegion -> subRegion.subregions(true).stream()).collect(Collectors.toSet())
|
||||
return recursive
|
||||
? subRegions.stream()
|
||||
.flatMap(subRegion -> subRegion.subregions(true).stream())
|
||||
.collect(Collectors.toSet())
|
||||
: subRegions;
|
||||
});
|
||||
|
||||
regions.put(mockRegion.getFullPath(), (Region) mockRegion);
|
||||
|
||||
return mockRegion;
|
||||
return rememberMockedRegion(mockRegion);
|
||||
}
|
||||
|
||||
public static <K, V> Region<K, V> mockSubRegion(Region<K, V> parent, String name,
|
||||
@@ -1022,6 +1359,295 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
return mockSubRegion;
|
||||
}
|
||||
|
||||
public static <K, V> RegionFactory<K, V> mockRegionFactory(Cache mockCache) {
|
||||
return mockRegionFactory(mockCache, null, null);
|
||||
}
|
||||
|
||||
public static <K, V> RegionFactory<K, V> mockRegionFactory(Cache mockCache,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
return mockRegionFactory(mockCache, null, regionAttributes);
|
||||
}
|
||||
|
||||
public static <K, V> RegionFactory<K, V> mockRegionFactory(Cache mockCache, RegionShortcut regionShortcut) {
|
||||
return mockRegionFactory(mockCache, regionShortcut, null);
|
||||
}
|
||||
|
||||
public static <K, V> RegionFactory<K, V> mockRegionFactory(Cache mockCache, String regionAttributesId) {
|
||||
return mockRegionFactory(mockCache, null, resolveRegionAttributes(regionAttributesId));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> RegionFactory<K, V> mockRegionFactory(Cache mockCache, RegionShortcut regionShortcut,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
|
||||
RegionFactory<K, V> mockRegionFactory = mock(RegionFactory.class,
|
||||
mockObjectIdentifier("MockRegionFactory"));
|
||||
|
||||
Optional<RegionAttributes<K, V>> optionalRegionAttributes = Optional.ofNullable(regionAttributes);
|
||||
|
||||
ExpirationAttributes DEFAULT_EXPIRATION_ATTRIBUTES =
|
||||
new ExpirationAttributes(0, ExpirationAction.INVALIDATE);
|
||||
|
||||
AtomicBoolean cloningEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCloningEnabled).orElse(false));
|
||||
|
||||
AtomicBoolean concurrencyChecksEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getConcurrencyChecksEnabled).orElse(true));
|
||||
|
||||
AtomicBoolean diskSynchronous = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::isDiskSynchronous).orElse(true));
|
||||
|
||||
AtomicBoolean enableAsyncConflation = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEnableAsyncConflation).orElse(false));
|
||||
|
||||
AtomicBoolean enableSubscriptionConflation = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEnableSubscriptionConflation).orElse(false));
|
||||
|
||||
AtomicBoolean ignoreJta = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getIgnoreJTA).orElse(false));
|
||||
|
||||
AtomicBoolean indexMaintenanceSynchronous = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getIndexMaintenanceSynchronous).orElse(true));
|
||||
|
||||
AtomicBoolean lockGrantor = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::isLockGrantor).orElse(false));
|
||||
|
||||
AtomicBoolean multicastEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getMulticastEnabled).orElse(false));
|
||||
|
||||
AtomicBoolean offHeap = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getOffHeap).orElse(false));
|
||||
|
||||
AtomicBoolean statisticsEnabled = new AtomicBoolean(optionalRegionAttributes
|
||||
.map(RegionAttributes::getStatisticsEnabled).orElse(false));
|
||||
|
||||
AtomicInteger concurrencyLevel = new AtomicInteger(optionalRegionAttributes
|
||||
.map(RegionAttributes::getConcurrencyLevel).orElse(16));
|
||||
|
||||
AtomicInteger initialCapacity = new AtomicInteger(optionalRegionAttributes
|
||||
.map(RegionAttributes::getInitialCapacity).orElse(16));
|
||||
|
||||
AtomicReference<CacheLoader> cacheLoader = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCacheLoader).orElse(null));
|
||||
|
||||
AtomicReference<CacheWriter> cacheWriter = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCacheWriter).orElse(null));
|
||||
|
||||
AtomicReference<Compressor> compressor = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCompressor).orElse(null));
|
||||
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCustomEntryIdleTimeout).orElse(null));
|
||||
|
||||
AtomicReference<CustomExpiry<K, V>> customEntryTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCustomEntryTimeToLive).orElse(null));
|
||||
|
||||
AtomicReference<DataPolicy> dataPolicy = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getDataPolicy).orElseGet(() -> convert(regionShortcut)));
|
||||
|
||||
AtomicReference<String> diskStoreName = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getDiskStoreName).orElse(null));
|
||||
|
||||
AtomicReference<ExpirationAttributes> entryIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEntryIdleTimeout).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<ExpirationAttributes> entryTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEntryTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<EvictionAttributes> evictionAttributes = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getEvictionAttributes).orElseGet(() -> EvictionAttributes.createLRUEntryAttributes()));
|
||||
|
||||
AtomicReference<Class<K>> keyConstraint = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getKeyConstraint).orElse(null));
|
||||
|
||||
AtomicReference<Float> loadFactor = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getLoadFactor).orElse(0.75f));
|
||||
|
||||
AtomicReference<PartitionAttributes<K, V>> partitionAttributes = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getPartitionAttributes).orElse(null));
|
||||
|
||||
AtomicReference<String> poolName = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getPoolName).orElse(null));
|
||||
|
||||
AtomicReference<ExpirationAttributes> regionIdleTimeout = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getRegionIdleTimeout).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<ExpirationAttributes> regionTimeToLive = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getRegionTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES));
|
||||
|
||||
AtomicReference<Scope> scope = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getScope).orElse(Scope.DISTRIBUTED_NO_ACK));
|
||||
|
||||
AtomicReference<SubscriptionAttributes> subscriptionAttributes = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getSubscriptionAttributes).orElseGet(() -> new SubscriptionAttributes()));
|
||||
|
||||
AtomicReference<Class<V>> valueConstraint = new AtomicReference<>(optionalRegionAttributes
|
||||
.map(RegionAttributes::getValueConstraint).orElse(null));
|
||||
|
||||
List<CacheListener> cacheListeners = new ArrayList<>(Arrays.asList(nullSafeArray(optionalRegionAttributes
|
||||
.map(RegionAttributes::getCacheListeners).orElse(null), CacheListener.class)));
|
||||
|
||||
Set<String> asyncEventQueueIds = new HashSet<>(nullSafeSet(optionalRegionAttributes
|
||||
.map(RegionAttributes::getAsyncEventQueueIds).orElse(null)));
|
||||
|
||||
Set<String> gatewaySenderIds = new HashSet<>(nullSafeSet(optionalRegionAttributes
|
||||
.map(RegionAttributes::getGatewaySenderIds).orElse(null)));
|
||||
|
||||
when(mockRegionFactory.addAsyncEventQueueId(anyString()))
|
||||
.thenAnswer(newAdder(asyncEventQueueIds, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.addCacheListener(any(CacheListener.class)))
|
||||
.thenAnswer(newAdder(cacheListeners, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.addGatewaySenderId(anyString()))
|
||||
.thenAnswer(newAdder(gatewaySenderIds, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.initCacheListeners(any(CacheListener[].class))).thenAnswer(invocation -> {
|
||||
cacheListeners.clear();
|
||||
Collections.addAll(cacheListeners, invocation.getArgument(0));
|
||||
return mockRegionFactory;
|
||||
});
|
||||
|
||||
when(mockRegionFactory.setCacheLoader(any(CacheLoader.class)))
|
||||
.thenAnswer(newSetter(cacheLoader, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setCacheWriter(any(CacheWriter.class)))
|
||||
.thenAnswer(newSetter(cacheWriter, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setCloningEnabled(anyBoolean()))
|
||||
.thenAnswer(newSetter(cloningEnabled, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setCompressor(any(Compressor.class)))
|
||||
.thenAnswer(newSetter(compressor, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setConcurrencyChecksEnabled(anyBoolean()))
|
||||
.then(newSetter(concurrencyChecksEnabled, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setConcurrencyLevel(anyInt()))
|
||||
.thenAnswer(newSetter(concurrencyLevel, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setCustomEntryIdleTimeout(any(CustomExpiry.class)))
|
||||
.thenAnswer(newSetter(customEntryIdleTimeout, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setCustomEntryTimeToLive(any(CustomExpiry.class)))
|
||||
.thenAnswer(newSetter(customEntryTimeToLive, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setDataPolicy(any(DataPolicy.class)))
|
||||
.thenAnswer(newSetter(dataPolicy, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setDiskStoreName(anyString())).thenAnswer(newSetter(diskStoreName, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setDiskSynchronous(anyBoolean()))
|
||||
.thenAnswer(newSetter(diskSynchronous, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setEnableAsyncConflation(anyBoolean()))
|
||||
.thenAnswer(newSetter(enableAsyncConflation, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setEnableSubscriptionConflation(anyBoolean()))
|
||||
.thenAnswer(newSetter(enableSubscriptionConflation, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setEntryIdleTimeout(any(ExpirationAttributes.class)))
|
||||
.thenAnswer(newSetter(entryIdleTimeout, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setEntryTimeToLive(any(ExpirationAttributes.class)))
|
||||
.thenAnswer(newSetter(entryTimeToLive, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setEvictionAttributes(any(EvictionAttributes.class)))
|
||||
.thenAnswer(newSetter(evictionAttributes, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setIgnoreJTA(anyBoolean())).thenAnswer(newSetter(ignoreJta, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setIndexMaintenanceSynchronous(anyBoolean()))
|
||||
.thenAnswer(newSetter(indexMaintenanceSynchronous, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setInitialCapacity(anyInt())).thenAnswer(newSetter(initialCapacity, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setKeyConstraint(any(Class.class)))
|
||||
.thenAnswer(newSetter(keyConstraint, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setLoadFactor(anyFloat())).thenAnswer(newSetter(loadFactor, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setLockGrantor(anyBoolean())).thenAnswer(newSetter(lockGrantor, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setMulticastEnabled(anyBoolean()))
|
||||
.thenAnswer(newSetter(multicastEnabled, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setOffHeap(anyBoolean())).thenAnswer(newSetter(offHeap, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setPartitionAttributes(any(PartitionAttributes.class)))
|
||||
.thenAnswer(newSetter(partitionAttributes, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setPoolName(anyString())).thenAnswer(newSetter(poolName, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setRegionIdleTimeout(any(ExpirationAttributes.class)))
|
||||
.thenAnswer(newSetter(regionIdleTimeout, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setRegionTimeToLive(any(ExpirationAttributes.class)))
|
||||
.thenAnswer(newSetter(regionTimeToLive, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setScope(any(Scope.class))).thenAnswer(newSetter(scope, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setStatisticsEnabled(anyBoolean()))
|
||||
.thenAnswer(newSetter(statisticsEnabled, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setSubscriptionAttributes(any(SubscriptionAttributes.class)))
|
||||
.thenAnswer(newSetter(subscriptionAttributes, mockRegionFactory));
|
||||
|
||||
when(mockRegionFactory.setValueConstraint(any(Class.class)))
|
||||
.thenAnswer(newSetter(valueConstraint, mockRegionFactory));
|
||||
|
||||
RegionAttributes<K, V> mockRegionAttributes =
|
||||
mock(RegionAttributes.class, mockObjectIdentifier("MockRegionAttributes"));
|
||||
|
||||
when(mockRegionAttributes.getAsyncEventQueueIds()).thenReturn(asyncEventQueueIds);
|
||||
|
||||
when(mockRegionAttributes.getCacheListeners())
|
||||
.thenAnswer(newGetter(() -> cacheListeners.toArray(new CacheListener[cacheListeners.size()])));
|
||||
|
||||
when(mockRegionAttributes.getCacheLoader()).thenAnswer(newGetter(cacheLoader));
|
||||
when(mockRegionAttributes.getCacheWriter()).thenAnswer(newGetter(cacheWriter));
|
||||
when(mockRegionAttributes.getCloningEnabled()).thenAnswer(newGetter(cloningEnabled));
|
||||
when(mockRegionAttributes.getCompressor()).thenAnswer(newGetter(compressor));
|
||||
when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenAnswer(newGetter(concurrencyChecksEnabled));
|
||||
when(mockRegionAttributes.getConcurrencyLevel()).thenAnswer(newGetter(concurrencyLevel));
|
||||
when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenAnswer(newGetter(customEntryIdleTimeout));
|
||||
when(mockRegionAttributes.getCustomEntryTimeToLive()).thenAnswer(newGetter(customEntryTimeToLive));
|
||||
when(mockRegionAttributes.getDataPolicy()).thenAnswer(newGetter(dataPolicy));
|
||||
when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(diskStoreName));
|
||||
when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous));
|
||||
when(mockRegionAttributes.getEnableAsyncConflation()).thenAnswer(newGetter(enableAsyncConflation));
|
||||
when(mockRegionAttributes.getEnableSubscriptionConflation()).thenAnswer(newGetter(enableSubscriptionConflation));
|
||||
when(mockRegionAttributes.getEntryIdleTimeout()).thenAnswer(newGetter(entryIdleTimeout));
|
||||
when(mockRegionAttributes.getEntryTimeToLive()).thenAnswer(newGetter(entryTimeToLive));
|
||||
when(mockRegionAttributes.getEvictionAttributes()).thenAnswer(newGetter(evictionAttributes));
|
||||
when(mockRegionAttributes.getGatewaySenderIds()).thenReturn(gatewaySenderIds);
|
||||
when(mockRegionAttributes.getIgnoreJTA()).thenAnswer(newGetter(ignoreJta));
|
||||
when(mockRegionAttributes.getIndexMaintenanceSynchronous()).thenAnswer(newGetter(indexMaintenanceSynchronous));
|
||||
when(mockRegionAttributes.getInitialCapacity()).thenAnswer(newGetter(initialCapacity));
|
||||
when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(keyConstraint));
|
||||
when(mockRegionAttributes.getLoadFactor()).thenAnswer(newGetter(loadFactor));
|
||||
when(mockRegionAttributes.isLockGrantor()).thenAnswer(newGetter(lockGrantor));
|
||||
when(mockRegionAttributes.getMulticastEnabled()).thenAnswer(newGetter(multicastEnabled));
|
||||
when(mockRegionAttributes.getOffHeap()).thenAnswer(newGetter(offHeap));
|
||||
when(mockRegionAttributes.getPartitionAttributes()).thenAnswer(newGetter(partitionAttributes));
|
||||
when(mockRegionAttributes.getPoolName()).thenAnswer(newGetter(poolName));
|
||||
when(mockRegionAttributes.getRegionIdleTimeout()).thenAnswer(newGetter(regionIdleTimeout));
|
||||
when(mockRegionAttributes.getRegionTimeToLive()).thenAnswer(newGetter(regionTimeToLive));
|
||||
when(mockRegionAttributes.getScope()).thenAnswer(newGetter(scope));
|
||||
when(mockRegionAttributes.getStatisticsEnabled()).thenAnswer(newGetter(statisticsEnabled));
|
||||
when(mockRegionAttributes.getSubscriptionAttributes()).thenAnswer(newGetter(subscriptionAttributes));
|
||||
when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(valueConstraint));
|
||||
|
||||
when(mockRegionFactory.create(anyString())).thenAnswer(invocation ->
|
||||
mockRegion(mockCache, invocation.getArgument(0), mockRegionAttributes));
|
||||
|
||||
when(mockRegionFactory.createSubregion(any(Region.class), anyString())).thenAnswer(invocation ->
|
||||
mockSubRegion(invocation.getArgument(0), invocation.getArgument(1), mockRegionAttributes));
|
||||
|
||||
return mockRegionFactory;
|
||||
}
|
||||
|
||||
public static ResourceManager mockResourceManager() {
|
||||
|
||||
ResourceManager mockResourceManager = mock(ResourceManager.class);
|
||||
@@ -1059,25 +1685,6 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
return mockResourceManager;
|
||||
}
|
||||
|
||||
private static <T extends GemFireCache> T rememberMockedGemFireCache(T mockedGemFireCache,
|
||||
boolean useSingletonCache) {
|
||||
|
||||
return Optional.ofNullable(mockedGemFireCache)
|
||||
.map(it -> {
|
||||
if (useSingletonCache) {
|
||||
singletonCache.compareAndSet(null, mockedGemFireCache);
|
||||
}
|
||||
|
||||
return mockedGemFireCache;
|
||||
})
|
||||
.orElseThrow(() -> newIllegalArgumentException("GemFireCache is required"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends GemFireCache> Optional<T> resolveMockedGemFireCache(boolean useSingletonCache) {
|
||||
return Optional.ofNullable((T) singletonCache.get()).filter(it -> useSingletonCache);
|
||||
}
|
||||
|
||||
public static CacheFactory spyOn(CacheFactory cacheFactory) {
|
||||
return spyOn(cacheFactory, DEFAULT_USE_SINGLETON_CACHE);
|
||||
}
|
||||
@@ -1291,4 +1898,8 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport {
|
||||
|
||||
return clientCacheFactorySpy;
|
||||
}
|
||||
|
||||
protected interface IoExceptionThrowingOperation {
|
||||
void doIo() throws IOException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.gemfire.test.mock;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -46,11 +47,11 @@ public abstract class MockObjectsSupport {
|
||||
|
||||
private static final String DEFAULT_MOCK_OBJECT_NAME = "MockObject";
|
||||
|
||||
protected static String mockObjectIdentifier() {
|
||||
public static String mockObjectIdentifier() {
|
||||
return mockObjectIdentifier(DEFAULT_MOCK_OBJECT_NAME);
|
||||
}
|
||||
|
||||
protected static String mockObjectIdentifier(String mockObjectName) {
|
||||
public static String mockObjectIdentifier(String mockObjectName) {
|
||||
return String.format("%s%d", Optional.ofNullable(mockObjectName).filter(StringUtils::hasText)
|
||||
.orElse(DEFAULT_MOCK_OBJECT_NAME), mockObjectIdentifier.incrementAndGet());
|
||||
}
|
||||
@@ -90,6 +91,14 @@ public abstract class MockObjectsSupport {
|
||||
return invocation -> converter.apply(returnValue.get());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static <E, C extends Collection<E>, R> Answer<R> newAdder(C collection, R returnValue) {
|
||||
return invocation -> {
|
||||
collection.add(invocation.getArgument(0));
|
||||
return returnValue;
|
||||
};
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected static <R> Answer<R> newSetter(AtomicBoolean argument, R returnValue) {
|
||||
return invocation -> {
|
||||
|
||||
Reference in New Issue
Block a user