From a644e5dd89d299a659bae20e5ebc4298ac7fc3b2 Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 25 Feb 2015 16:20:31 -0800 Subject: [PATCH] SGF-375 - The XML namespace element is missing the 'max-time-between-pings' attribute. --- .../data/gemfire/config/GatewayHubParser.java | 2 +- .../gemfire/config/spring-gemfire-1.5.xsd | 7 + .../config/GatewayHubNamespaceTest.java | 220 +++++++++++++++ .../gemfire/test/AbstractMockerySupport.java | 46 +++ .../data/gemfire/test/MockGatewayFactory.java | 266 ++++++++++++++++++ .../gemfire/test/MockGatewayHubFactory.java | 166 +++++++++++ .../data/gemfire/test/StubCache.java | 19 +- .../test/support/IdentifierSequence.java | 38 +++ .../gemfire/test/support/StackTraceUtils.java | 79 ++++++ .../gemfire/test/support/ThreadUtils.java | 73 +++++ .../GatewayHubNamespaceTest-context.xml | 50 ++++ 11 files changed, 960 insertions(+), 6 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/config/GatewayHubNamespaceTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/AbstractMockerySupport.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/MockGatewayFactory.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/MockGatewayHubFactory.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/support/IdentifierSequence.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/support/StackTraceUtils.java create mode 100644 src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java create mode 100644 src/test/resources/org/springframework/data/gemfire/config/GatewayHubNamespaceTest-context.xml diff --git a/src/main/java/org/springframework/data/gemfire/config/GatewayHubParser.java b/src/main/java/org/springframework/data/gemfire/config/GatewayHubParser.java index b98b67ce..e3e25b8a 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GatewayHubParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/GatewayHubParser.java @@ -56,7 +56,7 @@ class GatewayHubParser extends AbstractSimpleBeanDefinitionParser { ParsingUtils.setPropertyValue(element, builder, "bind-address"); ParsingUtils.setPropertyValue(element, builder, "manual-start"); - //ParsingUtils.setPropertyValue(element, builder, "max-time-between-pings", "maximumTimeBetweenPings"); + ParsingUtils.setPropertyValue(element, builder, "max-time-between-pings", "maximumTimeBetweenPings"); ParsingUtils.setPropertyValue(element, builder, "socket-buffer-size"); ParsingUtils.setPropertyValue(element, builder, "startup-policy"); ParsingUtils.setPropertyValue(element, builder, "port"); diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.5.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.5.xsd index 6bf942d7..ade1f354 100644 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.5.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.5.xsd @@ -3033,6 +3033,13 @@ Specifies if the gateway hub is manually (true) or automatically(false) started ]]> + + + + + example; + + @Autowired + private GatewayHub gatewayHub; + + protected Gateway getGatewayById(final List gateways, final String id) { + for (Gateway gateway : gateways) { + if (gateway.getId().equals(id)) { + return gateway; + } + } + + return null; + } + + @Test + public void testRegionConfiguration() { + assertNotNull("The '/Example' Region was not properly initialized!", example); + assertEquals("Example", example.getName()); + assertEquals("/Example", example.getFullPath()); + assertNotNull(example.getAttributes()); + assertEquals(DataPolicy.REPLICATE, example.getAttributes().getDataPolicy()); + assertTrue(example.getAttributes().getEnableGateway()); + assertEquals("testGatewayHub", example.getAttributes().getGatewayHubId()); + } + + @Test + public void testGatewayConfiguration() { + assertNotNull("The 'TestGatewayHub' GatewayHub was not properly initialized!", gatewayHub); + assertEquals("localhost", gatewayHub.getBindAddress()); + assertEquals("TestGatewayHub", gatewayHub.getId()); + assertTrue(gatewayHub.getManualStart()); + assertEquals(5000, gatewayHub.getMaximumTimeBetweenPings()); + assertEquals(45123, gatewayHub.getPort()); + assertEquals(16384, gatewayHub.getSocketBufferSize()); + assertEquals("primary", gatewayHub.getStartupPolicy()); + + List gateways = gatewayHub.getGateways(); + + assertNotNull(gateways); + assertFalse(gateways.isEmpty()); + assertEquals(3, gateways.size()); + + Gateway gatewayOne = getGatewayById(gateways, "gateway1"); + + assertNotNull(gatewayOne); + assertEquals("gateway1", gatewayOne.getId()); + assertEquals(8, gatewayOne.getConcurrencyLevel()); + assertEquals(Gateway.OrderPolicy.THREAD, gatewayOne.getOrderPolicy()); + assertEquals(65536, gatewayOne.getSocketBufferSize()); + //assertEquals(75000, gatewayOne.getSocketReadTimeout()); + assertTrue(gatewayOne.getEndpoints() == null || gatewayOne.getEndpoints().isEmpty()); + + List gatewayEventListeners = gatewayOne.getListeners(); + + assertNotNull(gatewayEventListeners); + assertFalse(gatewayEventListeners.isEmpty()); + assertEquals(2, gatewayEventListeners.size()); + assertTrue(gatewayEventListeners.get(0) instanceof TestGatewayListener); + assertEquals("ListenerOne", gatewayEventListeners.get(0).toString()); + assertTrue(gatewayEventListeners.get(1) instanceof TestGatewayListener); + assertEquals("ListenerTwo", gatewayEventListeners.get(1).toString()); + + GatewayQueueAttributes gatewayQueueAttributes = gatewayOne.getQueueAttributes(); + + assertNotNull(gatewayQueueAttributes); + assertEquals(99, gatewayQueueAttributes.getAlertThreshold()); + assertTrue(gatewayQueueAttributes.getBatchConflation()); + assertEquals(3, gatewayQueueAttributes.getBatchSize()); + assertEquals(10, gatewayQueueAttributes.getBatchTimeInterval()); + assertEquals("TestGatewayQueueDiskStore", gatewayQueueAttributes.getDiskStoreName()); + assertFalse(gatewayQueueAttributes.getEnablePersistence()); + assertEquals(5, gatewayQueueAttributes.getMaximumQueueMemory()); + + Gateway gatewayTwo = getGatewayById(gateways, "gateway2"); + + assertNotNull(gatewayTwo); + assertEquals("gateway2", gatewayTwo.getId()); + assertEquals(Gateway.DEFAULT_CONCURRENCY_LEVEL, gatewayTwo.getConcurrencyLevel()); + assertNull(gatewayTwo.getOrderPolicy()); + assertEquals(Gateway.DEFAULT_SOCKET_BUFFER_SIZE, gatewayTwo.getSocketBufferSize()); + assertEquals(Gateway.DEFAULT_SOCKET_READ_TIMEOUT, gatewayTwo.getSocketReadTimeout()); + assertTrue(gatewayTwo.getListeners() == null || gatewayTwo.getListeners().isEmpty()); + + List gatewayEndpoints = gatewayTwo.getEndpoints(); + + assertNotNull(gatewayEndpoints); + assertFalse(gatewayEndpoints.isEmpty()); + assertEquals(2, gatewayEndpoints.size()); + + Gateway.Endpoint gatewayEndpointOne = (Gateway.Endpoint) gatewayEndpoints.get(0); + + assertEquals("endpoint1", gatewayEndpointOne.getId()); + assertEquals("localhost", gatewayEndpointOne.getHost()); + assertEquals(1234, gatewayEndpointOne.getPort()); + + Gateway.Endpoint gatewayEndpointTwo = (Gateway.Endpoint) gatewayEndpoints.get(1); + + assertEquals("endpoint2", gatewayEndpointTwo.getId()); + assertEquals("localhost", gatewayEndpointTwo.getHost()); + assertEquals(4321, gatewayEndpointTwo.getPort()); + + gatewayQueueAttributes = gatewayTwo.getQueueAttributes(); + + assertNotNull(gatewayQueueAttributes); + assertEquals(GatewayQueueAttributes.DEFAULT_ALERT_THRESHOLD, gatewayQueueAttributes.getAlertThreshold()); + assertFalse(gatewayQueueAttributes.getBatchConflation()); + assertEquals(6, gatewayQueueAttributes.getBatchSize()); + assertEquals(20, gatewayQueueAttributes.getBatchTimeInterval()); + assertNull(gatewayQueueAttributes.getDiskStoreName()); + assertTrue(gatewayQueueAttributes.getEnablePersistence()); + assertEquals(GatewayQueueAttributes.DEFAULT_MAXIMUM_QUEUE_MEMORY, gatewayQueueAttributes.getMaximumQueueMemory()); + + Gateway gatewayThree = getGatewayById(gateways, "gateway3"); + + assertNotNull(gatewayThree); + assertEquals("gateway3", gatewayThree.getId()); + assertEquals(Gateway.DEFAULT_CONCURRENCY_LEVEL, gatewayThree.getConcurrencyLevel()); + assertNull(gatewayThree.getOrderPolicy()); + assertEquals(Gateway.DEFAULT_SOCKET_BUFFER_SIZE, gatewayThree.getSocketBufferSize()); + assertEquals(Gateway.DEFAULT_SOCKET_READ_TIMEOUT, gatewayThree.getSocketReadTimeout()); + assertTrue(gatewayThree.getEndpoints() == null || gatewayThree.getEndpoints().isEmpty()); + + gatewayEventListeners = gatewayThree.getListeners(); + + assertNotNull(gatewayEventListeners); + assertFalse(gatewayEventListeners.isEmpty()); + assertEquals(1, gatewayEventListeners.size()); + assertTrue(gatewayEventListeners.get(0) instanceof TestGatewayListener); + assertEquals("ListenerTwo", gatewayEventListeners.get(0).toString()); + } + + public static final class TestGatewayListener implements GatewayEventListener { + + private String name; + + public void setName(final String name) { + this.name = name; + } + + @Override + public boolean processEvents(final List events) { + return false; + } + + @Override + public void close() { + } + + @Override + public String toString() { + return name; + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/AbstractMockerySupport.java b/src/test/java/org/springframework/data/gemfire/test/AbstractMockerySupport.java new file mode 100644 index 00000000..66d30828 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/AbstractMockerySupport.java @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test; + +import org.mockito.invocation.InvocationOnMock; +import org.springframework.data.gemfire.test.support.IdentifierSequence; +import org.springframework.data.gemfire.test.support.StackTraceUtils; + +/** + * The AbstractMockery class is an abstract base class supporting the creation and use of mock objects in unit tests. + * + * @author John Blum + * @see org.mockito.invocation.InvocationOnMock + * @see org.springframework.data.gemfire.test.support.IdentifierSequence + * @see org.springframework.data.gemfire.test.support.StackTraceUtils + * @since 1.5.3 + */ +@SuppressWarnings("unused") +public abstract class AbstractMockerySupport { + + protected static final String NOT_IMPLEMENTED = "Not Implemented"; + + protected Object getMockId() { + StackTraceElement element = StackTraceUtils.getTestCaller(); + return (element != null ? StackTraceUtils.getCallerSimpleName(element): IdentifierSequence.nextId()); + } + + protected T getArgumentAt(final InvocationOnMock invocation, final int index, final Class type) { + return type.cast(invocation.getArguments()[index]); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/MockGatewayFactory.java b/src/test/java/org/springframework/data/gemfire/test/MockGatewayFactory.java new file mode 100644 index 00000000..861dc24c --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/MockGatewayFactory.java @@ -0,0 +1,266 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.gemstone.gemfire.cache.util.Gateway; +import com.gemstone.gemfire.cache.util.GatewayEventListener; +import com.gemstone.gemfire.cache.util.GatewayQueueAttributes; + +/** + * The MockGatewayFactory class is a factory for creating mock GemFire Gateways, GatewayQueueAttributes + * and Gateway.Endpoints. + * + * @author John Blum + * @see org.mockito.Mockito + * @see org.springframework.data.gemfire.wan.GatewayHubFactoryBean + * @see com.gemstone.gemfire.cache.util.Gateway + * @see com.gemstone.gemfire.cache.util.GatewayHub + * @since 1.5.3 + */ +@SuppressWarnings({ "deprecation", "unused" }) +public class MockGatewayFactory extends AbstractMockerySupport { + + private Boolean batchConflation = GatewayQueueAttributes.DEFAULT_BATCH_CONFLATION; + private Boolean persistence = GatewayQueueAttributes.DEFAULT_ENABLE_PERSISTENCE; + + private Gateway.OrderPolicy orderPolicy; + + private GatewayQueueAttributes queueAttributes; + + private Integer alertThreshold = GatewayQueueAttributes.DEFAULT_ALERT_THRESHOLD; + private Integer batchSize = GatewayQueueAttributes.DEFAULT_BATCH_SIZE; + private Integer batchTimeInterval = GatewayQueueAttributes.DEFAULT_BATCH_TIME_INTERVAL; + private Integer maxQueueMemory = GatewayQueueAttributes.DEFAULT_MAXIMUM_QUEUE_MEMORY; + private Integer socketBufferSize = Gateway.DEFAULT_SOCKET_BUFFER_SIZE; + private Integer socketReadTimeout = Gateway.DEFAULT_SOCKET_READ_TIMEOUT; + + private List endpoints; + private List listeners; + + private String diskStoreName; + + public MockGatewayFactory() { + endpoints = new ArrayList(); + listeners = new ArrayList(); + queueAttributes = mockGatewayQueueAttributes(); + } + + public Gateway mockGateway(final String id, final int concurrencyLevel) { + Gateway mockGateway = mock(Gateway.class, String.format("%1$s.MockGateway", getMockId())); + + when(mockGateway.getConcurrencyLevel()).thenReturn(concurrencyLevel); + when(mockGateway.getEndpoints()).thenReturn(endpoints); + when(mockGateway.getId()).thenReturn(id); + when(mockGateway.getListeners()).thenReturn(listeners); + when(mockGateway.getQueueSize()).thenThrow(new UnsupportedOperationException(NOT_IMPLEMENTED)); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + orderPolicy = getArgumentAt(invocation, 0, Gateway.OrderPolicy.class); + return null; + } + }).when(mockGateway).setOrderPolicy(any(Gateway.OrderPolicy.class)); + + when(mockGateway.getOrderPolicy()).thenAnswer(new Answer() { + @Override public Gateway.OrderPolicy answer(final InvocationOnMock invocation) throws Throwable { + return orderPolicy; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + queueAttributes = getArgumentAt(invocation, 0, GatewayQueueAttributes.class); + return null; + } + }).when(mockGateway).setQueueAttributes(any(GatewayQueueAttributes.class)); + + when(mockGateway.getQueueAttributes()).thenAnswer(new Answer() { + @Override public GatewayQueueAttributes answer(final InvocationOnMock invocation) throws Throwable { + return queueAttributes; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + socketBufferSize = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockGateway).setSocketBufferSize(anyInt()); + + when(mockGateway.getSocketBufferSize()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return socketBufferSize; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + socketReadTimeout = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockGateway).setSocketReadTimeout(anyInt()); + + when(mockGateway.getSocketReadTimeout()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return socketReadTimeout; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + String id = getArgumentAt(invocation, 0, String.class); + String host = getArgumentAt(invocation, 1, String.class); + int port = getArgumentAt(invocation, 2, Integer.class); + endpoints.add(mockGatewayEndpoint(id, host, port)); + return null; + } + }).when(mockGateway).addEndpoint(anyString(), anyString(), anyInt()); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + listeners.add(getArgumentAt(invocation, 0, GatewayEventListener.class)); + return null; + } + }).when(mockGateway).addListener(any(GatewayEventListener.class)); + + return mockGateway; + } + + public Gateway.Endpoint mockGatewayEndpoint(final String id, final String host, final int port) { + Gateway.Endpoint mockEndpoint = mock(Gateway.Endpoint.class, + String.format("%1$s.MockGatewayEndpoint", getMockId())); + + when(mockEndpoint.getId()).thenReturn(id); + when(mockEndpoint.getHost()).thenReturn(host); + when(mockEndpoint.getPort()).thenReturn(port); + + return mockEndpoint; + } + + public GatewayQueueAttributes mockGatewayQueueAttributes() { + GatewayQueueAttributes mockQueueAttributes = mock(GatewayQueueAttributes.class, + String.format("%1$s.MockGatewayQueueAttributes", getMockId())); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + alertThreshold = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockQueueAttributes).setAlertThreshold(anyInt()); + + when(mockQueueAttributes.getAlertThreshold()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return alertThreshold; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + batchConflation = getArgumentAt(invocation, 0, Boolean.class); + return null; + } + }).when(mockQueueAttributes).setBatchConflation(anyBoolean()); + + when(mockQueueAttributes.getBatchConflation()).thenAnswer(new Answer() { + @Override public Boolean answer(final InvocationOnMock invocation) throws Throwable { + return batchConflation; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + batchSize = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockQueueAttributes).setBatchSize(anyInt()); + + when(mockQueueAttributes.getBatchSize()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return batchSize; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + batchTimeInterval = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockQueueAttributes).setBatchTimeInterval(anyInt()); + + when(mockQueueAttributes.getBatchTimeInterval()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return batchTimeInterval; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + diskStoreName = getArgumentAt(invocation, 0, String.class); + return null; + } + }).when(mockQueueAttributes).setDiskStoreName(anyString()); + + when(mockQueueAttributes.getDiskStoreName()).thenAnswer(new Answer() { + @Override public String answer(final InvocationOnMock invocation) throws Throwable { + return diskStoreName; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + persistence = getArgumentAt(invocation, 0, Boolean.class); + return null; + } + }).when(mockQueueAttributes).setEnablePersistence(anyBoolean()); + + when(mockQueueAttributes.getEnablePersistence()).thenAnswer(new Answer() { + @Override public Boolean answer(final InvocationOnMock invocation) throws Throwable { + return persistence; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + maxQueueMemory = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockQueueAttributes).setMaximumQueueMemory(anyInt()); + + when(mockQueueAttributes.getMaximumQueueMemory()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return maxQueueMemory; + } + }); + + return mockQueueAttributes; + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/MockGatewayHubFactory.java b/src/test/java/org/springframework/data/gemfire/test/MockGatewayHubFactory.java new file mode 100644 index 00000000..04684374 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/MockGatewayHubFactory.java @@ -0,0 +1,166 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test; + +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.gemstone.gemfire.cache.util.Gateway; +import com.gemstone.gemfire.cache.util.GatewayHub; + +/** + * The MockGatewayHubFactory class is a factory for creating mock GemFire GatewayHubs. + * + * @author John Blum + * @see org.mockito.Mockito + * @see org.springframework.data.gemfire.test.AbstractMockerySupport + * @see org.springframework.data.gemfire.wan.GatewayHubFactoryBean + * @see com.gemstone.gemfire.cache.util.Gateway + * @see com.gemstone.gemfire.cache.util.GatewayHub + * @since 1.5.3 + */ +@SuppressWarnings({ "deprecation", "unused" }) +public class MockGatewayHubFactory extends AbstractMockerySupport { + + private static final AtomicLong ID_SEQUENCE = new AtomicLong(System.currentTimeMillis()); + + private Boolean manualStart = GatewayHub.DEFAULT_MANUAL_START; + + private Integer maximumTimeBetweenPings = GatewayHub.DEFAULT_MAXIMUM_TIME_BETWEEN_PINGS; + private Integer socketBufferSize = GatewayHub.DEFAULT_SOCKET_BUFFER_SIZE; + + private List gateways = new ArrayList(); + + private String bindAddress = GatewayHub.DEFAULT_BIND_ADDRESS; + private String startupPolicy = GatewayHub.DEFAULT_STARTUP_POLICY; + + public GatewayHub mockGatewayHub(final String id, final int port) { + final GatewayHub mockGatewayHub = mock(GatewayHub.class, String.format("%1$s.MockGatewayHub", getMockId())); + + when(mockGatewayHub.getGateways()).thenReturn(gateways); + when(mockGatewayHub.getGatewayIds()).thenReturn(getGatewayIds(gateways)); + when(mockGatewayHub.getId()).thenReturn(id); + when(mockGatewayHub.getPort()).thenReturn(port); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + bindAddress = getArgumentAt(invocation, 0, String.class); + return null; + } + }).when(mockGatewayHub).setBindAddress(anyString()); + + when(mockGatewayHub.getBindAddress()).thenAnswer(new Answer() { + @Override public String answer(final InvocationOnMock invocation) throws Throwable { + return bindAddress; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + manualStart = getArgumentAt(invocation, 0, Boolean.class); + return null; + } + }).when(mockGatewayHub).setManualStart(anyBoolean()); + + when(mockGatewayHub.getManualStart()).thenAnswer(new Answer() { + @Override public Boolean answer(final InvocationOnMock invocation) throws Throwable { + return manualStart; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + maximumTimeBetweenPings = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockGatewayHub).setMaximumTimeBetweenPings(anyInt()); + + when(mockGatewayHub.getMaximumTimeBetweenPings()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return maximumTimeBetweenPings; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + socketBufferSize = getArgumentAt(invocation, 0, Integer.class); + return null; + } + }).when(mockGatewayHub).setSocketBufferSize(anyInt()); + + when(mockGatewayHub.getSocketBufferSize()).thenAnswer(new Answer() { + @Override public Integer answer(final InvocationOnMock invocation) throws Throwable { + return socketBufferSize; + } + }); + + doAnswer(new Answer() { + @Override public Void answer(final InvocationOnMock invocation) throws Throwable { + startupPolicy = getArgumentAt(invocation, 0, String.class); + return null; + } + }).when(mockGatewayHub).setStartupPolicy(anyString()); + + when(mockGatewayHub.getStartupPolicy()).thenAnswer(new Answer() { + @Override public String answer(final InvocationOnMock invocation) throws Throwable { + return startupPolicy; + } + }); + + when(mockGatewayHub.addGateway(anyString())).thenAnswer(new Answer() { + @Override public Gateway answer(final InvocationOnMock invocation) throws Throwable { + String id = getArgumentAt(invocation, 0, String.class); + return mockGatewayHub.addGateway(id, Gateway.DEFAULT_CONCURRENCY_LEVEL); + } + }); + + when(mockGatewayHub.addGateway(anyString(), anyInt())).thenAnswer(new Answer() { + @Override public Gateway answer(final InvocationOnMock invocation) throws Throwable { + String id = getArgumentAt(invocation, 0, String.class); + Integer concurrencyLevel = getArgumentAt(invocation, 1, Integer.class); + Gateway mockGateway = new MockGatewayFactory().mockGateway(id, concurrencyLevel); + when(mockGateway.getGatewayHubId()).thenReturn(id); + gateways.add(mockGateway); + return mockGateway; + } + }); + + return mockGatewayHub; + } + + private List getGatewayIds(final List gateways) { + List gatewayIds = new ArrayList(gateways.size()); + + for (Gateway gateway : gateways) { + gatewayIds.add(gateway.getId()); + } + + return gatewayIds; + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/StubCache.java b/src/test/java/org/springframework/data/gemfire/test/StubCache.java index ca76a482..2b4d0cf1 100644 --- a/src/test/java/org/springframework/data/gemfire/test/StubCache.java +++ b/src/test/java/org/springframework/data/gemfire/test/StubCache.java @@ -411,8 +411,11 @@ public class StubCache implements Cache { * @see com.gemstone.gemfire.cache.Cache#addGatewayHub(java.lang.String, int) */ @Override - public GatewayHub addGatewayHub(String name, int port) { - return mockGatewayHub(); + public GatewayHub addGatewayHub(String id, int port) { + GatewayHub gatewayHub = getGatewayHub(id); + gatewayHub = (gatewayHub != null ? gatewayHub : new MockGatewayHubFactory().mockGatewayHub(id, port)); + gatewayHubs.add(gatewayHub); + return gatewayHub; } /* (non-Javadoc) @@ -557,15 +560,21 @@ public class StubCache implements Cache { @Override @Deprecated public GatewayHub getGatewayHub() { - return mockGatewayHub(); + return (gatewayHubs.isEmpty() ? null : gatewayHubs.get(0)); } /* (non-Javadoc) * @see com.gemstone.gemfire.cache.Cache#getGatewayHub(java.lang.String) */ @Override - public GatewayHub getGatewayHub(String name) { - return mockGatewayHub(); + public GatewayHub getGatewayHub(String id) { + for (GatewayHub gatewayHub : gatewayHubs) { + if (gatewayHub.getId().equals(id)) { + return gatewayHub; + } + } + + return null; } /* (non-Javadoc) diff --git a/src/test/java/org/springframework/data/gemfire/test/support/IdentifierSequence.java b/src/test/java/org/springframework/data/gemfire/test/support/IdentifierSequence.java new file mode 100644 index 00000000..d541b6b8 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/IdentifierSequence.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test.support; + +import java.util.concurrent.atomic.AtomicLong; + +/** + * The IdentifierSequence class is an Identifier (ID) generator generating unique IDs in sequence. + * + * @author John Blum + * @see java.lang.System#currentTimeMillis() + * @see java.util.concurrent.atomic.AtomicLong + * @since 1.5.3 + */ +@SuppressWarnings("unused") +public abstract class IdentifierSequence { + + private static final AtomicLong ID_SEQUENCE = new AtomicLong(System.currentTimeMillis()); + + public static long nextId() { + return ID_SEQUENCE.incrementAndGet(); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/StackTraceUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/StackTraceUtils.java new file mode 100644 index 00000000..35c8ec3f --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/StackTraceUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test.support; + +/** + * The StackTraceUtils class is a utility class for working with stack trace frames (elements) of the current Thread. + * + * @author John Blum + * @see java.lang.StackTraceElement + * @see java.lang.Thread + * @see org.springframework.data.gemfire.test.support.ThreadUtils + * @since 1.5.3 + */ +@SuppressWarnings("unused") +public abstract class StackTraceUtils extends ThreadUtils { + + public static StackTraceElement getCaller() { + return getCaller(Thread.currentThread()); + } + + public static StackTraceElement getCaller(final Thread thread) { + return thread.getStackTrace()[2]; + } + + public static String getCallerName(final StackTraceElement element) { + return String.format("%1$%s.%2$s", element.getClass().getName(), element.getMethodName()); + } + + public static String getCallerSimpleName(final StackTraceElement element) { + return String.format("%1$%s.%2$s", element.getClass().getSimpleName(), element.getMethodName()); + } + + public static StackTraceElement getTestCaller() { + return getTestCaller(Thread.currentThread()); + } + + public static StackTraceElement getTestCaller(final Thread thread) { + for (StackTraceElement stackTraceElement : thread.getStackTrace()) { + if (isTestSuiteClass(stackTraceElement) && isTestCaseMethod(stackTraceElement)) { + return stackTraceElement; + } + } + + return null; + } + + private static boolean isTestCaseMethod(final StackTraceElement element) { + boolean result = element.getMethodName().toLowerCase().startsWith("test"); + + try { + result |= element.getClass().getMethod(element.getMethodName()).isAnnotationPresent(org.junit.Test.class); + } + catch (NoSuchMethodException ignore) { + } + + return result; + } + + private static boolean isTestSuiteClass(final StackTraceElement element) { + boolean result = element.getClass().getSimpleName().toLowerCase().endsWith("test"); + result |= element.getClass().isAssignableFrom(junit.framework.TestCase.class); + return result; + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java new file mode 100644 index 00000000..d2318079 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.test.support; + +import java.util.concurrent.TimeUnit; + +/** + * The ThreadUtils class is a utility class for working with Java Threads. + * + * @author John Blum + * @see java.lang.Thread + * @since 1.5.0 + */ +@SuppressWarnings("unused") +public abstract class ThreadUtils { + + public static boolean sleep(final long milliseconds) { + try { + Thread.sleep(milliseconds); + return true; + } + catch (InterruptedException ignore) { + return false; + } + } + + public static void timedWait(final long milliseconds) { + timedWait(milliseconds, milliseconds); + } + + public static void timedWait(final long milliseconds, final long interval) { + timedWait(milliseconds, interval, new WaitCondition() { + @Override public boolean waiting() { + return true; + } + }); + } + + public static void timedWait(final long milliseconds, long interval, final WaitCondition waitCondition) { + final long timeout = (System.currentTimeMillis() + milliseconds); + + interval = Math.min(interval, milliseconds); + + while (waitCondition.waiting() && (System.currentTimeMillis() < timeout)) { + try { + synchronized (waitCondition) { + TimeUnit.MILLISECONDS.timedWait(waitCondition, interval); + } + } + catch (InterruptedException ignore) { + } + } + } + + public static interface WaitCondition { + boolean waiting(); + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/config/GatewayHubNamespaceTest-context.xml b/src/test/resources/org/springframework/data/gemfire/config/GatewayHubNamespaceTest-context.xml new file mode 100644 index 00000000..648a9936 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/GatewayHubNamespaceTest-context.xml @@ -0,0 +1,50 @@ + + + + + GatewayHubNamespaceTest + 0 + warning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +