From 495ca6ff9aefaee52d0d7aa514b226f70f269a12 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 16 Jul 2019 14:08:07 -0700 Subject: [PATCH] DATAGEODE-197 - Add integration tests testing the association of Region(s) to GatewaySender ID(s). --- .../data/gemfire/PeerRegionFactoryBean.java | 16 +- .../config/xml/AbstractPeerRegionParser.java | 49 ++++++ .../config/xml/AbstractRegionParser.java | 31 ++-- .../config/xml/ClientRegionParser.java | 4 +- .../gemfire/config/xml/LocalRegionParser.java | 7 +- .../data/gemfire/config/xml/ParsingUtils.java | 2 - .../config/xml/PartitionedRegionParser.java | 27 ++-- .../config/xml/ReplicatedRegionParser.java | 11 +- .../InvalidRegionDataPolicyShortcutsTest.java | 24 +-- .../ClientServerIntegrationTestsSupport.java | 9 +- ...rXmlConfigurationByIdIntegrationTests.java | 151 ++++++++++++++++++ src/test/resources/logback.xml | 2 + ...figurationByIdIntegrationTests-context.xml | 28 ++++ 13 files changed, 302 insertions(+), 59 deletions(-) create mode 100644 src/main/java/org/springframework/data/gemfire/config/xml/AbstractPeerRegionParser.java create mode 100644 src/test/java/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests.java create mode 100644 src/test/resources/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests-context.xml diff --git a/src/main/java/org/springframework/data/gemfire/PeerRegionFactoryBean.java b/src/main/java/org/springframework/data/gemfire/PeerRegionFactoryBean.java index 197637b8..f9fae0b5 100644 --- a/src/main/java/org/springframework/data/gemfire/PeerRegionFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/PeerRegionFactoryBean.java @@ -21,6 +21,7 @@ import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newI import java.util.Arrays; import java.util.HashSet; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -98,7 +99,7 @@ public abstract class PeerRegionFactoryBean extends ConfigurableRegionFact private boolean close = false; private boolean destroy = false; - private boolean running; + private boolean running = false; private Boolean offHeap; private Boolean persistent; @@ -1002,13 +1003,12 @@ public abstract class PeerRegionFactoryBean extends ConfigurableRegionFact public void start() { if (!ObjectUtils.isEmpty(this.gatewaySenders)) { - synchronized (this.gatewaySenders) { - for (Object obj : this.gatewaySenders) { - GatewaySender gatewaySender = (GatewaySender) obj; - if (!(gatewaySender.isManualStart() || gatewaySender.isRunning())) { - gatewaySender.start(); - } - } + synchronized(this.gatewaySenders) { + Arrays.stream(this.gatewaySenders) + .filter(Objects::nonNull) + .filter(gatewaySender -> !gatewaySender.isManualStart()) + .filter(gatewaySender -> !gatewaySender.isRunning()) + .forEach(GatewaySender::start); } } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/AbstractPeerRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractPeerRegionParser.java new file mode 100644 index 00000000..bc96abd7 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/xml/AbstractPeerRegionParser.java @@ -0,0 +1,49 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.gemfire.config.xml; + +import org.apache.geode.cache.asyncqueue.AsyncEventQueue; +import org.apache.geode.cache.wan.GatewaySender; + +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; + +import org.w3c.dom.Element; + +/** + * The AbstractPeerRegionParser class... + * + * @author John Blum + * @since 1.0.0 + */ +public abstract class AbstractPeerRegionParser extends AbstractRegionParser { + + @Override + protected void doParseRegionConfiguration(Element element, ParserContext parserContext, + BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder regionAttributesBuilder, boolean subRegion) { + + super.doParseRegionConfiguration(element, parserContext, regionBuilder, regionAttributesBuilder, subRegion); + + ParsingUtils.setPropertyValue(element, regionBuilder, "async-event-queue-ids"); + ParsingUtils.setPropertyValue(element, regionBuilder, "gateway-sender-ids"); + + parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, AsyncEventQueue.class.getName(), + "async-event-queue", "asyncEventQueues"); + + parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, GatewaySender.class.getName(), + "gateway-sender", "gatewaySenders"); + } +} 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 5a6d4c18..4f48a16b 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 @@ -22,9 +22,9 @@ import java.util.Optional; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.geode.cache.asyncqueue.AsyncEventQueue; -import org.apache.geode.cache.wan.GatewaySender; +import org.apache.geode.cache.Region; +import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; @@ -135,12 +135,6 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { ParsingUtils.parseEviction(element, parserContext, regionAttributesBuilder); ParsingUtils.parseCompressor(element, parserContext, regionAttributesBuilder); - parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, AsyncEventQueue.class.getName(), - "async-event-queue", "asyncEventQueues"); - - parseCollectionOfCustomSubElements(element, parserContext, regionBuilder, GatewaySender.class.getName(), - "gateway-sender", "gatewaySenders"); - List subElements = DomUtils.getChildElements(element); for (Element subElement : subElements) { @@ -256,20 +250,23 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { String name = element.getAttribute(NAME_ATTRIBUTE); - return StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE); + return StringUtils.hasText(name) + ? name + : element.getAttribute(ID_ATTRIBUTE); } private String buildSubRegionPath(String parentName, String regionName) { String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName, regionName }, "/"); - if (!regionPath.startsWith("/")) { - regionPath = "/" + regionPath; + if (!regionPath.startsWith(Region.SEPARATOR)) { + regionPath = Region.SEPARATOR + regionPath; } return regionPath; } + @SuppressWarnings("all") private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, String subRegionPath, String cacheRef) { @@ -281,20 +278,22 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser { BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element); - beanDefinition.getPropertyValues().add("cache", new RuntimeBeanReference(cacheRef)); - beanDefinition.getPropertyValues().add("parent", new RuntimeBeanReference(parentBeanName)); - beanDefinition.getPropertyValues().add("regionName", regionName); + MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); + + propertyValues.add("cache", new RuntimeBeanReference(cacheRef)); + propertyValues.add("parent", new RuntimeBeanReference(parentBeanName)); + propertyValues.add("regionName", regionName); return beanDefinition; } private String getParentRegionPathFrom(String regionPath) { - int index = regionPath.lastIndexOf("/"); + int index = regionPath.lastIndexOf(Region.SEPARATOR); String parentPath = regionPath.substring(0, index); - if (parentPath.lastIndexOf("/") == 0) { + if (parentPath.lastIndexOf(Region.SEPARATOR) == 0) { parentPath = parentPath.substring(1); } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java index d44ee4b7..88bac8f2 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ClientRegionParser.java @@ -17,7 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire.config.xml; import java.util.List; @@ -31,6 +30,7 @@ import org.springframework.data.gemfire.client.KeyInterest; import org.springframework.data.gemfire.client.RegexInterest; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; + import org.w3c.dom.Element; /** @@ -66,7 +66,9 @@ class ClientRegionParser extends AbstractRegionParser { String resolvedCacheRef = ParsingUtils.resolveCacheReference(element.getAttribute("cache-ref")); if (!subRegion) { + regionBuilder.addPropertyReference("cache", resolvedCacheRef); + ParsingUtils.setPropertyValue(element, regionBuilder, "close"); ParsingUtils.setPropertyValue(element, regionBuilder, "destroy"); } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/LocalRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/LocalRegionParser.java index a7f4e2eb..b3b830c7 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/LocalRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/LocalRegionParser.java @@ -27,10 +27,13 @@ import org.w3c.dom.Element; * * @author David Turanski * @author John Blum + * @see org.springframework.beans.factory.support.BeanDefinitionBuilder + * @see org.springframework.beans.factory.xml.ParserContext * @see org.springframework.data.gemfire.LocalRegionFactoryBean - * @see AbstractRegionParser + * @see org.springframework.data.gemfire.config.xml.AbstractPeerRegionParser + * @see org.w3c.dom.Element */ -class LocalRegionParser extends AbstractRegionParser { +class LocalRegionParser extends AbstractPeerRegionParser { /** * {@inheritDoc} diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java b/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java index 4a0ccf34..c18b5b0f 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ParsingUtils.java @@ -378,13 +378,11 @@ abstract class ParsingUtils { static void parseOptionalRegionAttributes(Element element, ParserContext parserContext, BeanDefinitionBuilder regionAttributesBuilder) { - setPropertyValue(element, regionAttributesBuilder, "async-event-queue-ids"); setPropertyValue(element, regionAttributesBuilder, "cloning-enabled"); setPropertyValue(element, regionAttributesBuilder, "concurrency-level"); setPropertyValue(element, regionAttributesBuilder, "disk-synchronous"); setPropertyValue(element, regionAttributesBuilder, "enable-async-conflation"); setPropertyValue(element, regionAttributesBuilder, "enable-subscription-conflation"); - setPropertyValue(element, regionAttributesBuilder, "gateway-sender-ids"); setPropertyValue(element, regionAttributesBuilder, "ignore-jta", "ignoreJTA"); setPropertyValue(element, regionAttributesBuilder, "index-update-type"); setPropertyValue(element, regionAttributesBuilder, "initial-capacity"); 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 b60e32d1..3ded7f44 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 @@ -40,10 +40,13 @@ import org.w3c.dom.Element; * @author Costin Leau * @author David Turanski * @author John Blum + * @see org.springframework.beans.factory.support.BeanDefinitionBuilder + * @see org.springframework.beans.factory.xml.ParserContext * @see org.springframework.data.gemfire.PartitionedRegionFactoryBean - * @see AbstractRegionParser + * @see org.springframework.data.gemfire.config.xml.AbstractPeerRegionParser + * @see org.w3c.dom.Element */ -class PartitionedRegionParser extends AbstractRegionParser { +class PartitionedRegionParser extends AbstractPeerRegionParser { /** * {@inheritDoc} @@ -75,7 +78,7 @@ class PartitionedRegionParser extends AbstractRegionParser { mergeTemplateRegionPartitionAttributes(element, parserContext, regionBuilder, partitionAttributesBuilder); - parseColocatedWith(element, regionBuilder, partitionAttributesBuilder, "colocated-with"); + parseCollocatedWith(element, regionBuilder, partitionAttributesBuilder, "colocated-with"); ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "copies", "redundantCopies"); ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "local-max-memory"); ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "recovery-delay"); @@ -122,7 +125,6 @@ class PartitionedRegionParser extends AbstractRegionParser { regionAttributesBuilder.addPropertyValue("partitionAttributes", partitionAttributesBuilder.getBeanDefinition()); } - /* (non-Javadoc) */ void mergeTemplateRegionPartitionAttributes(Element element, ParserContext parserContext, BeanDefinitionBuilder regionBuilder, BeanDefinitionBuilder partitionAttributesBuilder) { @@ -158,8 +160,7 @@ class PartitionedRegionParser extends AbstractRegionParser { } } - /* (non-Javadoc) */ - private void parseColocatedWith(Element element, BeanDefinitionBuilder regionBuilder, + private void parseCollocatedWith(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 @@ -177,17 +178,15 @@ class PartitionedRegionParser extends AbstractRegionParser { } } - /* (non-Javadoc) */ - private Object parsePartitionResolver(Element subElement, ParserContext parserContext, - BeanDefinitionBuilder builder) { - - return ParsingUtils.parseRefOrSingleNestedBeanDeclaration(subElement, parserContext, builder); - } - - /* (non-Javadoc) */ private Object parsePartitionListeners(Element subElement, ParserContext parserContext, BeanDefinitionBuilder builder) { return ParsingUtils.parseRefOrNestedBeanDeclaration(subElement, parserContext, builder); } + + private Object parsePartitionResolver(Element subElement, ParserContext parserContext, + BeanDefinitionBuilder builder) { + + return ParsingUtils.parseRefOrSingleNestedBeanDeclaration(subElement, parserContext, builder); + } } diff --git a/src/main/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionParser.java b/src/main/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionParser.java index 3dea017a..7bd8aa47 100644 --- a/src/main/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/xml/ReplicatedRegionParser.java @@ -28,10 +28,13 @@ import org.w3c.dom.Element; * @author Costin Leau * @author David Turanski * @author John Blum + * @see org.springframework.beans.factory.support.BeanDefinitionBuilder + * @see org.springframework.beans.factory.xml.ParserContext * @see org.springframework.data.gemfire.ReplicatedRegionFactoryBean - * @see AbstractRegionParser + * @see org.springframework.data.gemfire.config.xml.AbstractPeerRegionParser + * @see org.w3c.dom.Element */ -class ReplicatedRegionParser extends AbstractRegionParser { +class ReplicatedRegionParser extends AbstractPeerRegionParser { /** * {@inheritDoc} @@ -52,8 +55,8 @@ class ReplicatedRegionParser extends AbstractRegionParser { ParsingUtils.parseScope(element, builder); - BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition( - RegionAttributesFactoryBean.class); + BeanDefinitionBuilder regionAttributesBuilder = + BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class); doParseRegionConfiguration(element, parserContext, builder, regionAttributesBuilder, subRegion); diff --git a/src/test/java/org/springframework/data/gemfire/InvalidRegionDataPolicyShortcutsTest.java b/src/test/java/org/springframework/data/gemfire/InvalidRegionDataPolicyShortcutsTest.java index 7e9d1a00..0a5a0e3f 100644 --- a/src/test/java/org/springframework/data/gemfire/InvalidRegionDataPolicyShortcutsTest.java +++ b/src/test/java/org/springframework/data/gemfire/InvalidRegionDataPolicyShortcutsTest.java @@ -13,51 +13,55 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.gemfire; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; + import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * The InvalidRegionDataPolicyShortcutsIntegrationTest class is a test suite of test cases testing and setting up - * some invalid, or illegal uses of the Region data-policy and/or shortcut XML namespace attributes. + * Integration Tests testing and setting up some invalid, or illegal uses of the Region data-policy and shortcut + * XML namespace attributes. * * @author John Blum * @see org.junit.Test + * @see org.springframework.context.support.ClassPathXmlApplicationContext * @since 1.4.0 */ public class InvalidRegionDataPolicyShortcutsTest { @Test(expected = BeanCreationException.class) public void testInvalidRegionShortcutWithPersistentAttribute() { + try { new ClassPathXmlApplicationContext( "/org/springframework/data/gemfire/invalid-region-shortcut-with-persistent-attribute.xml"); } catch (BeanCreationException expected) { - //expected.printStackTrace(System.err); - assertTrue(expected.getMessage().contains("Error creating bean with name 'InvalidReplicate'")); + + assertThat(expected).hasMessageContaining("Error creating bean with name 'InvalidReplicate'"); + throw expected; } } @Test(expected = BeanDefinitionParsingException.class) public void testInvalidUseOfRegionDataPolicyAndShortcut() { + try { new ClassPathXmlApplicationContext( "/org/springframework/data/gemfire/invalid-use-of-region-datapolicy-and-shortcut.xml"); } catch (BeanDefinitionParsingException expected) { - //expected.printStackTrace(System.err); - assertTrue(expected.getMessage().contains( - "Only one of [data-policy, shortcut] may be specified with element 'gfe:partitioned-region'")); + + assertThat(expected).hasMessageContaining( + "Only one of [data-policy, shortcut] may be specified with element [gfe:partitioned-region]"); + throw expected; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java b/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java index af6caad6..d9ec101f 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/ClientServerIntegrationTestsSupport.java @@ -14,7 +14,6 @@ * limitations under the License. * */ - package org.springframework.data.gemfire.test.support; import static org.assertj.core.api.Assertions.assertThat; @@ -28,10 +27,12 @@ import java.net.Socket; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Optional; +import java.util.Scanner; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.geode.cache.server.CacheServer; + import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.data.gemfire.process.ProcessWrapper; import org.springframework.data.gemfire.util.CollectionUtils; @@ -83,6 +84,10 @@ public class ClientServerIntegrationTestsSupport { LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-hh-mm-ss"))); } + protected static String block() { + return new Scanner(System.in).nextLine(); + } + protected static File createDirectory(String pathname) { return createDirectory(new File(pathname)); } @@ -141,7 +146,7 @@ public class ClientServerIntegrationTestsSupport { } protected static int intValue(Number number) { - return (number != null ? number.intValue() : 0); + return number != null ? number.intValue() : 0; } protected static String logFile() { diff --git a/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests.java new file mode 100644 index 00000000..bfe4bf85 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests.java @@ -0,0 +1,151 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.gemfire.wan; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import javax.annotation.Resource; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +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.wan.GatewaySender; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.data.gemfire.ReplicatedRegionFactoryBean; +import org.springframework.data.gemfire.config.annotation.EnableLocator; +import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; +import org.springframework.data.gemfire.util.ArrayUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Integration Tests testing the configuration of {@link GatewaySender GatewaySenders} on a cache {@link Region} + * by {@literal identifier} using the SDG XML Namespace. + * + * @author John Blum + * @see org.junit.Test + * @see org.apache.geode.cache.Region + * @see org.apache.geode.cache.wan.GatewaySender + * @since 2.2.0 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration(locations = "GatewaySenderXmlConfigurationByIdIntegrationTests-context.xml") +@SuppressWarnings("unused") +public class GatewaySenderXmlConfigurationByIdIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper geodeServer; + + private static final String GEMFIRE_LOG_LEVEL = "error"; + + @BeforeClass + public static void startGeodeServer() throws IOException { + + int port = findAvailablePort(); + + System.setProperty("spring.data.gemfire.locator.port", String.valueOf(port)); + + geodeServer = run(GeodeServerConfiguration.class, "-Dspring.data.gemfire.locator.port=" + port); + waitForServerToStart("localhost", port); + } + + @AfterClass + public static void stopGeodeServer() { + + stop(geodeServer); + + System.getProperties().stringPropertyNames().stream() + .filter(propertyName -> propertyName.startsWith("spring.data.gemfire")) + .forEach(System::clearProperty); + } + + @Resource(name = "Example") + private Region example; + + @Test + public void regionGatewaySendersByIdConfiguredCorrectly() { + + assertThat(this.example).isNotNull(); + assertThat(this.example.getName()).isEqualTo("Example"); + + RegionAttributes exampleAttributes = this.example.getAttributes(); + + assertThat(exampleAttributes).isNotNull(); + assertThat(exampleAttributes.getDataPolicy()).isEqualTo(DataPolicy.REPLICATE); + assertThat(exampleAttributes.getGatewaySenderIds()) + .containsExactlyInAnyOrder("TestGatewaySenderOne", "TestGatewaySenderTwo"); + } + + @EnableLocator + @PeerCacheApplication(logLevel = GEMFIRE_LOG_LEVEL) + static class GeodeServerConfiguration { + + public static void main(String[] args) { + + System.err.printf("Locator Port [%s]%n", System.getProperty("spring.data.gemfire.locator.port")); + + runSpringApplication(GeodeServerConfiguration.class, args); + block(); + } + + @Bean("TestGatewaySenderOne") + public GatewaySenderFactoryBean gatewaySenderOne(Cache cache) { + + GatewaySenderFactoryBean gatewaySenderOne = new GatewaySenderFactoryBean(cache); + + gatewaySenderOne.setRemoteDistributedSystemId(1); + gatewaySenderOne.setManualStart(true); + + return gatewaySenderOne; + } + + @Bean("TestGatewaySenderTwo") + public GatewaySenderFactoryBean gatewaySenderTwo(Cache cache) { + + GatewaySenderFactoryBean gatewaySenderTwo = new GatewaySenderFactoryBean(cache); + + gatewaySenderTwo.setRemoteDistributedSystemId(1); + gatewaySenderTwo.setManualStart(true); + + return gatewaySenderTwo; + } + + @Bean("Example") + public ReplicatedRegionFactoryBean exampleRegion(GemFireCache gemfireCache, + @Qualifier("TestGatewaySenderOne") GatewaySender gatewaySenderOne, + @Qualifier("TestGatewaySenderTwo") GatewaySender gatewaySenderTwo) { + + ReplicatedRegionFactoryBean exampleRegion = new ReplicatedRegionFactoryBean<>(); + + exampleRegion.setCache(gemfireCache); + exampleRegion.setGatewaySenders(ArrayUtils.asArray(gatewaySenderOne, gatewaySenderTwo)); + + return exampleRegion; + } + } +} diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 4d64c87c..6606bd1b 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -19,6 +19,8 @@ + + diff --git a/src/test/resources/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests-context.xml b/src/test/resources/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests-context.xml new file mode 100644 index 00000000..2ee11a4c --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/wan/GatewaySenderXmlConfigurationByIdIntegrationTests-context.xml @@ -0,0 +1,28 @@ + + + + + + + GatewaySenderXmlConfigurationByIdIntegrationTests + error + localhost[${spring.data.gemfire.locator.port}] + 1 + + + + + + +