diff --git a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java index dafbfabe..1bfbe1f6 100644 --- a/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/PartitionedRegionFactoryBean.java @@ -28,9 +28,10 @@ public class PartitionedRegionFactoryBean extends RegionFactoryBean @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, DataPolicy dataPolicy) { + // First, verify the GemFire version is 6.5 or Higher when Persistence is specified... Assert.isTrue(!DataPolicy.PERSISTENT_PARTITION.equals(dataPolicy) || GemfireUtils.isGemfireVersion65OrAbove(), - String.format("Persistent PARTITION Regions can only be used from GemFire 6.5 onwards; current version is [%1$s].", + String.format("Persistent PARTITION Regions can only be used from GemFire 6.5 onwards; current version is [%s].", CacheFactory.getVersion())); if (dataPolicy == null) { @@ -52,6 +53,7 @@ public class PartitionedRegionFactoryBean extends RegionFactoryBean @Override protected void resolveDataPolicy(RegionFactory regionFactory, Boolean persistent, String dataPolicy) { + DataPolicy resolvedDataPolicy = null; if (dataPolicy != null) { @@ -61,5 +63,4 @@ public class PartitionedRegionFactoryBean extends RegionFactoryBean resolveDataPolicy(regionFactory, persistent, resolvedDataPolicy); } - } diff --git a/src/main/java/org/springframework/data/gemfire/RegionAttributesFactoryBean.java b/src/main/java/org/springframework/data/gemfire/RegionAttributesFactoryBean.java index f7994713..31fe7aec 100644 --- a/src/main/java/org/springframework/data/gemfire/RegionAttributesFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/RegionAttributesFactoryBean.java @@ -57,7 +57,7 @@ public class RegionAttributesFactoryBean extends AttributesFactory return true; } - public void setIndexUpdateType(final IndexMaintenancePolicyType indexUpdateType) { + public void setIndexUpdateType(IndexMaintenancePolicyType indexUpdateType) { indexUpdateType.setIndexMaintenance(this); } } diff --git a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java index 17e6b262..e9913553 100644 --- a/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/RegionFactoryBean.java @@ -338,7 +338,7 @@ public abstract class RegionFactoryBean extends RegionLookupFactoryBean postProcess(RegionFactory regionFactory) { - regionFactory.setOffHeap(Boolean.TRUE.equals(this.offHeap)); + Optional.ofNullable(this.offHeap).ifPresent(regionFactory::setOffHeap); return regionFactory; } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java index f0884198..5ec34b80 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractRegionParser.java @@ -91,11 +91,9 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { doParseRegion(element, parserContext, builder, isSubRegion(element)); } - /* (non-Javadoc) */ protected abstract void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, boolean subRegion); - /* (non-Javadoc) */ protected void doParseRegionConfiguration(Element element, ParserContext parserContext, BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder, boolean subRegion) { @@ -156,7 +154,6 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { } } - /* (non-Javadoc) */ void mergeRegionTemplateAttributes(Element element, ParserContext parserContext, BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder) { @@ -164,6 +161,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { if (StringUtils.hasText(regionTemplateName)) { if (parserContext.getRegistry().containsBeanDefinition(regionTemplateName)) { + BeanDefinition templateRegion = parserContext.getRegistry().getBeanDefinition(regionTemplateName); BeanDefinition templateRegionAttributes = getRegionAttributesBeanDefinition(templateRegion); @@ -183,8 +181,8 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { } } - /* (non-Javadoc) */ BeanDefinition getRegionAttributesBeanDefinition(BeanDefinition region) { + Assert.notNull(region, "BeanDefinition must not be null"); Object regionAttributes = null; @@ -197,14 +195,14 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { return (regionAttributes instanceof BeanDefinition ? (BeanDefinition) regionAttributes : null); } - /* (non-Javadoc) */ protected void parseCollectionOfCustomSubElements(Element element, ParserContext parserContext, BeanDefinitionBuilder builder, String className, String subElementName, String propertyName) { - List subElements = DomUtils.getChildElementsByTagName( - element, subElementName, subElementName + "-ref"); + List subElements = + DomUtils.getChildElementsByTagName(element, subElementName, subElementName + "-ref"); if (!CollectionUtils.isEmpty(subElements)) { + ManagedArray array = new ManagedArray(className, subElements.size()); for (Element subElement : subElements) { @@ -215,9 +213,9 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { } } - /* (non-Javadoc) */ protected void parseSubRegions(Element element, ParserContext parserContext, String resolvedCacheRef) { - Map allSubRegionElements = new HashMap(); + + Map allSubRegionElements = new HashMap<>(); findSubRegionElements(element, getRegionNameFromElement(element), allSubRegionElements); @@ -228,30 +226,36 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { } } - /* (non-Javadoc) */ private void findSubRegionElements(Element parent, String parentPath, Map allSubRegionElements) { + for (Element element : DomUtils.getChildElements(parent)) { if (element.getLocalName().endsWith("region")) { + String subRegionName = getRegionNameFromElement(element); String subRegionPath = buildSubRegionPath(parentPath, subRegionName); + allSubRegionElements.put(subRegionPath, element); + findSubRegionElements(element, subRegionPath, allSubRegionElements); } } } - /* (non-Javadoc) */ private String getRegionNameFromElement(Element element) { + String name = element.getAttribute(NAME_ATTRIBUTE); + return (StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE)); } - /* (non-Javadoc) */ private String buildSubRegionPath(String parentName, String regionName) { + String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName, regionName }, "/"); + if (!regionPath.startsWith("/")) { regionPath = "/" + regionPath; } + return regionPath; } @@ -276,16 +280,21 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { /* (non-Javadoc) */ private String getParentRegionPathFrom(String regionPath) { + int index = regionPath.lastIndexOf("/"); + String parentPath = regionPath.substring(0, index); + if (parentPath.lastIndexOf("/") == 0) { parentPath = parentPath.substring(1); } + return parentPath; } /* (non-Javadoc) */ protected void validateDataPolicyShortcutAttributesMutualExclusion(Element element, ParserContext parserContext) { + if (element.hasAttribute("data-policy") && element.hasAttribute("shortcut")) { parserContext.getReaderContext().error(String.format( "Only one of [data-policy, shortcut] may be specified with element '%1$s'.", element.getTagName()), diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/PartitionedRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/PartitionedRegionParser.java index aff24927..0a359987 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/PartitionedRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/PartitionedRegionParser.java @@ -63,15 +63,15 @@ class PartitionedRegionParser extends AbstractRegionParser { validateDataPolicyShortcutAttributesMutualExclusion(element, parserContext); - BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( - RegionAttributesFactoryBean.class); + BeanDefinitionBuilder regionAttributesBuilder = + BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class); doParseRegionConfiguration(element, parserContext, regionBuilder, regionAttributesBuilder, subRegion); regionBuilder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition()); - BeanDefinitionBuilder partitionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( - PartitionAttributesFactoryBean.class); + BeanDefinitionBuilder partitionAttributesBuilder = + BeanDefinitionBuilder.genericBeanDefinition(PartitionAttributesFactoryBean.class); mergeTemplateRegionPartitionAttributes(element, parserContext, regionBuilder, partitionAttributesBuilder); @@ -83,13 +83,6 @@ class PartitionedRegionParser extends AbstractRegionParser { ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "total-buckets", "totalNumBuckets"); ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "total-max-memory"); - Element partitionResolverSubElement = DomUtils.getChildElementByTagName(element, "partition-resolver"); - - if (partitionResolverSubElement != null) { - partitionAttributesBuilder.addPropertyValue("partitionResolver", - parsePartitionResolver(partitionResolverSubElement, parserContext, regionBuilder)); - } - Element partitionListenerSubElement = DomUtils.getChildElementByTagName(element, "partition-listener"); if (partitionListenerSubElement != null) { @@ -97,18 +90,29 @@ class PartitionedRegionParser extends AbstractRegionParser { parsePartitionListeners(partitionListenerSubElement, parserContext, regionBuilder)); } + Element partitionResolverSubElement = DomUtils.getChildElementByTagName(element, "partition-resolver"); + + if (partitionResolverSubElement != null) { + partitionAttributesBuilder.addPropertyValue("partitionResolver", + parsePartitionResolver(partitionResolverSubElement, parserContext, regionBuilder)); + } + List fixedPartitionSubElements = DomUtils.getChildElementsByTagName(element, "fixed-partition"); if (!CollectionUtils.isEmpty(fixedPartitionSubElements)){ + @SuppressWarnings("rawtypes") ManagedList fixedPartitionAttributes = new ManagedList(); for (Element fixedPartition : fixedPartitionSubElements) { - BeanDefinitionBuilder fixedPartitionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( - FixedPartitionAttributesFactoryBean.class); + + BeanDefinitionBuilder fixedPartitionAttributesBuilder = + BeanDefinitionBuilder.genericBeanDefinition(FixedPartitionAttributesFactoryBean.class); + ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "partition-name"); ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "num-buckets"); ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "primary"); + fixedPartitionAttributes.add(fixedPartitionAttributesBuilder.getBeanDefinition()); } @@ -126,20 +130,22 @@ class PartitionedRegionParser extends AbstractRegionParser { if (StringUtils.hasText(regionTemplateName)) { if (parserContext.getRegistry().containsBeanDefinition(regionTemplateName)) { + BeanDefinition templateRegion = parserContext.getRegistry().getBeanDefinition(regionTemplateName); BeanDefinition templateRegionAttributes = getRegionAttributesBeanDefinition(templateRegion); if (templateRegionAttributes != null) { if (templateRegionAttributes.getPropertyValues().contains("partitionAttributes")) { + PropertyValue partitionAttributesProperty = templateRegionAttributes.getPropertyValues() .getPropertyValue("partitionAttributes"); Object partitionAttributes = partitionAttributesProperty.getValue(); if (partitionAttributes instanceof BeanDefinition) { - partitionAttributesBuilder.getRawBeanDefinition().overrideFrom( - (BeanDefinition) partitionAttributes); + partitionAttributesBuilder.getRawBeanDefinition() + .overrideFrom((BeanDefinition) partitionAttributes); } } } @@ -155,6 +161,7 @@ class PartitionedRegionParser extends AbstractRegionParser { /* (non-Javadoc) */ private void parseColocatedWith(Element element, BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder partitionAttributesBuilder, String attributeName) { + // NOTE rather than using a dependency (with depends-on) we could also set the colocatedWith property of the // PartitionAttributesFactoryBean with a reference to the Region "this" Partitioned Region will be colocated // with, where the colocated-with attribute refers to the the bean name/alias of the other, depended on Region diff --git a/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java index 045e66ad..52da077c 100644 --- a/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/client/SpELExpressionConfiguredPoolsIntegrationTests.java @@ -37,7 +37,7 @@ import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.data.gemfire.support.ConnectionEndpoint; import org.springframework.data.gemfire.support.ConnectionEndpointList; -import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport; +import org.springframework.data.gemfire.test.mock.GemFireMockObjectsSupport; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -217,7 +217,7 @@ public class SpELExpressionConfiguredPoolsIntegrationTests { @Override protected PoolFactory createPoolFactory() { - PoolFactory mockPoolFactory = MockGemFireObjectsSupport.mockPoolFactory(); + PoolFactory mockPoolFactory = GemFireMockObjectsSupport.mockPoolFactory(); when(mockPoolFactory.addLocator(anyString(), anyInt())).thenAnswer(invocation -> { String host = invocation.getArgument(0); diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegionsUnitTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegionsUnitTests.java index 29df9d66..9dc5cda3 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegionsUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegionsUnitTests.java @@ -51,7 +51,7 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport; +import org.springframework.data.gemfire.test.mock.GemFireMockObjectsSupport; import org.springframework.data.gemfire.test.support.MapBuilder; import org.springframework.stereotype.Service; @@ -78,7 +78,7 @@ public class EnableCachingDefinedRegionsUnitTests { @Before public void setup() { this.configuration = new CachingDefinedRegionsConfiguration(); - MockGemFireObjectsSupport.destroy(); + GemFireMockObjectsSupport.destroy(); } @Test @@ -189,7 +189,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); when(mockBeanFactory.containsBean(anyString())).thenReturn(false); when(mockBeanFactory.getBean(eq(GemFireCache.class))).thenReturn(mockGemFireCache); @@ -213,7 +213,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -244,7 +244,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -280,7 +280,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -317,7 +317,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -363,7 +363,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -398,7 +398,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); @@ -432,7 +432,7 @@ public class EnableCachingDefinedRegionsUnitTests { ConfigurableBeanFactory mockBeanFactory = mock(ConfigurableBeanFactory.class); - GemFireCache mockGemFireCache = MockGemFireObjectsSupport.mockClientCache(); + GemFireCache mockGemFireCache = GemFireMockObjectsSupport.mockClientCache(); Set registeredBeanNames = new HashSet<>(); diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableContinuousQueriesConfigurationUnitTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableContinuousQueriesConfigurationUnitTests.java index 16f958a6..df7b3873 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableContinuousQueriesConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableContinuousQueriesConfigurationUnitTests.java @@ -57,7 +57,7 @@ import org.springframework.data.gemfire.listener.annotation.ContinuousQuery; import org.springframework.data.gemfire.mapping.GemfireMappingContext; import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories; import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean; -import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport; +import org.springframework.data.gemfire.test.mock.GemFireMockObjectsSupport; import org.springframework.data.gemfire.test.mock.annotation.EnableGemFireMockObjects; import org.springframework.data.gemfire.test.model.Person; import org.springframework.data.gemfire.test.repo.PersonRepository; @@ -255,7 +255,7 @@ public class EnableContinuousQueriesConfigurationUnitTests { Region mockPeopleRegion(GemFireCache gemfireCache, @Qualifier("peopleRegionAttributes") RegionAttributes peopleRegionAttributes) { - return MockGemFireObjectsSupport.mockRegion(gemfireCache, "People", peopleRegionAttributes); + return GemFireMockObjectsSupport.mockRegion(gemfireCache, "People", peopleRegionAttributes); } @Bean @@ -274,7 +274,7 @@ public class EnableContinuousQueriesConfigurationUnitTests { Region mockExamplesRegion(GemFireCache gemfireCache, @Qualifier("examplesRegionAttributes") RegionAttributes mockExamplesRegionAttributes) { - return MockGemFireObjectsSupport.mockRegion(gemfireCache, "Examples", + return GemFireMockObjectsSupport.mockRegion(gemfireCache, "Examples", mockExamplesRegionAttributes); } diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/LocalRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/LocalRegionNamespaceTest.java index 9896ea5c..6d763a9d 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/LocalRegionNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/LocalRegionNamespaceTest.java @@ -38,7 +38,7 @@ import org.springframework.data.gemfire.RegionFactoryBean; import org.springframework.data.gemfire.RegionLookupFactoryBean; import org.springframework.data.gemfire.SimpleCacheListener; import org.springframework.data.gemfire.TestUtils; -import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; +import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.ObjectUtils; @@ -54,7 +54,8 @@ import org.springframework.util.ObjectUtils; * @see org.springframework.data.gemfire.config.xml.LocalRegionParser */ @RunWith(SpringRunner.class) -@ContextConfiguration(locations="local-ns.xml", initializers=GemfireTestApplicationContextInitializer.class) +@ContextConfiguration(locations="local-ns.xml", + initializers = GemFireMockObjectsApplicationContextInitializer.class) public class LocalRegionNamespaceTest { @Autowired @@ -142,7 +143,9 @@ public class LocalRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testRegionLookup() throws Exception { + Cache cache = applicationContext.getBean(Cache.class); + Region existing = cache.createRegionFactory().create("existing"); assertTrue(applicationContext.containsBean("lookup")); @@ -156,6 +159,7 @@ public class LocalRegionNamespaceTest { @Test @SuppressWarnings("rawtypes") public void testLocalPersistent() { + Region persistentLocalRegion = applicationContext.getBean("persistent", Region.class); assertNotNull("The 'persistent' Local Region was not properly configured and initialized!", persistentLocalRegion); @@ -170,6 +174,7 @@ public class LocalRegionNamespaceTest { @Test public void testCompressedLocalRegion() { + assertTrue(applicationContext.containsBean("Compressed")); Region compressed = applicationContext.getBean("Compressed", Region.class); @@ -207,5 +212,4 @@ public class LocalRegionNamespaceTest { return this.name; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/PartitionedRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/PartitionedRegionNamespaceTest.java index 91fcb499..4e44def0 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/PartitionedRegionNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/PartitionedRegionNamespaceTest.java @@ -16,9 +16,11 @@ package org.springframework.data.gemfire.config.xml; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -43,7 +45,7 @@ import org.springframework.data.gemfire.RegionFactoryBean; import org.springframework.data.gemfire.SimpleCacheListener; import org.springframework.data.gemfire.SimplePartitionResolver; import org.springframework.data.gemfire.TestUtils; -import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; +import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.ObjectUtils; @@ -59,7 +61,8 @@ import org.springframework.util.ObjectUtils; * @see org.springframework.data.gemfire.config.xml.PartitionedRegionParser */ @RunWith(SpringRunner.class) -@ContextConfiguration(locations = "partitioned-ns.xml", initializers = GemfireTestApplicationContextInitializer.class) +@ContextConfiguration(locations = "partitioned-ns.xml", + initializers = GemFireMockObjectsApplicationContextInitializer.class) @SuppressWarnings("unused") public class PartitionedRegionNamespaceTest { @@ -85,14 +88,22 @@ public class PartitionedRegionNamespaceTest { public void testOptionsPartitionRegion() throws Exception { assertTrue(applicationContext.containsBean("options")); + assertTrue(applicationContext.containsBean("redundant")); + + Region options = applicationContext.getBean("options", Region.class); + + assertThat(options).isNotNull(); + assertThat(options.getAttributes()).isNotNull(); + assertThat(options.getName()).isEqualTo("redundant"); + assertThat(options.getAttributes().getOffHeap()).isTrue(); RegionFactoryBean optionsRegionFactoryBean = applicationContext.getBean("&options", RegionFactoryBean.class); assertTrue(optionsRegionFactoryBean instanceof PartitionedRegionFactoryBean); - assertEquals(null, TestUtils.readField("scope", optionsRegionFactoryBean)); + assertNull(TestUtils.readField("scope", optionsRegionFactoryBean)); assertEquals("redundant", TestUtils.readField("name", optionsRegionFactoryBean)); - RegionAttributes optionsRegionAttributes = TestUtils.readField("attributes", optionsRegionFactoryBean); + RegionAttributes optionsRegionAttributes = optionsRegionFactoryBean.getAttributes(); assertNotNull(optionsRegionAttributes); assertTrue(optionsRegionAttributes.getOffHeap()); @@ -265,5 +276,4 @@ public class PartitionedRegionNamespaceTest { return this.name; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java index 56f39185..19b8950a 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionNamespaceTest.java @@ -40,9 +40,9 @@ import org.springframework.data.gemfire.RegionLookupFactoryBean; import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; import org.springframework.data.gemfire.SimpleCacheListener; import org.springframework.data.gemfire.TestUtils; -import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer; +import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.ObjectUtils; /** @@ -55,8 +55,9 @@ import org.springframework.util.ObjectUtils; * @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean * @see org.springframework.data.gemfire.config.xml.ReplicatedRegionParser */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="replicated-ns.xml", initializers=GemfireTestApplicationContextInitializer.class) +@RunWith(SpringRunner.class) +@ContextConfiguration(locations = "replicated-ns.xml", + initializers = GemFireMockObjectsApplicationContextInitializer.class) @SuppressWarnings("unused") public class ReplicatedRegionNamespaceTest { @@ -78,6 +79,7 @@ public class ReplicatedRegionNamespaceTest { assertNotNull(simpleRegionAttributes); assertFalse(simpleRegionAttributes.getConcurrencyChecksEnabled()); + assertEquals(13, simpleRegionAttributes.getConcurrencyLevel()); assertEquals(Scope.DISTRIBUTED_NO_ACK, simpleRegionAttributes.getScope()); } diff --git a/src/test/java/org/springframework/data/gemfire/test/mock/MockGemFireObjectsSupport.java b/src/test/java/org/springframework/data/gemfire/test/mock/GemFireMockObjectsSupport.java similarity index 70% rename from src/test/java/org/springframework/data/gemfire/test/mock/MockGemFireObjectsSupport.java rename to src/test/java/org/springframework/data/gemfire/test/mock/GemFireMockObjectsSupport.java index 754dceb4..be220ba4 100644 --- a/src/test/java/org/springframework/data/gemfire/test/mock/MockGemFireObjectsSupport.java +++ b/src/test/java/org/springframework/data/gemfire/test/mock/GemFireMockObjectsSupport.java @@ -30,6 +30,7 @@ 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.asSet; 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; @@ -52,6 +53,7 @@ import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -60,6 +62,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; +import org.apache.geode.cache.AttributesMutator; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.CacheListener; @@ -70,6 +73,7 @@ import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.DiskStore; import org.apache.geode.cache.DiskStoreFactory; import org.apache.geode.cache.EvictionAttributes; +import org.apache.geode.cache.EvictionAttributesMutator; import org.apache.geode.cache.ExpirationAction; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.GemFireCache; @@ -82,6 +86,9 @@ 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.asyncqueue.AsyncEventListener; +import org.apache.geode.cache.asyncqueue.AsyncEventQueue; +import org.apache.geode.cache.asyncqueue.AsyncEventQueueFactory; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.ClientRegionFactory; @@ -92,11 +99,20 @@ import org.apache.geode.cache.control.ResourceManager; import org.apache.geode.cache.execute.RegionFunctionContext; import org.apache.geode.cache.query.CqAttributes; import org.apache.geode.cache.query.CqQuery; +import org.apache.geode.cache.query.Index; +import org.apache.geode.cache.query.IndexStatistics; import org.apache.geode.cache.query.Query; import org.apache.geode.cache.query.QueryService; 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.cache.wan.GatewayEventFilter; +import org.apache.geode.cache.wan.GatewayEventSubstitutionFilter; +import org.apache.geode.cache.wan.GatewayReceiver; +import org.apache.geode.cache.wan.GatewayReceiverFactory; +import org.apache.geode.cache.wan.GatewaySender; +import org.apache.geode.cache.wan.GatewaySenderFactory; +import org.apache.geode.cache.wan.GatewayTransportFilter; import org.apache.geode.compression.Compressor; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DistributedSystem; @@ -104,12 +120,14 @@ import org.apache.geode.internal.concurrent.ConcurrentHashSet; import org.apache.geode.pdx.PdxSerializer; import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; +import org.springframework.data.gemfire.IndexType; import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy; import org.springframework.data.gemfire.test.mock.support.MockObjectInvocationException; import org.springframework.data.gemfire.test.support.FileSystemUtils; +import org.springframework.util.Assert; /** - * The {@link MockGemFireObjectsSupport} class is an abstract base class encapsulating factory methods for creating + * The {@link GemFireMockObjectsSupport} class is an abstract base class encapsulating factory methods for creating * Mock GemFire Objects (e.g. {@link Cache}, {@link ClientCache}, {@link Region}, etc). * * @author John Blum @@ -128,8 +146,8 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils; * @see org.springframework.data.gemfire.test.mock.MockObjectsSupport * @since 2.0.0 */ -@SuppressWarnings("unused") -public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { +@SuppressWarnings("all") +public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { private static final boolean DEFAULT_USE_SINGLETON_CACHE = false; @@ -246,8 +264,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { * @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 + * @see IOException */ private static boolean doSafeIo(IoExceptionThrowingOperation operation) { @@ -280,7 +297,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { * is a root {@link Region}. */ private static boolean isRootRegion(String regionPath) { - return (regionPath.lastIndexOf(Region.SEPARATOR) <= 0); + return regionPath.lastIndexOf(Region.SEPARATOR) <= 0; } /** @@ -296,7 +313,8 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { regionPath = regionPath.replaceAll(REPEATING_REGION_SEPARATOR, Region.SEPARATOR); regionPath = regionPath.endsWith(Region.SEPARATOR) - ? regionPath.substring(0, regionPath.length() - 1) : regionPath; + ? regionPath.substring(0, regionPath.length() - 1) + : regionPath; return regionPath; } @@ -389,7 +407,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { * @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 + * @see String */ private static String toRegionName(String regionName) { @@ -410,14 +428,14 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { * @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 + * @see String */ private static String toRegionPath(String regionPath) { return Optional.ofNullable(regionPath) .map(String::trim) .map(it -> it.startsWith(Region.SEPARATOR) ? it : String.format("%1$s%2$s", Region.SEPARATOR, it)) - .map(MockGemFireObjectsSupport::normalizeRegionPath) + .map(GemFireMockObjectsSupport::normalizeRegionPath) .filter(it -> !it.isEmpty()) .orElseThrow(() -> newIllegalArgumentException("Region path [%s] is required", regionPath)); } @@ -453,8 +471,8 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { when(mockGemFireCache.listRegionAttributes()).thenReturn(Collections.unmodifiableMap(regionAttributes)); - doThrow(newUnsupportedOperationException(NOT_SUPPORTED)).when(mockGemFireCache) - .loadCacheXml(any(InputStream.class)); + doThrow(newUnsupportedOperationException(NOT_SUPPORTED)) + .when(mockGemFireCache).loadCacheXml(any(InputStream.class)); return mockRegionServiceApi(mockGemFireCache); } @@ -477,7 +495,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { String resolvedRegionPath = Optional.ofNullable(regionPath) .map(String::trim) .filter(it -> !it.isEmpty()) - .map(MockGemFireObjectsSupport::toRegionPath) + .map(GemFireMockObjectsSupport::toRegionPath) .orElseThrow(() -> newIllegalArgumentException("Region path [%s] is not valid", regionPath)); return regions.get(resolvedRegionPath); @@ -490,7 +508,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { .thenThrow(newUnsupportedOperationException(NOT_SUPPORTED)); when(mockRegionService.rootRegions()).thenAnswer(invocation -> - regions.values().stream().filter(MockGemFireObjectsSupport::isRootRegion).collect(Collectors.toSet())); + regions.values().stream().filter(GemFireMockObjectsSupport::isRootRegion).collect(Collectors.toSet())); return mockRegionService; } @@ -562,7 +580,124 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { when(mockCache.createRegionFactory(anyString())).thenAnswer(invocation -> mockRegionFactory(mockCache, invocation.getArgument(0))); - return mockQueryService(mockCacheApi(mockCache)); + return mockQueryService( + mockGatewaySenderFactory( + mockGatewayReceiverFactory( + mockAsyncEventQueueFactory( + mockCacheApi(mockCache))))); + } + + public static Cache mockAsyncEventQueueFactory(Cache mockCache) { + + when(mockCache.createAsyncEventQueueFactory()).thenAnswer(invocation -> mockAsyncEventQueueFactory()); + + return mockCache; + } + + public static AsyncEventQueueFactory mockAsyncEventQueueFactory() { + + AsyncEventQueueFactory mockAsyncEventQueueFactory = mock(AsyncEventQueueFactory.class); + + AtomicBoolean batchConflationEnabled = new AtomicBoolean(false); + AtomicBoolean diskSynchronous = new AtomicBoolean(true); + AtomicBoolean forwardExpirationDestroy = new AtomicBoolean(false); + AtomicBoolean parallel = new AtomicBoolean(false); + AtomicBoolean persistent = new AtomicBoolean(false); + + AtomicInteger batchSize = new AtomicInteger(100); + AtomicInteger batchTimeInterval = new AtomicInteger(5); + AtomicInteger dispatcherThreads = new AtomicInteger(5); + AtomicInteger maximumQueueMemory = new AtomicInteger(100); + + AtomicReference diskStoreName = new AtomicReference<>(null); + AtomicReference gatewayEventSubstitutionFilter = + new AtomicReference<>(null); + AtomicReference orderPolicy = new AtomicReference<>(GatewaySender.OrderPolicy.KEY); + + CopyOnWriteArrayList gatewayEventFilters = new CopyOnWriteArrayList<>(); + + when(mockAsyncEventQueueFactory.setBatchConflationEnabled(anyBoolean())) + .thenAnswer(newSetter(batchConflationEnabled, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setBatchSize(anyInt())) + .thenAnswer(newSetter(batchSize, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setBatchTimeInterval(anyInt())) + .thenAnswer(newSetter(batchTimeInterval, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setDiskStoreName(anyString())) + .thenAnswer(newSetter(diskStoreName, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setDiskSynchronous(anyBoolean())) + .thenAnswer(newSetter(diskSynchronous, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setDispatcherThreads(anyInt())) + .thenAnswer(newSetter(dispatcherThreads, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setForwardExpirationDestroy(anyBoolean())) + .thenAnswer(newSetter(forwardExpirationDestroy, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setGatewayEventSubstitutionListener(any(GatewayEventSubstitutionFilter.class))) + .thenAnswer(newSetter(gatewayEventSubstitutionFilter, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setMaximumQueueMemory(anyInt())) + .thenAnswer(newSetter(maximumQueueMemory, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setOrderPolicy(any(GatewaySender.OrderPolicy.class))) + .thenAnswer(newSetter(orderPolicy, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setParallel(anyBoolean())) + .thenAnswer(newSetter(parallel, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.setPersistent(anyBoolean())) + .thenAnswer(newSetter(persistent, mockAsyncEventQueueFactory)); + + when(mockAsyncEventQueueFactory.addGatewayEventFilter(any(GatewayEventFilter.class))).thenAnswer(invocation -> { + + gatewayEventFilters.add(invocation.getArgument(0)); + + return mockAsyncEventQueueFactory; + }); + + when(mockAsyncEventQueueFactory.removeGatewayEventFilter(any(GatewayEventFilter.class))).thenAnswer(invocation -> { + + gatewayEventFilters.remove(invocation.getArgument(0)); + + return mockAsyncEventQueueFactory; + }); + + when(mockAsyncEventQueueFactory.create(anyString(), any(AsyncEventListener.class))).thenAnswer(invocation -> { + + String asyncEventQueueId = invocation.getArgument(0); + + AsyncEventListener listener = invocation.getArgument(1); + + AsyncEventQueue mockAsyncEventQueue = mock(AsyncEventQueue.class); + + when(mockAsyncEventQueue.isBatchConflationEnabled()).thenAnswer(newGetter(batchConflationEnabled)); + when(mockAsyncEventQueue.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous)); + when(mockAsyncEventQueue.isForwardExpirationDestroy()).thenAnswer(newGetter(forwardExpirationDestroy)); + when(mockAsyncEventQueue.isParallel()).thenAnswer(newGetter(parallel)); + when(mockAsyncEventQueue.isPersistent()).thenAnswer(newGetter(persistent)); + when(mockAsyncEventQueue.isPrimary()).thenReturn(false); + + when(mockAsyncEventQueue.getAsyncEventListener()).thenReturn(listener); + when(mockAsyncEventQueue.getBatchSize()).thenAnswer(newGetter(batchSize)); + when(mockAsyncEventQueue.getBatchTimeInterval()).thenAnswer(newGetter(batchTimeInterval)); + when(mockAsyncEventQueue.getDiskStoreName()).thenAnswer(newGetter(diskStoreName)); + when(mockAsyncEventQueue.getDispatcherThreads()).thenAnswer(newGetter(dispatcherThreads)); + when(mockAsyncEventQueue.getGatewayEventFilters()).thenReturn(gatewayEventFilters); + when(mockAsyncEventQueue.getGatewayEventSubstitutionFilter()).thenAnswer(newGetter(gatewayEventSubstitutionFilter)); + when(mockAsyncEventQueue.getId()).thenReturn(asyncEventQueueId); + when(mockAsyncEventQueue.getMaximumQueueMemory()).thenAnswer(newGetter(maximumQueueMemory)); + when(mockAsyncEventQueue.getOrderPolicy()).thenAnswer(newGetter(orderPolicy)); + + when(mockAsyncEventQueue.size()).thenReturn(0); + + return mockAsyncEventQueue; + }); + + return mockAsyncEventQueueFactory; } public static CacheServer mockCacheServer() { @@ -648,13 +783,13 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { } public static ClientRegionFactory mockClientRegionFactory(ClientCache mockClientCache, - ClientRegionShortcut clientRegionShortcut) { + ClientRegionShortcut clientRegionShortcut) { return mockClientRegionFactory(mockClientCache, clientRegionShortcut, null); } public static ClientRegionFactory mockClientRegionFactory(ClientCache mockClientCache, - String regionAttributesId) { + String regionAttributesId) { return mockClientRegionFactory(mockClientCache, null, resolveRegionAttributes(regionAttributesId)); @@ -662,7 +797,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { @SuppressWarnings("unchecked") public static ClientRegionFactory mockClientRegionFactory(ClientCache mockClientCache, - ClientRegionShortcut clientRegionShortcut, RegionAttributes regionAttributes) { + ClientRegionShortcut clientRegionShortcut, RegionAttributes regionAttributes) { ClientRegionFactory mockClientRegionFactory = mock(ClientRegionFactory.class, mockObjectIdentifier("MockClientRegionFactory")); @@ -712,7 +847,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { .map(RegionAttributes::getEntryTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES)); AtomicReference evictionAttributes = new AtomicReference<>(optionalRegionAttributes - .map(RegionAttributes::getEvictionAttributes).orElseGet(() -> EvictionAttributes.createLRUEntryAttributes())); + .map(RegionAttributes::getEvictionAttributes).orElseGet(EvictionAttributes::createLRUEntryAttributes)); AtomicReference> keyConstraint = new AtomicReference<>(optionalRegionAttributes .map(RegionAttributes::getKeyConstraint).orElse(null)); @@ -983,6 +1118,259 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { return mockDistributedSystem; } + public static Cache mockGatewayReceiverFactory(Cache mockCache) { + + when(mockCache.createGatewayReceiverFactory()).thenAnswer(invocation -> mockGatewayReceiverFactory()); + + return mockCache; + } + + public static GatewayReceiverFactory mockGatewayReceiverFactory() { + + GatewayReceiverFactory mockGatewayReceiverFactory = mock(GatewayReceiverFactory.class); + + AtomicBoolean manualStart = new AtomicBoolean(GatewayReceiver.DEFAULT_MANUAL_START); + + AtomicInteger endPort = new AtomicInteger(GatewayReceiver.DEFAULT_END_PORT); + AtomicInteger maximumTimeBetweenPings = new AtomicInteger(GatewayReceiver.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS); + AtomicInteger socketBufferSize = new AtomicInteger(GatewayReceiver.DEFAULT_SOCKET_BUFFER_SIZE); + AtomicInteger startPort = new AtomicInteger(GatewayReceiver.DEFAULT_START_PORT); + + AtomicReference bindAddress = new AtomicReference<>(GatewayReceiver.DEFAULT_BIND_ADDRESS); + AtomicReference hostnameForSenders = new AtomicReference<>(GatewayReceiver.DEFAULT_HOSTNAME_FOR_SENDERS); + + CopyOnWriteArrayList gatewayTransportFilters = new CopyOnWriteArrayList<>(); + + when(mockGatewayReceiverFactory.setBindAddress(anyString())) + .thenAnswer(newSetter(bindAddress, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setEndPort(anyInt())) + .thenAnswer(newSetter(endPort, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setHostnameForSenders(anyString())) + .thenAnswer(newSetter(hostnameForSenders, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setManualStart(anyBoolean())) + .thenAnswer(newSetter(manualStart, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setMaximumTimeBetweenPings(anyInt())) + .thenAnswer(newSetter(maximumTimeBetweenPings, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setSocketBufferSize(anyInt())) + .thenAnswer(newSetter(socketBufferSize, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.setStartPort(anyInt())) + .thenAnswer(newSetter(startPort, mockGatewayReceiverFactory)); + + when(mockGatewayReceiverFactory.addGatewayTransportFilter(any(GatewayTransportFilter.class))).thenAnswer(invocation -> { + + gatewayTransportFilters.add(invocation.getArgument(0)); + + return mockGatewayReceiverFactory; + }); + + when(mockGatewayReceiverFactory.removeGatewayTransportFilter(any(GatewayTransportFilter.class))).thenAnswer(invocation -> { + + gatewayTransportFilters.remove(invocation.getArgument(0)); + + return mockGatewayReceiverFactory; + }); + + when(mockGatewayReceiverFactory.create()).thenAnswer(invocation -> { + + AtomicBoolean running = new AtomicBoolean(false); + + GatewayReceiver mockGatewayReceiver = mock(GatewayReceiver.class); + + when(mockGatewayReceiver.isManualStart()).thenAnswer(newGetter(manualStart)); + when(mockGatewayReceiver.isRunning()).thenAnswer(newGetter(running)); + + when(mockGatewayReceiver.getBindAddress()).thenAnswer(newGetter(bindAddress)); + when(mockGatewayReceiver.getEndPort()).thenAnswer(newGetter(endPort)); + when(mockGatewayReceiver.getGatewayTransportFilters()).thenReturn(gatewayTransportFilters); + when(mockGatewayReceiver.getHost()).thenAnswer(newGetter(hostnameForSenders)); + //when(mockGatewayReceiver.getHostnameForSenders()).thenAnswer(newGetter(hostnameForSenders)); + when(mockGatewayReceiver.getMaximumTimeBetweenPings()).thenAnswer(newGetter(maximumTimeBetweenPings)); + when(mockGatewayReceiver.getPort()).thenReturn(0); + when(mockGatewayReceiver.getSocketBufferSize()).thenAnswer(newGetter(socketBufferSize)); + when(mockGatewayReceiver.getStartPort()).thenAnswer(newGetter(startPort)); + + doAnswer(newSetter(running, true, null)).when(mockGatewayReceiver).start(); + doAnswer(newSetter(running, false, null)).when(mockGatewayReceiver).stop(); + + return mockGatewayReceiver; + }); + + return mockGatewayReceiverFactory; + } + + public static Cache mockGatewaySenderFactory(Cache mockCache) { + + when(mockCache.createGatewaySenderFactory()).thenAnswer(invocation -> mockGatewaySenderFactory()); + + return mockCache; + } + + public static GatewaySenderFactory mockGatewaySenderFactory() { + + GatewaySenderFactory mockGatewaySenderFactory = mock(GatewaySenderFactory.class); + + AtomicBoolean batchConflationEnabled = new AtomicBoolean(GatewaySender.DEFAULT_BATCH_CONFLATION); + AtomicBoolean diskSynchronous = new AtomicBoolean(GatewaySender.DEFAULT_DISK_SYNCHRONOUS); + AtomicBoolean parallel = new AtomicBoolean(GatewaySender.DEFAULT_IS_PARALLEL); + AtomicBoolean persistenceEnabled = new AtomicBoolean(GatewaySender.DEFAULT_PERSISTENCE_ENABLED); + + AtomicInteger alertThreshold = new AtomicInteger(GatewaySender.DEFAULT_ALERT_THRESHOLD); + AtomicInteger batchSize = new AtomicInteger(GatewaySender.DEFAULT_BATCH_SIZE); + AtomicInteger batchTimeInterval = new AtomicInteger(GatewaySender.DEFAULT_BATCH_TIME_INTERVAL); + AtomicInteger dispatcherThreads = new AtomicInteger(GatewaySender.DEFAULT_DISPATCHER_THREADS); + AtomicInteger maximumQueueMemory = new AtomicInteger(GatewaySender.DEFAULT_MAXIMUM_QUEUE_MEMORY); + AtomicInteger parallelFactorForReplicatedRegion = + new AtomicInteger(GatewaySender.DEFAULT_PARALLELISM_REPLICATED_REGION); + AtomicInteger socketBufferSize = new AtomicInteger(GatewaySender.DEFAULT_SOCKET_BUFFER_SIZE); + AtomicInteger socketReadTimeout = new AtomicInteger(GatewaySender.DEFAULT_SOCKET_READ_TIMEOUT); + + AtomicReference diskStoreName = new AtomicReference<>(null); + AtomicReference gatewayEventSubstitutionFilter = + new AtomicReference<>(null); + AtomicReference orderPolicy = new AtomicReference<>(GatewaySender.DEFAULT_ORDER_POLICY); + + CopyOnWriteArrayList gatewayEventFilters = new CopyOnWriteArrayList<>(); + CopyOnWriteArrayList gatewayTransportFilters = new CopyOnWriteArrayList<>(); + + when(mockGatewaySenderFactory.setAlertThreshold(anyInt())) + .thenAnswer(newSetter(alertThreshold, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setBatchConflationEnabled(anyBoolean())) + .thenAnswer(newSetter(batchConflationEnabled, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setBatchSize(anyInt())).thenAnswer(newSetter(batchSize, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setBatchTimeInterval(anyInt())) + .thenAnswer(newSetter(batchTimeInterval, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setDiskStoreName(anyString())) + .thenAnswer(newSetter(diskStoreName, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setDiskSynchronous(anyBoolean())) + .thenAnswer(newSetter(diskSynchronous, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setDispatcherThreads(anyInt())) + .thenAnswer(newSetter(dispatcherThreads, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setGatewayEventSubstitutionFilter(any(GatewayEventSubstitutionFilter.class))) + .thenAnswer(newSetter(gatewayEventSubstitutionFilter, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setMaximumQueueMemory(anyInt())) + .thenAnswer(newSetter(maximumQueueMemory, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setOrderPolicy(any(GatewaySender.OrderPolicy.class))) + .thenAnswer(newSetter(orderPolicy, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setParallel(anyBoolean())).thenAnswer(newSetter(parallel, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setParallelFactorForReplicatedRegion(anyInt())) + .thenAnswer(newSetter(parallelFactorForReplicatedRegion, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setPersistenceEnabled(anyBoolean())) + .thenAnswer(newSetter(persistenceEnabled, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setSocketBufferSize(anyInt())) + .thenAnswer(newSetter(socketBufferSize, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.setSocketReadTimeout(anyInt())) + .thenAnswer(newSetter(socketReadTimeout, mockGatewaySenderFactory)); + + when(mockGatewaySenderFactory.addGatewayEventFilter(any(GatewayEventFilter.class))).thenAnswer(invocation -> { + + gatewayEventFilters.add(invocation.getArgument(0)); + + return mockGatewaySenderFactory; + }); + + when(mockGatewaySenderFactory.addGatewayTransportFilter(any(GatewayTransportFilter.class))).thenAnswer(invocation -> { + + gatewayTransportFilters.add(invocation.getArgument(0)); + + return mockGatewaySenderFactory; + }); + + when(mockGatewaySenderFactory.removeGatewayEventFilter(any(GatewayEventFilter.class))).thenAnswer(invocation -> { + + gatewayEventFilters.remove(invocation.getArgument(0)); + + return mockGatewaySenderFactory; + }); + + when(mockGatewaySenderFactory.removeGatewayTransportFilter(any(GatewayTransportFilter.class))).thenAnswer(invocation -> { + + gatewayTransportFilters.remove(invocation.getArgument(0)); + + return mockGatewaySenderFactory; + }); + + when(mockGatewaySenderFactory.create(anyString(), anyInt())).thenAnswer(invocation -> { + + GatewaySender mockGatewaySender = mock(GatewaySender.class); + + AtomicBoolean destroyed = new AtomicBoolean(false); + AtomicBoolean running = new AtomicBoolean(false); + + Integer remoteDistributedSystemId = invocation.getArgument(1); + + String gatewaySenderId = invocation.getArgument(0); + + when(mockGatewaySender.isBatchConflationEnabled()).thenAnswer(newGetter(batchConflationEnabled)); + when(mockGatewaySender.isDiskSynchronous()).thenAnswer(newGetter(diskSynchronous)); + when(mockGatewaySender.isParallel()).thenAnswer(newGetter(parallel)); + when(mockGatewaySender.isPaused()).thenAnswer(newGetter(running)); + when(mockGatewaySender.isPersistenceEnabled()).thenAnswer(newGetter(persistenceEnabled)); + when(mockGatewaySender.isRunning()).thenAnswer(newGetter(running)); + + when(mockGatewaySender.getAlertThreshold()).thenAnswer(newGetter(alertThreshold)); + when(mockGatewaySender.getBatchSize()).thenAnswer(newGetter(batchSize)); + when(mockGatewaySender.getBatchTimeInterval()).thenAnswer(newGetter(batchTimeInterval)); + when(mockGatewaySender.getDiskStoreName()).thenAnswer(newGetter(diskStoreName)); + when(mockGatewaySender.getDispatcherThreads()).thenAnswer(newGetter(dispatcherThreads)); + when(mockGatewaySender.getGatewayEventFilters()).thenReturn(gatewayEventFilters); + when(mockGatewaySender.getGatewayEventSubstitutionFilter()).thenAnswer(newGetter(gatewayEventSubstitutionFilter)); + when(mockGatewaySender.getGatewayTransportFilters()).thenReturn(gatewayTransportFilters); + when(mockGatewaySender.getId()).thenReturn(gatewaySenderId); + when(mockGatewaySender.getMaximumQueueMemory()).thenAnswer(newGetter(maximumQueueMemory)); + when(mockGatewaySender.getMaxParallelismForReplicatedRegion()).thenAnswer(newGetter(parallelFactorForReplicatedRegion)); + when(mockGatewaySender.getOrderPolicy()).thenAnswer(newGetter(orderPolicy)); + when(mockGatewaySender.getRemoteDSId()).thenReturn(remoteDistributedSystemId); + when(mockGatewaySender.getSocketBufferSize()).thenAnswer(newGetter(socketBufferSize)); + when(mockGatewaySender.getSocketReadTimeout()).thenAnswer(newGetter(socketReadTimeout)); + + doAnswer(it -> { + + gatewayEventFilters.add(it.getArgument(0)); + + return null; + + }).when(mockGatewaySender).addGatewayEventFilter(any(GatewayEventFilter.class)); + + doAnswer(newSetter(destroyed, null)).when(mockGatewaySender).destroy(); + doAnswer(newSetter(running, false, null)).when(mockGatewaySender).pause(); + doAnswer(newSetter(running, true, null)).when(mockGatewaySender).resume(); + doAnswer(newSetter(running, true, null)).when(mockGatewaySender).start(); + doAnswer(newSetter(running, false, null)).when(mockGatewaySender).stop(); + + doAnswer(it -> { + + gatewayEventFilters.remove(it.getArgument(0)); + + return null; + + }).when(mockGatewaySender).removeGatewayEventFilter(any(GatewayEventFilter.class)); + + return mockGatewaySender; + }); + + return mockGatewaySenderFactory; + } + public static PoolFactory mockPoolFactory() { PoolFactory mockPoolFactory = mock(PoolFactory.class); @@ -1151,6 +1539,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { QueryService mockQueryService = mock(QueryService.class); Set cqQueries = new ConcurrentHashSet<>(); + Set indexes = new ConcurrentHashSet<>(); try { when(mockQueryService.getCqs()).thenAnswer(invocation -> cqQueries.toArray(new CqQuery[cqQueries.size()])); @@ -1182,6 +1571,47 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { return cqQueriesByRegion.toArray(new CqQuery[cqQueriesByRegion.size()]); }); + when(mockQueryService.getIndexes()).thenReturn(indexes); + + when(mockQueryService.getIndexes(any(Region.class))).thenAnswer(invocation -> { + + Region region = invocation.getArgument(0); + + return indexes.stream() + .filter(index -> index.getRegion().equals(region)) + .collect(Collectors.toList()); + + }); + + when(mockQueryService.getIndex(any(Region.class), anyString())).thenAnswer(invocation -> { + + Region region = invocation.getArgument(0); + + String indexName = invocation.getArgument(1); + + Collection indexesForRegion = mockQueryService.getIndexes(region); + + return indexesForRegion.stream() + .filter(index -> index.getName().equals(indexName)) + .findFirst().orElse(null); + + }); + + when(mockQueryService.createIndex(anyString(), anyString(), anyString())) + .thenAnswer(createIndexAnswer(indexes, IndexType.FUNCTIONAL)); + + when(mockQueryService.createIndex(anyString(), anyString(), anyString(), anyString())) + .thenAnswer(createIndexAnswer(indexes, IndexType.FUNCTIONAL)); + + when(mockQueryService.createHashIndex(anyString(), anyString(), anyString())) + .thenAnswer(createIndexAnswer(indexes, IndexType.HASH)); + + when(mockQueryService.createHashIndex(anyString(), anyString(), anyString(), anyString())) + .thenAnswer(createIndexAnswer(indexes, IndexType.HASH)); + + when(mockQueryService.createKeyIndex(anyString(), anyString(), anyString())) + .thenAnswer(createIndexAnswer(indexes, IndexType.KEY)); + when(mockQueryService.newCq(anyString(), any(CqAttributes.class))).thenAnswer(invocation -> add(cqQueries, mockCqQuery(null, invocation.getArgument(0), invocation.getArgument(1), false))); @@ -1212,6 +1642,25 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { return cqQuery; } + private static Index add(Collection indexes, Index index) { + + indexes.add(index); + + return index; + } + + private static Answer createIndexAnswer(Collection indexes, IndexType indexType) { + + return invocation -> { + + String indexName = invocation.getArgument(0); + String indexedExpression = invocation.getArgument(1); + String regionPath = invocation.getArgument(2); + + return add(indexes, mockIndex(indexName, indexedExpression, regionPath, indexType)); + }; + } + private static CqQuery mockCqQuery(String name, String queryString, CqAttributes cqAttributes, boolean durable) { CqQuery mockCqQuery = mock(CqQuery.class); @@ -1299,9 +1748,33 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { return mockQueryStatistics; } + public static Index mockIndex(String name, String expression, String fromClause, IndexType indexType) { + + Index mockIndex = mock(Index.class, name); + + IndexStatistics mockIndexStaticts = mockIndexStatistics(name); + + when(mockIndex.getName()).thenReturn(name); + when(mockIndex.getCanonicalizedFromClause()).thenReturn(fromClause); + when(mockIndex.getCanonicalizedIndexedExpression()).thenReturn(expression); + when(mockIndex.getCanonicalizedProjectionAttributes()).thenReturn(expression); + when(mockIndex.getFromClause()).thenReturn(fromClause); + when(mockIndex.getIndexedExpression()).thenReturn(expression); + when(mockIndex.getProjectionAttributes()).thenReturn(expression); + when(mockIndex.getRegion()).thenAnswer(invocation -> regions.get(fromClause)); + when(mockIndex.getStatistics()).thenReturn(mockIndexStaticts); + when(mockIndex.getType()).thenReturn(indexType.getGemfireIndexType()); + + return mockIndex; + } + + private static IndexStatistics mockIndexStatistics(String name) { + return mock(IndexStatistics.class, mockObjectIdentifier(name)); + } + @SuppressWarnings("unchecked") public static Region mockRegion(RegionService regionService, String name, - RegionAttributes regionAttributes) { + RegionAttributes regionAttributes) { Map data = new ConcurrentHashMap<>(); @@ -1309,7 +1782,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { Set> subRegions = new CopyOnWriteArraySet<>(); - when(mockRegion.getAttributes()).thenReturn(regionAttributes); + when(mockRegion.getAttributes()).thenAnswer(invocation -> mockRegionAttributes(mockRegion, regionAttributes)); when(mockRegion.getFullPath()).thenReturn(toRegionPath(name)); when(mockRegion.getName()).thenReturn(toRegionName(name)); when(mockRegion.getRegionService()).thenReturn(regionService); @@ -1326,8 +1799,8 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { data.get(invocation.getArgument(0))); when(mockRegion.getEntry(ArgumentMatchers.any())).thenAnswer(invocation -> - data.entrySet().stream().filter(entry -> entry.getKey().equals(invocation.getArgument(0))) - .findFirst().orElse(null)); + data.entrySet().stream().filter(entry -> entry.getKey().equals(invocation.getArgument(0))).findFirst() + .orElse(null)); when(mockRegion.put(any(), any())).thenAnswer(invocation -> data.put(invocation.getArgument(0), invocation.getArgument(1))); @@ -1340,16 +1813,195 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { return recursive ? subRegions.stream() - .flatMap(subRegion -> subRegion.subregions(true).stream()) - .collect(Collectors.toSet()) + .flatMap(subRegion -> subRegion.subregions(true).stream()) + .collect(Collectors.toSet()) : subRegions; }); return rememberMockedRegion(mockRegion); } + @SuppressWarnings("unchecked") + private static RegionAttributes mockRegionAttributes(Region mockRegion, + RegionAttributes baseRegionAttributes) { + + AttributesMutator mockAttributesMutator = mock(AttributesMutator.class); + + EvictionAttributesMutator mockEvictionAttributesMutator = mock(EvictionAttributesMutator.class); + + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + when(mockRegion.getAttributesMutator()).thenReturn(mockAttributesMutator); + when(mockAttributesMutator.getEvictionAttributesMutator()).thenReturn(mockEvictionAttributesMutator); + when(mockAttributesMutator.getRegion()).thenReturn(mockRegion); + + AtomicInteger evictionMaximum = + new AtomicInteger(Optional.ofNullable(baseRegionAttributes.getEvictionAttributes()) + .map(EvictionAttributes::getMaximum) + .orElse(EvictionAttributes.DEFAULT_ENTRIES_MAXIMUM)); + + AtomicReference cloningEnabled = new AtomicReference<>(null); + + AtomicReference> cacheLoader = new AtomicReference<>(baseRegionAttributes.getCacheLoader()); + + AtomicReference> cacheWriter = new AtomicReference<>(baseRegionAttributes.getCacheWriter()); + + AtomicReference> customEntryIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getCustomEntryIdleTimeout()); + + AtomicReference> customEntryTimeToLive = + new AtomicReference<>(baseRegionAttributes.getCustomEntryTimeToLive()); + + AtomicReference entryIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getEntryIdleTimeout()); + + AtomicReference entryTimeToLive = + new AtomicReference<>(baseRegionAttributes.getEntryTimeToLive()); + + AtomicReference regionIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getRegionIdleTimeout()); + + AtomicReference regionTimeToLive = + new AtomicReference<>(baseRegionAttributes.getRegionTimeToLive()); + + List asyncEventQueueIds = + new CopyOnWriteArrayList<>(nullSafeSet(baseRegionAttributes.getAsyncEventQueueIds())); + + List> cacheListeners = + new CopyOnWriteArrayList<>(nullSafeArray(baseRegionAttributes.getCacheListeners(), CacheListener.class)); + + List gatewaySenderIds = + new CopyOnWriteArrayList<>(nullSafeSet(baseRegionAttributes.getGatewaySenderIds())); + + // Mock AttributesMutator + doAnswer(newAdder(asyncEventQueueIds, null)) + .when(mockAttributesMutator).addAsyncEventQueueId(anyString()); + + doAnswer(newAdder(cacheListeners, null)) + .when(mockAttributesMutator).addCacheListener(any(CacheListener.class)); + + doAnswer(newAdder(gatewaySenderIds, null)). + when(mockAttributesMutator).addGatewaySenderId(anyString()); + + when(mockAttributesMutator.getCloningEnabled()).thenAnswer(newGetter(() -> + Optional.ofNullable(cloningEnabled.get()).orElseGet(baseRegionAttributes::getCloningEnabled))); + + doAnswer(invocation -> { + + CacheListener[] cacheListenersArgument = + nullSafeArray(invocation.getArgument(0), CacheListener.class); + + Arrays.stream(cacheListenersArgument).forEach(it -> + Assert.notNull(it, "The CacheListener[] must not contain null elements")); + + cacheListeners.forEach(CacheListener::close); + cacheListeners.addAll(Arrays.asList(cacheListenersArgument)); + + return null; + + }).when(mockAttributesMutator).initCacheListeners(any(CacheListener[].class)); + + + doAnswer(invocation -> asyncEventQueueIds.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeAsyncEventQueueId(anyString()); + + doAnswer(invocation -> cacheListeners.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeCacheListener(any(CacheListener.class)); + + doAnswer(invocation -> gatewaySenderIds.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeGatewaySenderId(anyString()); + + doAnswer(newSetter(cacheLoader, baseRegionAttributes.getCacheLoader())) + .when(mockAttributesMutator).setCacheLoader(any(CacheLoader.class)); + + doAnswer(newSetter(cacheWriter, baseRegionAttributes.getCacheWriter())) + .when(mockAttributesMutator).setCacheWriter(any(CacheWriter.class)); + + doAnswer(newSetter(cloningEnabled, null)) + .when(mockAttributesMutator).setCloningEnabled(anyBoolean()); + + doAnswer(newSetter(customEntryIdleTimeout, baseRegionAttributes.getCustomEntryIdleTimeout())) + .when(mockAttributesMutator).setCustomEntryIdleTimeout(any(CustomExpiry.class)); + + doAnswer(newSetter(customEntryTimeToLive, baseRegionAttributes.getCustomEntryTimeToLive())) + .when(mockAttributesMutator).setCustomEntryTimeToLive(any(CustomExpiry.class)); + + doAnswer(newSetter(entryIdleTimeout, baseRegionAttributes.getEntryIdleTimeout())) + .when(mockAttributesMutator).setEntryIdleTimeout(any(ExpirationAttributes.class)); + + doAnswer(newSetter(entryTimeToLive, baseRegionAttributes.getEntryTimeToLive())) + .when(mockAttributesMutator).setEntryTimeToLive(any(ExpirationAttributes.class)); + + doAnswer(newSetter(regionIdleTimeout, baseRegionAttributes.getRegionIdleTimeout())) + .when(mockAttributesMutator).setRegionIdleTimeout(any(ExpirationAttributes.class)); + + doAnswer(newSetter(regionTimeToLive, baseRegionAttributes.getRegionTimeToLive())) + .when(mockAttributesMutator).setRegionTimeToLive(any(ExpirationAttributes.class)); + + // Mock EvictionAttributesMutator + doAnswer(newSetter(evictionMaximum, null)).when(mockEvictionAttributesMutator).setMaximum(anyInt()); + + // Mock RegionAttributes + when(mockRegionAttributes.getAsyncEventQueueIds()) + .thenAnswer(invocation -> asSet(asyncEventQueueIds.toArray(new String[asyncEventQueueIds.size()]))); + + when(mockRegionAttributes.getCacheListeners()) + .thenAnswer(invocation -> cacheListeners.toArray(new CacheListener[cacheListeners.size()])); + + when(mockRegionAttributes.getCacheLoader()).thenAnswer(newGetter(cacheLoader::get)); + when(mockRegionAttributes.getCacheWriter()).thenAnswer(newGetter(cacheWriter::get)); + when(mockRegionAttributes.getCloningEnabled()).thenAnswer(newGetter(cloningEnabled::get)); + when(mockRegionAttributes.getCompressor()).thenAnswer(newGetter(baseRegionAttributes::getCompressor)); + when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenAnswer(newGetter(baseRegionAttributes::getConcurrencyChecksEnabled)); + when(mockRegionAttributes.getConcurrencyLevel()).thenAnswer(newGetter(baseRegionAttributes::getConcurrencyLevel)); + when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenAnswer(newGetter(customEntryIdleTimeout::get)); + when(mockRegionAttributes.getCustomEntryTimeToLive()).thenAnswer(newGetter(customEntryTimeToLive::get)); + when(mockRegionAttributes.getDataPolicy()).thenAnswer(newGetter(baseRegionAttributes::getDataPolicy)); + when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(baseRegionAttributes::getDiskStoreName)); + when(mockRegionAttributes.getEnableAsyncConflation()).thenAnswer(newGetter(baseRegionAttributes::getEnableAsyncConflation)); + when(mockRegionAttributes.getEnableSubscriptionConflation()).thenAnswer(newGetter(baseRegionAttributes::getEnableSubscriptionConflation)); + when(mockRegionAttributes.getEntryIdleTimeout()).thenAnswer(newGetter(entryIdleTimeout::get)); + when(mockRegionAttributes.getEntryTimeToLive()).thenAnswer(newGetter(entryTimeToLive::get)); + + when(mockRegionAttributes.getEvictionAttributes()).thenAnswer(invocation -> { + + EvictionAttributes mockEvictionAttibutes = mock(EvictionAttributes.class); + EvictionAttributes regionEvictionAttributes = baseRegionAttributes.getEvictionAttributes(); + + when(mockEvictionAttibutes.getAction()).thenAnswer(newGetter(regionEvictionAttributes::getAction)); + when(mockEvictionAttibutes.getAlgorithm()).thenAnswer(newGetter(regionEvictionAttributes::getAlgorithm)); + when(mockEvictionAttibutes.getMaximum()).thenAnswer(newGetter(evictionMaximum)); + when(mockEvictionAttibutes.getObjectSizer()).thenAnswer(newGetter(regionEvictionAttributes::getObjectSizer)); + + return mockEvictionAttibutes; + }); + + when(mockRegionAttributes.getGatewaySenderIds()) + .thenAnswer(invocation -> asSet(gatewaySenderIds.toArray(new String[gatewaySenderIds.size()]))); + + when(mockRegionAttributes.getIgnoreJTA()).thenAnswer(newGetter(baseRegionAttributes::getIgnoreJTA)); + when(mockRegionAttributes.getIndexMaintenanceSynchronous()).thenAnswer(newGetter(baseRegionAttributes::getIndexMaintenanceSynchronous)); + when(mockRegionAttributes.getInitialCapacity()).thenAnswer(newGetter(baseRegionAttributes::getInitialCapacity)); + when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(baseRegionAttributes::getKeyConstraint)); + when(mockRegionAttributes.getLoadFactor()).thenAnswer(newGetter(baseRegionAttributes::getLoadFactor)); + when(mockRegionAttributes.getMulticastEnabled()).thenAnswer(newGetter(baseRegionAttributes::getMulticastEnabled)); + when(mockRegionAttributes.getOffHeap()).thenAnswer(newGetter(baseRegionAttributes::getOffHeap)); + when(mockRegionAttributes.getPartitionAttributes()).thenAnswer(newGetter(baseRegionAttributes::getPartitionAttributes)); + when(mockRegionAttributes.getPoolName()).thenAnswer(newGetter(baseRegionAttributes::getPoolName)); + when(mockRegionAttributes.getRegionIdleTimeout()).thenAnswer(newGetter(regionIdleTimeout::get)); + when(mockRegionAttributes.getRegionTimeToLive()).thenAnswer(newGetter(regionTimeToLive::get)); + when(mockRegionAttributes.getScope()).thenAnswer(newGetter(baseRegionAttributes::getScope)); + when(mockRegionAttributes.getStatisticsEnabled()).thenAnswer(newGetter(baseRegionAttributes::getStatisticsEnabled)); + when(mockRegionAttributes.getSubscriptionAttributes()).thenAnswer(newGetter(baseRegionAttributes::getSubscriptionAttributes)); + when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(baseRegionAttributes::getValueConstraint)); + when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(baseRegionAttributes::isDiskSynchronous)); + when(mockRegionAttributes.isLockGrantor()).thenAnswer(newGetter(baseRegionAttributes::isLockGrantor)); + + return mockRegionAttributes; + } + public static Region mockSubRegion(Region parent, String name, - RegionAttributes regionAttributes) { + RegionAttributes regionAttributes) { String subRegionName = String.format("%1$s%2$s", parent.getFullPath(), toRegionPath(name)); @@ -1365,7 +2017,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { } public static RegionFactory mockRegionFactory(Cache mockCache, - RegionAttributes regionAttributes) { + RegionAttributes regionAttributes) { return mockRegionFactory(mockCache, null, regionAttributes); } @@ -1380,7 +2032,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { @SuppressWarnings("unchecked") public static RegionFactory mockRegionFactory(Cache mockCache, RegionShortcut regionShortcut, - RegionAttributes regionAttributes) { + RegionAttributes regionAttributes) { RegionFactory mockRegionFactory = mock(RegionFactory.class, mockObjectIdentifier("MockRegionFactory")); @@ -1457,7 +2109,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { .map(RegionAttributes::getEntryTimeToLive).orElse(DEFAULT_EXPIRATION_ATTRIBUTES)); AtomicReference evictionAttributes = new AtomicReference<>(optionalRegionAttributes - .map(RegionAttributes::getEvictionAttributes).orElseGet(() -> EvictionAttributes.createLRUEntryAttributes())); + .map(RegionAttributes::getEvictionAttributes).orElseGet(EvictionAttributes::createLRUEntryAttributes)); AtomicReference> keyConstraint = new AtomicReference<>(optionalRegionAttributes .map(RegionAttributes::getKeyConstraint).orElse(null)); @@ -1481,7 +2133,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { .map(RegionAttributes::getScope).orElse(Scope.DISTRIBUTED_NO_ACK)); AtomicReference subscriptionAttributes = new AtomicReference<>(optionalRegionAttributes - .map(RegionAttributes::getSubscriptionAttributes).orElseGet(() -> new SubscriptionAttributes())); + .map(RegionAttributes::getSubscriptionAttributes).orElseGet(SubscriptionAttributes::new)); AtomicReference> valueConstraint = new AtomicReference<>(optionalRegionAttributes .map(RegionAttributes::getValueConstraint).orElse(null)); @@ -1692,7 +2344,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { CacheFactory cacheFactorySpy = spy(cacheFactory); - Cache resolvedMockCache = MockGemFireObjectsSupport.resolveMockedGemFireCache(useSingletonCache) + Cache resolvedMockCache = GemFireMockObjectsSupport.resolveMockedGemFireCache(useSingletonCache) .orElseGet(() -> { Cache mockCache = mockPeerCache(); @@ -1742,7 +2394,7 @@ public abstract class MockGemFireObjectsSupport extends MockObjectsSupport { ClientCacheFactory clientCacheFactorySpy = spy(clientCacheFactory); ClientCache resolvedMockedClientCache = - MockGemFireObjectsSupport.resolveMockedGemFireCache(useSingletonCache).orElseGet(() -> { + GemFireMockObjectsSupport.resolveMockedGemFireCache(useSingletonCache).orElseGet(() -> { ClientCache mockClientCache = mockClientCache(); diff --git a/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireMockObjectsConfiguration.java b/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireMockObjectsConfiguration.java index 349de024..f6a87954 100644 --- a/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireMockObjectsConfiguration.java +++ b/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireMockObjectsConfiguration.java @@ -26,8 +26,8 @@ import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.EventListener; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; -import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport; -import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor; +import org.springframework.data.gemfire.test.mock.GemFireMockObjectsSupport; +import org.springframework.data.gemfire.test.mock.config.GemFireMockObjectsBeanPostProcessor; /** * The {@link GemFireMockObjectsConfiguration} class is a Spring {@link Configuration @Configuration} class @@ -41,7 +41,7 @@ import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanP * @see org.springframework.context.annotation.ImportAware * @see org.springframework.core.annotation.AnnotationAttributes * @see org.springframework.core.type.AnnotationMetadata - * @see org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor + * @see GemFireMockObjectsBeanPostProcessor * @since 2.0.0 */ @SuppressWarnings("unused") @@ -87,11 +87,11 @@ public class GemFireMockObjectsConfiguration implements ImportAware { @Bean public BeanPostProcessor mockGemFireObjectsBeanPostProcessor() { - return MockGemFireObjectsBeanPostProcessor.newInstance(this.useSingletonCache); + return GemFireMockObjectsBeanPostProcessor.newInstance(this.useSingletonCache); } @EventListener public void releaseMockResources(ContextClosedEvent event) { - MockGemFireObjectsSupport.destroy(); + GemFireMockObjectsSupport.destroy(); } } diff --git a/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireUnitTest.java b/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireUnitTest.java index 1c74a68c..b96b5b13 100644 --- a/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireUnitTest.java +++ b/src/test/java/org/springframework/data/gemfire/test/mock/annotation/GemFireUnitTest.java @@ -24,7 +24,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.runner.RunWith; -import org.springframework.data.gemfire.test.mock.context.MockGemFireObjectsApplicationContextInitializer; +import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -41,7 +41,7 @@ import org.springframework.test.context.junit4.SpringRunner; * @see java.lang.annotation.Retention * @see java.lang.annotation.Target * @see org.junit.runner.RunWith - * @see org.springframework.data.gemfire.test.mock.context.MockGemFireObjectsApplicationContextInitializer + * @see GemFireMockObjectsApplicationContextInitializer * @see org.springframework.test.context.ContextConfiguration * @see org.springframework.test.context.junit4.SpringRunner * @since 2.0.0 @@ -51,7 +51,7 @@ import org.springframework.test.context.junit4.SpringRunner; @Inherited @Documented @RunWith(SpringRunner.class) -@ContextConfiguration(initializers = MockGemFireObjectsApplicationContextInitializer.class) +@ContextConfiguration(initializers = GemFireMockObjectsApplicationContextInitializer.class) @SuppressWarnings("unused") public @interface GemFireUnitTest { diff --git a/src/test/java/org/springframework/data/gemfire/test/mock/config/MockGemFireObjectsBeanPostProcessor.java b/src/test/java/org/springframework/data/gemfire/test/mock/config/GemFireMockObjectsBeanPostProcessor.java similarity index 89% rename from src/test/java/org/springframework/data/gemfire/test/mock/config/MockGemFireObjectsBeanPostProcessor.java rename to src/test/java/org/springframework/data/gemfire/test/mock/config/GemFireMockObjectsBeanPostProcessor.java index 1c3f1d84..56c6c432 100644 --- a/src/test/java/org/springframework/data/gemfire/test/mock/config/MockGemFireObjectsBeanPostProcessor.java +++ b/src/test/java/org/springframework/data/gemfire/test/mock/config/GemFireMockObjectsBeanPostProcessor.java @@ -30,11 +30,11 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.data.gemfire.CacheFactoryBean; import org.springframework.data.gemfire.client.ClientCacheFactoryBean; import org.springframework.data.gemfire.client.PoolFactoryBean; -import org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport; +import org.springframework.data.gemfire.test.mock.GemFireMockObjectsSupport; import org.springframework.lang.Nullable; /** - * The {@link MockGemFireObjectsBeanPostProcessor} class is a Spring {@link BeanPostProcessor} that applies + * The {@link GemFireMockObjectsBeanPostProcessor} class is a Spring {@link BeanPostProcessor} that applies * mocks and spies to Spring Data GemFire / Spring Data Geode and Pivotal GemFire / Apache Geode objects * and components. * @@ -46,10 +46,10 @@ import org.springframework.lang.Nullable; * @see org.springframework.data.gemfire.CacheFactoryBean * @see org.springframework.data.gemfire.client.ClientCacheFactoryBean * @see org.springframework.data.gemfire.client.PoolFactoryBean - * @see org.springframework.data.gemfire.test.mock.MockGemFireObjectsSupport + * @see GemFireMockObjectsSupport * @since 2.0.0 */ -public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { +public class GemFireMockObjectsBeanPostProcessor implements BeanPostProcessor { private static final boolean DEFAULT_USE_SINGLETON_CACHE = false; @@ -59,13 +59,13 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { private final AtomicReference gemfireProperties = new AtomicReference<>(new Properties()); - public static MockGemFireObjectsBeanPostProcessor newInstance() { + public static GemFireMockObjectsBeanPostProcessor newInstance() { return newInstance(DEFAULT_USE_SINGLETON_CACHE); } - public static MockGemFireObjectsBeanPostProcessor newInstance(boolean useSingletonCache) { + public static GemFireMockObjectsBeanPostProcessor newInstance(boolean useSingletonCache) { - MockGemFireObjectsBeanPostProcessor beanPostProcessor = new MockGemFireObjectsBeanPostProcessor(); + GemFireMockObjectsBeanPostProcessor beanPostProcessor = new GemFireMockObjectsBeanPostProcessor(); beanPostProcessor.useSingletonCache = useSingletonCache; @@ -130,7 +130,7 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { @Override public CacheFactory initialize(CacheFactory cacheFactory) { - return MockGemFireObjectsSupport.spyOn(cacheFactory, useSingletonCache); + return GemFireMockObjectsSupport.spyOn(cacheFactory, useSingletonCache); } } @@ -154,7 +154,7 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { @Override public ClientCacheFactory initialize(ClientCacheFactory clientCacheFactory) { - return MockGemFireObjectsSupport.spyOn(clientCacheFactory, this.useSingletonCache); + return GemFireMockObjectsSupport.spyOn(clientCacheFactory, this.useSingletonCache); } } @@ -167,7 +167,7 @@ public class MockGemFireObjectsBeanPostProcessor implements BeanPostProcessor { @Override public PoolFactory initialize(PoolFactory poolFactory) { - return MockGemFireObjectsSupport.mockPoolFactory(); + return GemFireMockObjectsSupport.mockPoolFactory(); } } } diff --git a/src/test/java/org/springframework/data/gemfire/test/mock/context/MockGemFireObjectsApplicationContextInitializer.java b/src/test/java/org/springframework/data/gemfire/test/mock/context/GemFireMockObjectsApplicationContextInitializer.java similarity index 76% rename from src/test/java/org/springframework/data/gemfire/test/mock/context/MockGemFireObjectsApplicationContextInitializer.java rename to src/test/java/org/springframework/data/gemfire/test/mock/context/GemFireMockObjectsApplicationContextInitializer.java index 4d64d5c9..a670e5c2 100644 --- a/src/test/java/org/springframework/data/gemfire/test/mock/context/MockGemFireObjectsApplicationContextInitializer.java +++ b/src/test/java/org/springframework/data/gemfire/test/mock/context/GemFireMockObjectsApplicationContextInitializer.java @@ -18,24 +18,24 @@ package org.springframework.data.gemfire.test.mock.context; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor; +import org.springframework.data.gemfire.test.mock.config.GemFireMockObjectsBeanPostProcessor; /** - * The {@link MockGemFireObjectsApplicationContextInitializer} class is a Spring {@link ApplicationContextInitializer} + * The {@link GemFireMockObjectsApplicationContextInitializer} class is a Spring {@link ApplicationContextInitializer} * used to initialize the Spring {@link ConfigurableApplicationContext} with GemFire Object mocking. * * @author John Blum * @see org.springframework.context.ApplicationContextInitializer * @see org.springframework.context.ConfigurableApplicationContext - * @see org.springframework.data.gemfire.test.mock.config.MockGemFireObjectsBeanPostProcessor + * @see GemFireMockObjectsBeanPostProcessor * @since 2.0.0 */ -public class MockGemFireObjectsApplicationContextInitializer +public class GemFireMockObjectsApplicationContextInitializer implements ApplicationContextInitializer { @Override @SuppressWarnings("all") public void initialize(ConfigurableApplicationContext applicationContext) { - applicationContext.getBeanFactory().addBeanPostProcessor(MockGemFireObjectsBeanPostProcessor.newInstance()); + applicationContext.getBeanFactory().addBeanPostProcessor(GemFireMockObjectsBeanPostProcessor.newInstance()); } } diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml index e5b4f30c..87d28c2e 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/replicated-ns.xml @@ -20,7 +20,7 @@ - +