diff --git a/src/main/java/org/springframework/data/gemfire/listener/ContinuousQueryListenerContainer.java b/src/main/java/org/springframework/data/gemfire/listener/ContinuousQueryListenerContainer.java index abff3d47..0ceee030 100644 --- a/src/main/java/org/springframework/data/gemfire/listener/ContinuousQueryListenerContainer.java +++ b/src/main/java/org/springframework/data/gemfire/listener/ContinuousQueryListenerContainer.java @@ -54,23 +54,28 @@ import org.springframework.util.ErrorHandler; import org.springframework.util.StringUtils; /** - * Container providing asynchronous behaviour for GemFire continuous queries. + * Container providing asynchronous behaviour for GemFire Continuous Queries (CQ). * * @author Costin Leau * @author John Blum + * @see org.apache.geode.cache.RegionService + * @see org.apache.geode.cache.client.Pool + * @see org.apache.geode.cache.client.PoolManager + * @see org.apache.geode.cache.query.CqAttributes + * @see org.apache.geode.cache.query.CqEvent + * @see org.apache.geode.cache.query.CqListener + * @see org.apache.geode.cache.query.CqQuery + * @see org.apache.geode.cache.query.QueryService + * @see org.springframework.beans.factory.BeanFactory + * @see org.springframework.beans.factory.BeanFactoryAware * @see org.springframework.beans.factory.BeanNameAware * @see org.springframework.beans.factory.DisposableBean * @see org.springframework.beans.factory.InitializingBean * @see org.springframework.context.SmartLifecycle * @see org.springframework.core.task.SimpleAsyncTaskExecutor * @see org.springframework.core.task.TaskExecutor - * @see org.apache.geode.cache.RegionService - * @see org.apache.geode.cache.client.Pool - * @see org.apache.geode.cache.client.PoolManager - * @see org.apache.geode.cache.query.CqEvent - * @see org.apache.geode.cache.query.CqListener - * @see org.apache.geode.cache.query.CqQuery - * @see org.apache.geode.cache.query.QueryService + * @see org.springframework.data.gemfire.client.support.DefaultableDelegatingPoolAdapter + * @see org.springframework.data.gemfire.client.support.DelegatingPoolAdapter */ @SuppressWarnings("unused") public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanNameAware, @@ -136,8 +141,8 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN } } catch (BeansException ignore) { - Assert.notNull(PoolManager.find(poolName), String.format("No GemFire Pool with name [%s] was found", - poolName)); + Assert.notNull(PoolManager.find(poolName), + String.format("No GemFire Pool with name [%s] was found", poolName)); } return poolName; @@ -213,7 +218,7 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN cq.execute(); } catch (QueryException e) { - throw new GemfireQueryException(String.format("Could not execute query [%1$s]; state is [%2$s].", + throw new GemfireQueryException(String.format("Could not execute query [%1$s]; state is [%2$s]", cq.getName(), cq.getState()), e); } } @@ -242,7 +247,7 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN cq.stop(); } catch (Exception e) { - logger.warn(String.format("Cannot stop query '%1$s'; state is '%2$s.", cq.getName(), cq.getState()), e); + logger.warn(String.format("Cannot stop query [%1$s]; state is [%2$s]", cq.getName(), cq.getState()), e); } } } @@ -263,7 +268,7 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN } } catch (Exception e) { - logger.warn(String.format("Cannot close query '%1$s'; state is '%2$s.", + logger.warn(String.format("Cannot close query [%1$s]; state is [%2$s]", cq.getName(), cq.getState()), e); } } @@ -465,16 +470,12 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN return cq; } catch (QueryException e) { - throw new GemfireQueryException("Cannot create query ", e); + throw new GemfireQueryException("Cannot create query", e); } } private void dispatchEvent(final ContinuousQueryListener listener, final CqEvent event) { - taskExecutor.execute(new Runnable() { - public void run() { - executeListener(listener, event); - } - }); + taskExecutor.execute(() -> executeListener(listener, event)); } /** @@ -532,7 +533,7 @@ public class ContinuousQueryListenerContainer implements BeanFactoryAware, BeanN private final ContinuousQueryListener delegate; - private EventDispatcherAdapter(final ContinuousQueryListener delegate) { + private EventDispatcherAdapter(ContinuousQueryListener delegate) { this.delegate = delegate; } diff --git a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java index c0f24e0c..77cbeafc 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java @@ -132,8 +132,8 @@ public class CacheClusterConfigurationIntegrationTest { arguments.add("-Dgemfire.name=" + locatorName); arguments.add("-Dgemfire.mcast-port=0"); arguments.add("-Dgemfire.log-level=error"); - arguments.add("-Dspring.gemfire.enable-cluster-configuration=true"); - arguments.add("-Dspring.gemfire.load-cluster-configuration=true"); + arguments.add("-Dspring.data.gemfire.enable-cluster-configuration=true"); + arguments.add("-Dspring.data.gemfire.load-cluster-configuration=true"); locatorProcess = ProcessExecutor.launch(locatorWorkingDirectory, LocatorProcess.class, arguments.toArray(new String[arguments.size()])); diff --git a/src/test/java/org/springframework/data/gemfire/ForkUtil.java b/src/test/java/org/springframework/data/gemfire/ForkUtil.java index 82bdd352..51f2188a 100644 --- a/src/test/java/org/springframework/data/gemfire/ForkUtil.java +++ b/src/test/java/org/springframework/data/gemfire/ForkUtil.java @@ -27,14 +27,17 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import org.springframework.data.gemfire.fork.CacheServerProcess; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.gemfire.fork.CqCacheServerProcess; +import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; import org.springframework.data.gemfire.test.support.IOUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.util.StringUtils; /** - * Utility for forking Java processes. - * + * Utility class used to fork Java, JVM processes. + * * @author Costin Leau * @author John Blum * @deprecated ForkUtils has serious design flaws; please use ProcessExecutor instead @@ -42,6 +45,11 @@ import org.springframework.util.StringUtils; @Deprecated public class ForkUtil { + private static final long TIMEOUT = 30000L; + + @SuppressWarnings("all") + private static final Logger logger = LoggerFactory.getLogger(ForkUtil.class); + private static OutputStream processStandardInStream; private static String JAVA_CLASSPATH = System.getProperty("java.class.path"); @@ -49,115 +57,131 @@ public class ForkUtil { private static String JAVA_EXE = JAVA_HOME.concat(File.separator).concat("bin").concat(File.separator).concat("java"); private static String TEMP_DIRECTORY = System.getProperty("java.io.tmpdir"); - private static OutputStream cloneJVM(final String arguments) { - String[] args = arguments.split("\\s+"); + private static List buildJavaCommand(String arguments) { + return buildJavaCommand(arguments.split("\\s+")); + } - List command = new ArrayList(args.length + 3); + private static List buildJavaCommand(String[] args) { + List command = new ArrayList<>(args.length + 5); command.add(JAVA_EXE); + command.add("-server"); + command.add("-ea"); command.add("-classpath"); command.add(JAVA_CLASSPATH); command.addAll(Arrays.asList(args)); + return command; + } + + private static OutputStream cloneJVM(String arguments) { + AtomicBoolean runCondition = new AtomicBoolean(true); + + List command = buildJavaCommand(arguments); + Process javaProcess; try { javaProcess = Runtime.getRuntime().exec(command.toArray(new String[command.size()])); + + logger.debug("Started fork from command: {}", + StringUtils.arrayToDelimitedString(command.toArray()," ")); + + captureProcessStreams(runCondition, javaProcess); + registerShutdownHook(runCondition, javaProcess); + + processStandardInStream = javaProcess.getOutputStream(); + + return processStandardInStream; } catch (IOException e) { - System.out.println("[FORK-ERROR] " + e.getMessage()); - throw new IllegalStateException(String.format("Cannot start command %1$s", + throw new RuntimeException(String.format("Failed to fork JVM process using command [%s]", StringUtils.arrayToDelimitedString(command.toArray(), " ")), e); } - - System.out.println("Started fork from command: \n" + StringUtils.arrayToDelimitedString(command.toArray()," ")); - - final AtomicBoolean runCondition = new AtomicBoolean(true); - final Process p = javaProcess; - - startNewThread(newProcessStreamReader(runCondition, p.getErrorStream(), "[FORK-ERROR]")); - startNewThread(newProcessStreamReader(runCondition, p.getInputStream(), "[FORK]")); - - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - runCondition.set(false); - processStandardInStream = null; - - try { - p.destroy(); - p.waitFor(); - } - catch (InterruptedException ignore) { - } - } - }); - - processStandardInStream = javaProcess.getOutputStream(); - - return processStandardInStream; } - protected static Thread startNewThread(final Runnable runnable) { + private static void captureProcessStreams(AtomicBoolean runCondition, Process javaProcess) { + startNewThread(newProcessStreamReader(runCondition, javaProcess.getErrorStream(), "[FORK-ERR]")); + startNewThread(newProcessStreamReader(runCondition, javaProcess.getInputStream(), "[FORK-OUT]")); + } + + private static Thread startNewThread(Runnable runnable) { Thread runnableThread = new Thread(runnable); + runnableThread.setDaemon(true); + runnableThread.setPriority(Thread.NORM_PRIORITY); runnableThread.start(); return runnableThread; } - protected static Runnable newProcessStreamReader(final AtomicBoolean runCondition, final InputStream processStream, final String label) { - return new Runnable() { - public void run() { - BufferedReader processStreamReader = new BufferedReader(new InputStreamReader(processStream)); - try { - while (runCondition.get()) { - for (String line = "Reading..."; line != null; line = processStreamReader.readLine()) { - System.out.printf("%1$s %2$s%n ", label, line); - } - } - } - catch (Exception ignore) { - } - finally { - IOUtils.close(processStreamReader); + private static Runnable newProcessStreamReader(AtomicBoolean runCondition, InputStream processStream, String label) { + return () -> { + BufferedReader processStreamReader = null; + + try { + processStreamReader = new BufferedReader(new InputStreamReader(processStream)); + + for (String line = "Reading..."; runCondition.get() && line != null; + line = processStreamReader.readLine()) { + + logger.debug("{} {}", label, line); } } + catch (Exception ignore) { + } + finally { + IOUtils.close(processStreamReader); + } }; } - public static OutputStream cacheServer() { - return cacheServer(CacheServerProcess.class); + private static void registerShutdownHook(AtomicBoolean runCondition, Process javaProcess) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + runCondition.set(false); + processStandardInStream = null; + + try { + javaProcess.destroyForcibly(); + javaProcess.waitFor(); + } + catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } + })); } public static OutputStream cacheServer(Class type) { return startCacheServer(type.getName()); } + public static OutputStream cqCacheServer() { + return cacheServer(CqCacheServerProcess.class); + } + + public static OutputStream functionCacheServer() { + return cacheServer(FunctionCacheServerProcess.class); + } + public static OutputStream startCacheServer(String args) { return startGemFireProcess(args, "cache server"); } - protected static OutputStream startGemFireProcess(final String args, final String processName) { + protected static OutputStream startGemFireProcess(String args, String processName) { String className = args.split(" ")[0]; - System.out.println("main class: " + className); - if (controlFileExists(className)) { deleteControlFile(className); } OutputStream outputStream = cloneJVM(args); - final long timeout = System.currentTimeMillis() + 30000; + long timeout = (System.currentTimeMillis() + TIMEOUT); while (!controlFileExists(className) && System.currentTimeMillis() < timeout) { - ThreadUtils.sleep(500); + ThreadUtils.sleep(500L); } - if (controlFileExists(className)) { - System.out.printf("[FORK] Started %1$s%n", processName); - } - else { - throw new RuntimeException(String.format("Failed to fork %1$s", processName)); + if (!controlFileExists(className)) { + throw new RuntimeException(String.format("Failed to fork %s", processName)); } return outputStream; @@ -168,21 +192,20 @@ public class ForkUtil { processStandardInStream.write("\n".getBytes()); processStandardInStream.flush(); } - catch (IOException ex) { - throw new IllegalStateException("Cannot communicate with forked VM", ex); + catch (IOException e) { + logger.info("Cannot communicate with forked VM", e); } } - public static boolean createControlFile(final String name) throws IOException { + public static boolean createControlFile( String name) throws IOException { return new File(TEMP_DIRECTORY + File.separator + name).createNewFile(); } - public static boolean controlFileExists(final String name) { + public static boolean controlFileExists(String name) { return new File(TEMP_DIRECTORY + File.separator + name).isFile(); } - public static boolean deleteControlFile(final String name) { + public static boolean deleteControlFile(String name) { return new File(TEMP_DIRECTORY + File.separator + name).delete(); } - } diff --git a/src/test/java/org/springframework/data/gemfire/GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests.java index f81accb3..ffed594d 100644 --- a/src/test/java/org/springframework/data/gemfire/GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests.java @@ -86,8 +86,6 @@ import lombok.RequiredArgsConstructor; public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationTests extends ClientServerIntegrationTestsSupport{ - protected static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning"; - private static ProcessWrapper serverOne; private static ProcessWrapper serverTwo; @@ -160,7 +158,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT } String logLevel() { - return System.getProperty("gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); + return System.getProperty("spring.data.gemfire.log.level", GEMFIRE_LOG_LEVEL); } @Bean @@ -268,7 +266,7 @@ public class GemfireTemplateQueriesOnGroupedPooledClientCacheRegionsIntegrationT abstract String groups(); String logLevel() { - return System.getProperty("gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); + return System.getProperty("spring.data.gemfire.log.level", GEMFIRE_LOG_LEVEL); } String startLocator() { diff --git a/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java index 46eb283f..1d8711e1 100644 --- a/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/RegionLookupIntegrationTests.java @@ -30,6 +30,7 @@ import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.data.gemfire.fork.SpringContainerProcess; /** * The RegionLookupIntegrationTests class is a test suite of test cases testing the lookup functionality for various @@ -38,7 +39,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * @author John Blum * @see org.junit.Test * @see org.springframework.context.ConfigurableApplicationContext - * @see org.springframework.data.gemfire.fork.SpringCacheServerProcess + * @see SpringContainerProcess * @see org.apache.geode.cache.Region * @since 1.4.0 * @link https://jira.spring.io/browse/SGF-204 diff --git a/src/test/java/org/springframework/data/gemfire/cache/CompoundCachePutCacheEvictIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/cache/CompoundCachePutCacheEvictIntegrationTests.java index cd206e91..379a52d0 100644 --- a/src/test/java/org/springframework/data/gemfire/cache/CompoundCachePutCacheEvictIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/cache/CompoundCachePutCacheEvictIntegrationTests.java @@ -217,10 +217,11 @@ public class CompoundCachePutCacheEvictIntegrationTests { } String logLevel() { - return System.getProperty("gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); + return System.getProperty("spring.data.gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); } - @Bean CacheFactoryBean gemfireCache() { + @Bean + CacheFactoryBean gemfireCache() { CacheFactoryBean gemfireCache = new CacheFactoryBean(); gemfireCache.setClose(true); @@ -229,7 +230,8 @@ public class CompoundCachePutCacheEvictIntegrationTests { return gemfireCache; } - @Bean(name = "People") LocalRegionFactoryBean peopleRegion(GemFireCache gemfireCache) { + @Bean(name = "People") + LocalRegionFactoryBean peopleRegion(GemFireCache gemfireCache) { LocalRegionFactoryBean peopleRegion = new LocalRegionFactoryBean(); peopleRegion.setCache(gemfireCache); diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests.java new file mode 100644 index 00000000..d6bdb674 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests.java @@ -0,0 +1,128 @@ +/* + * 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.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import javax.annotation.Resource; + +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.gemfire.GemfireTemplate; +import org.springframework.data.gemfire.fork.ServerProcess; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Integration test testing {@link Region sub-Region} functionality from a GemFire cache client. + * + * @author John Blum + * @see org.junit.Test + * @see org.junit.runner.RunWith + * @see org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport + * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.junit4.SpringRunner + * @since 1.4.0 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@SuppressWarnings("unused") +public class ClientSubRegionIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; + + @Autowired + private ClientCache clientCache; + + @Resource(name = "parentTemplate") + private GemfireTemplate parentTemplate; + + @Resource(name = "childTemplate") + private GemfireTemplate childTemplate; + + @Resource(name = "Parent") + private Region parent; + + @Resource(name = "/Parent/Child") + private Region child; + + @BeforeClass + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(ServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort), + getServerContextXmlFileLocation(ClientSubRegionIntegrationTests.class)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + protected void assertRegion(Region region, String name) { + assertRegion(region, name, String.format("%1$s%2$s", Region.SEPARATOR, name)); + } + + protected void assertRegion(Region region, String name, String fullPath) { + assertThat(region).isNotNull(); + assertThat(region.getName()).isEqualTo(name); + assertThat(region.getFullPath()).isEqualTo(fullPath); + } + @Test + public void gemFireSubRegionCreationConfigurationIsCorrect() { + assertThat(clientCache).describedAs("The Client Cache was not properly initialized!").isNotNull(); + + Region parent = clientCache.getRegion("Parent"); + + assertRegion(parent, "Parent"); + + Region child = parent.getSubregion("Child"); + + assertRegion(child, "Child", "/Parent/Child"); + + Region clientCacheChild = clientCache.getRegion("/Parent/Child"); + + assertThat(child).isSameAs(clientCacheChild); + } + + @Test + public void springSubRegionCreationConfigurationIsCorrect() { + assertRegion(parent, "Parent"); + assertRegion(child, "Child", "/Parent/Child"); + } + + @Test + public void templateCreationConfigurationIsCorrect() { + assertThat(parentTemplate).isNotNull(); + assertThat(parentTemplate.getRegion()).isSameAs(parent); + assertThat(childTemplate).isNotNull(); + assertThat(childTemplate.getRegion()).isSameAs(child); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionTest.java b/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionTest.java deleted file mode 100644 index 6d48a912..00000000 --- a/src/test/java/org/springframework/data/gemfire/client/ClientSubRegionTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.client; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - -import javax.annotation.Resource; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.GemfireTemplate; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * The ClientSubRegionTest class is a test suite of test cases testing SubRegion functionality from a client - * GemFire Cache. - * - * @author John Blum - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @since 1.4.0 - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("clientcache-with-subregion-config.xml") -@SuppressWarnings("unused") -public class ClientSubRegionTest { - - @Autowired - private ClientCache clientCache; - - @Resource(name = "parentTemplate") - private GemfireTemplate parentTemplate; - - @Resource(name = "childTemplate") - private GemfireTemplate childTemplate; - - @Resource(name = "Parent") - private Region parent; - - @Resource(name = "/Parent/Child") - private Region child; - - @BeforeClass - public static void startCacheServer() throws Exception { - ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " - + "/org/springframework/data/gemfire/client/servercache-with-region-for-client.xml"); - } - - @Test - public void testGemFireSubRegionCreationConfiguration() { - assertNotNull("The Client Cache was not properly initialized!", clientCache); - - Region parent = clientCache.getRegion("Parent"); - - assertNotNull(parent); - assertEquals("Parent", parent.getName()); - assertEquals("/Parent", parent.getFullPath()); - - Region child = parent.getSubregion("Child"); - - assertNotNull(child); - assertEquals("Child", child.getName()); - assertEquals("/Parent/Child", child.getFullPath()); - - Region clientCacheChild = clientCache.getRegion("/Parent/Child"); - - assertSame(child, clientCacheChild); - } - - @Test - public void testSpringSubRegionCreationConfiguration() { - assertNotNull(parent); - assertEquals("Parent", parent.getName()); - assertEquals("/Parent", parent.getFullPath()); - assertNotNull(child); - assertEquals("Child", child.getName()); - assertEquals("/Parent/Child", child.getFullPath()); - } - - @Test - public void testTemplateCreationConfiguration() { - assertNotNull(parentTemplate); - assertSame(parent, parentTemplate.getRegion()); - assertNotNull(childTemplate); - assertSame(child, childTemplate.getRegion()); - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java new file mode 100644 index 00000000..f9eb9288 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests.java @@ -0,0 +1,111 @@ +/* + * Copyright 2002-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.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; + +import org.apache.geode.cache.DataPolicy; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.Pool; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.fork.ServerProcess; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.repository.sample.Person; +import org.springframework.data.gemfire.repository.sample.PersonRepository; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Integration tests for a GemFire DataSource. + * + * @author David Turanski + * @author John Blum + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +public class GemFireDataSourceIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; + + @Autowired + private ApplicationContext applicationContext; + + @BeforeClass + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(ServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort), + getServerContextXmlFileLocation(GemFireDataSourceIntegrationTests.class)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + protected void assertRegion(Region region, String name, DataPolicy dataPolicy) { + assertRegion(region, name, String.format("%1$s%2$s", Region.SEPARATOR, "simple"), dataPolicy); + } + + protected void assertRegion(Region region, String name, String fullPath, DataPolicy dataPolicy) { + assertThat(region).isNotNull(); + assertThat(region.getName()).isEqualTo(name); + assertThat(region.getFullPath()).isEqualTo(fullPath); + assertThat(region.getAttributes()).isNotNull(); + assertThat(region.getAttributes().getDataPolicy()).isEqualTo(dataPolicy); + } + + @Test + @SuppressWarnings("unused") + public void gemfireServerDataSourceCreated() { + Pool pool = applicationContext.getBean("gemfirePool", Pool.class); + + assertThat(pool).isNotNull(); + assertThat(pool.getSubscriptionEnabled()).isTrue(); + + List regionList = Arrays.asList(applicationContext.getBeanNamesForType(Region.class)); + + assertThat(regionList).hasSize(3); + assertThat(regionList.contains("r1")).isTrue(); + assertThat(regionList.contains("r2")).isTrue(); + assertThat(regionList.contains("simple")).isTrue(); + + Region simple = applicationContext.getBean("simple", Region.class); + + assertRegion(simple, "simple", DataPolicy.EMPTY); + } + + @Test + public void repositoryCreatedAndFunctional() { + PersonRepository repo = applicationContext.getBean(PersonRepository.class); + Person daveMathhews = new Person(1L, "Dave", "Mathhews"); + + assertThat(repo.save(daveMathhews)).isSameAs(daveMathhews); + assertThat(repo.findOne(1L).getFirstname()).isEqualTo("Dave"); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java deleted file mode 100644 index ce7b16b4..00000000 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2002-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.client; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.Pool; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; -import org.springframework.data.gemfire.repository.sample.Person; -import org.springframework.data.gemfire.repository.sample.PersonRepository; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author David Turanski - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("/org/springframework/data/gemfire/client/datasource-client.xml") -public class GemFireDataSourceTest { - @Autowired - ApplicationContext ctx; - - @BeforeClass - public static void startUp() throws Exception { - ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " - + "/org/springframework/data/gemfire/client/datasource-server.xml"); - } - - @SuppressWarnings("unused") - @Test - public void testServerDataSource() { - Cache cache = ctx.getBean("gemfireCache", Cache.class); - Pool pool = ctx.getBean("gemfirePool", Pool.class); - assertEquals(true, pool.getSubscriptionEnabled()); - - String regions[] = ctx.getBeanNamesForType(Region.class); - List regionList = Arrays.asList(regions); - assertTrue(regionList.contains("r1")); - assertTrue(regionList.contains("r2")); - assertTrue(regionList.contains("simple")); - - Region simple = ctx.getBean("simple", Region.class); - assertEquals(DataPolicy.EMPTY, simple.getAttributes().getDataPolicy()); - } - - @Test - public void testRepositoryCreated() { - PersonRepository repo = ctx.getBean(PersonRepository.class); - Person dave = new Person(1L, "Dave", "Mathhews"); - repo.save(dave); - Person saved = repo.findOne(1L); - assertEquals("Dave", saved.getFirstname()); - } - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java deleted file mode 100644 index b98d546d..00000000 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceWithLocalRegionTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2002-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.client; - -import static org.junit.Assert.assertEquals; - -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.Region; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author David Turanski - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("/org/springframework/data/gemfire/client/datasource-client-with-regions.xml") -public class GemFireDataSourceWithLocalRegionTest { - @Autowired - ApplicationContext ctx; - - @BeforeClass - public static void startUp() throws Exception { - ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " - + "/org/springframework/data/gemfire/client/datasource-server.xml"); - } - - - @Test - public void testRegionDefinitionNotOverridden() { - Region simple = ctx.getBean("simple",Region.class); - assertEquals(DataPolicy.NORMAL, - simple.getAttributes().getDataPolicy()); - } - - - - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java index b6409123..c654fd96 100644 --- a/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java @@ -90,7 +90,7 @@ public class LocalOnlyClientCacheIntegrationTest { } @Bean - Properties gemfireProperties(@Value("${spring.gemfire.log.level:warning}") String logLevel) { + Properties gemfireProperties(@Value("${spring.data.gemfire.log.level:warning}") String logLevel) { Properties gemfireProperties = new Properties(); gemfireProperties.setProperty("name", LocalOnlyClientCacheIntegrationTest.class.getSimpleName()); @@ -114,7 +114,7 @@ public class LocalOnlyClientCacheIntegrationTest { ClientRegionFactoryBean exampleRegion(GemFireCache gemfireCache, RegionAttributes exampleAttributes) { - ClientRegionFactoryBean exampleRegion = new ClientRegionFactoryBean(); + ClientRegionFactoryBean exampleRegion = new ClientRegionFactoryBean<>(); exampleRegion.setCache(gemfireCache); exampleRegion.setAttributes(exampleAttributes); @@ -136,5 +136,4 @@ public class LocalOnlyClientCacheIntegrationTest { return exampleRegionAttributes; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest.java index 0b455f76..f603eaf5 100644 --- a/src/test/java/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest.java @@ -37,14 +37,16 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.ForkUtil; import org.springframework.data.gemfire.TestUtils; +import org.springframework.data.gemfire.fork.CqCacheServerProcess; import org.springframework.data.gemfire.listener.ContinuousQueryListener; import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer; import org.springframework.data.gemfire.listener.GemfireMDP; import org.springframework.data.gemfire.listener.adapter.ContinuousQueryListenerAdapter; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.ErrorHandler; /** @@ -57,25 +59,35 @@ import org.springframework.util.ErrorHandler; * @see org.junit.runner.RunWith * @see org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner + * @see org.springframework.test.context.junit4.SpringRunner * @see org.apache.geode.cache.client.ClientCache * @see org.apache.geode.cache.query.CqListener * @see org.apache.geode.cache.query.CqQuery * @since 1.4.0 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") -public class ContinuousQueryListenerContainerNamespaceTest { +public class ContinuousQueryListenerContainerNamespaceTest extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; @BeforeClass - public static void setupBeforeClass() { - ForkUtil.cacheServer(); + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(CqCacheServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); } @AfterClass - public static void tearDownAfterClass() { - ForkUtil.sendSignal(); + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); } @Autowired @@ -111,6 +123,7 @@ public class ContinuousQueryListenerContainerNamespaceTest { for (CqQuery query : queries) { actualNames.add(query.getName()); + assertEquals("SELECT * FROM /test-cq", query.getQueryString()); assertEquals("Q3".equalsIgnoreCase(query.getName()), query.isDurable()); @@ -133,5 +146,4 @@ public class ContinuousQueryListenerContainerNamespaceTest { actualNames.containsAll(Arrays.asList("Q1", "Q2", "Q3")); } - } diff --git a/src/test/java/org/springframework/data/gemfire/fork/CacheServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/CacheServerProcess.java deleted file mode 100644 index a1143c3c..00000000 --- a/src/test/java/org/springframework/data/gemfire/fork/CacheServerProcess.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011-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.fork; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.Properties; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.CacheFactory; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionFactory; -import org.apache.geode.cache.Scope; -import org.apache.geode.cache.server.CacheServer; -import org.springframework.data.gemfire.ForkUtil; - -/** - * @author Costin Leau - * @author John Blum - */ -@SuppressWarnings("unchecked") -public class CacheServerProcess { - - public static void main(final String[] args) throws Exception { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", "CqServer"); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", "warning"); - - Cache cache = new CacheFactory(gemfireProperties).create(); - - RegionFactory regionFactory = cache.createRegionFactory(); - regionFactory.setDataPolicy(DataPolicy.REPLICATE); - regionFactory.setScope(Scope.DISTRIBUTED_ACK); - - Region testRegion = regionFactory.create("test-cq"); - - System.out.printf("Test Region '%1$s' created in Cache '%2$s.%n", testRegion.getFullPath(), cache.getName()); - - CacheServer server = cache.addCacheServer(); - server.setPort(40404); - server.start(); - - ForkUtil.createControlFile(CacheServerProcess.class.getName()); - - System.out.println("Waiting for signal..."); - - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); - bufferedReader.readLine(); - - System.out.println("Signal received!"); - - testRegion.put("one", 1); - testRegion.put("two", 2); - testRegion.put("three", 3); - - System.out.println("Waiting for shutdown..."); - - bufferedReader.readLine(); - - System.out.println("Shutting down!"); - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java new file mode 100644 index 00000000..e1ebd73e --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/fork/CqCacheServerProcess.java @@ -0,0 +1,110 @@ +/* + * Copyright 2011-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.fork; + +import java.io.IOException; +import java.util.Scanner; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheClosedException; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.RegionFactory; +import org.apache.geode.cache.RegionShortcut; +import org.apache.geode.cache.Scope; +import org.apache.geode.cache.server.CacheServer; +import org.springframework.data.gemfire.ForkUtil; + +/** + * @author Costin Leau + * @author John Blum + */ +@SuppressWarnings("unchecked") +public class CqCacheServerProcess { + + private static final int DEFAULT_CACHE_SERVER_PORT = 40404; + + private static Region testCqRegion; + + private static final String CACHE_SERVER_PORT_PROPERTY = "spring.data.gemfire.cache.server.port"; + private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String GEMFIRE_NAME = "CqServer"; + + @SuppressWarnings("deprecation") + public static void main(final String[] args) throws Exception { + waitForShutdown(registerShutdownHook(startCacheServer(addRegion( + newGemFireCache(GEMFIRE_NAME, GEMFIRE_LOG_LEVEL), "test-cq")))); + } + + private static Cache newGemFireCache(String name, String logLevel) { + return new CacheFactory() + .set("name", name) + .set("mcast-port", "0") + .set("log-level", logLevel) + .create(); + } + + private static Cache addRegion(Cache gemfireCache, String name) { + RegionFactory regionFactory = gemfireCache.createRegionFactory(RegionShortcut.REPLICATE); + + regionFactory.setScope(Scope.DISTRIBUTED_ACK); + + testCqRegion = regionFactory.create(name); + + return gemfireCache; + } + + private static Cache startCacheServer(Cache gemfireCache) throws IOException { + CacheServer cacheServer = gemfireCache.addCacheServer(); + cacheServer.setPort(getCacheServerPort(DEFAULT_CACHE_SERVER_PORT)); + cacheServer.start(); + return gemfireCache; + } + + private static int getCacheServerPort(int defaultPort) { + return Integer.getInteger(CACHE_SERVER_PORT_PROPERTY, defaultPort); + } + + private static Cache registerShutdownHook(Cache gemfireCache) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + if (gemfireCache != null) { + try { + gemfireCache.close(); + } + catch (CacheClosedException ignore) { + } + } + })); + + return gemfireCache; + } + + @SuppressWarnings("deprecation") + private static void waitForShutdown(Cache gemfireCache) throws IOException { + ForkUtil.createControlFile(CqCacheServerProcess.class.getName()); + + Scanner scanner = new Scanner(System.in); + + scanner.nextLine(); + + testCqRegion.put("one", 1); + testCqRegion.put("two", 2); + testCqRegion.put("three", 3); + + scanner.nextLine(); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java index be808f7d..6529749b 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/FunctionCacheServerProcess.java @@ -16,17 +16,17 @@ package org.springframework.data.gemfire.fork; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.Properties; +import java.io.IOException; +import java.util.Scanner; import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheClosedException; import org.apache.geode.cache.CacheFactory; -import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionFactory; +import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.Scope; -import org.apache.geode.cache.execute.FunctionAdapter; +import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionContext; import org.apache.geode.cache.execute.FunctionService; import org.apache.geode.cache.server.CacheServer; @@ -35,100 +35,120 @@ import org.springframework.data.gemfire.ForkUtil; /** * @author Costin Leau * @author David Turanski + * @author John Blum */ public class FunctionCacheServerProcess { - static Region testRegion; + + private static final int DEFAULT_CACHE_SERVER_PORT = 40404; + + private static Region testFunctionRegion; + + private static final String CACHE_SERVER_PORT_PROPERTY = "spring.data.gemfire.cache.server.port"; + private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String GEMFIRE_NAME = "FunctionServer"; + public static void main(String[] args) throws Exception { + waitForShutdown(registerShutdownHook(registerFunctions(startCacheServer( + addRegion(newGemFireCache(GEMFIRE_NAME, GEMFIRE_LOG_LEVEL), "test-function"))))); + } - Properties props = new Properties(); - props.setProperty("name", "FunctionServer"); - props.setProperty("log-level", "config"); - props.setProperty("groups","g1,g2,g3"); + private static Cache newGemFireCache(String name, String logLevel) { + return new CacheFactory() + .set("name", name) + .set("mcast-port", "0") + .set("log-level", logLevel) + .set("groups", "g1,g2,g3") + .create(); + } + private static Cache addRegion(Cache gemfireCache, String name) { + RegionFactory regionFactory = gemfireCache.createRegionFactory(RegionShortcut.REPLICATE); - Cache cache = new CacheFactory(props).create(); + regionFactory.setScope(Scope.DISTRIBUTED_ACK); - // Create region. - RegionFactory factory = cache.createRegionFactory(); - factory.setDataPolicy(DataPolicy.REPLICATE); - factory.setScope(Scope.DISTRIBUTED_ACK); - testRegion = factory.create("test-function"); - System.out.println("Test region, " + testRegion.getFullPath() + ", created in cache."); + testFunctionRegion = regionFactory.create(name); + testFunctionRegion.put("one", 1); + testFunctionRegion.put("two", 2); + testFunctionRegion.put("three", 3); - // Start Cache Server. - CacheServer server = cache.addCacheServer(); - server.setPort(40404); - server.start(); - System.out.println("Server started"); + return gemfireCache; + } + private static Cache startCacheServer(Cache gemfireCache) throws IOException { + CacheServer cacheServer = gemfireCache.addCacheServer(); + cacheServer.setPort(getCacheServerPort(DEFAULT_CACHE_SERVER_PORT)); + cacheServer.start(); + return gemfireCache; + } - testRegion.put("one", 1); - testRegion.put("two", 2); - testRegion.put("three", 3); + private static int getCacheServerPort(int defaultPort) { + return Integer.getInteger(CACHE_SERVER_PORT_PROPERTY, defaultPort); + } - System.out.println("Registering ServerFunction"); - FunctionService.registerFunction(new ServerFunction()); - System.out.println("Registered ServerFunction"); - - System.out.println("Registering EchoFunction"); + private static Cache registerFunctions(Cache gemfireCache) { FunctionService.registerFunction(new EchoFunction()); - System.out.println("Registered EchoFunction"); + FunctionService.registerFunction(new ServerFunction()); - ForkUtil.createControlFile(FunctionCacheServerProcess.class.getName()); - - System.out.println("Waiting for shutdown"); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); - bufferedReader.readLine(); + return gemfireCache; } - @SuppressWarnings("serial") - static class ServerFunction extends FunctionAdapter { - - /* (non-Javadoc) - * @see org.apache.geode.cache.execute.FunctionAdapter#execute(org.apache.geode.cache.execute.FunctionContext) - */ - @Override - public void execute(FunctionContext functionContext) { - Object[] args = (Object[])functionContext.getArguments(); - testRegion.put(args[0], args[1]); - functionContext.getResultSender().lastResult(null); - } - - /* (non-Javadoc) - * @see org.apache.geode.cache.execute.FunctionAdapter#getId() - */ - @Override - public String getId() { - return "serverFunction"; - } - - } - - @SuppressWarnings("serial") - static class EchoFunction extends FunctionAdapter { - - /* (non-Javadoc) - * @see org.apache.geode.cache.execute.FunctionAdapter#execute(org.apache.geode.cache.execute.FunctionContext) - */ - @Override - public void execute(FunctionContext functionContext) { - Object[] args = (Object[])functionContext.getArguments(); - for (int i=0; i< args.length; i++){ - if (i == args.length-1){ - functionContext.getResultSender().lastResult(args[i]); - } else { - functionContext.getResultSender().sendResult(args[i]); + private static Cache registerShutdownHook(Cache gemfireCache) { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + if (gemfireCache != null) { + try { + gemfireCache.close(); + } + catch (CacheClosedException ignore) { } } + })); + return gemfireCache; + } + + @SuppressWarnings({ "deprecation", "unused" }) + private static void waitForShutdown(Cache gemfireCache) throws IOException { + ForkUtil.createControlFile(FunctionCacheServerProcess.class.getName()); + Scanner scanner = new Scanner(System.in); + scanner.nextLine(); + } + + @SuppressWarnings("serial") + static class EchoFunction implements Function { - } @Override public String getId() { return "echoFunction"; } + @Override + public void execute(FunctionContext functionContext) { + Object[] arguments = (Object[]) functionContext.getArguments(); + + for (int index = 0; index < arguments.length; index++) { + if ((index + 1) == arguments.length){ + functionContext.getResultSender().lastResult(arguments[index]); + } + else { + functionContext.getResultSender().sendResult(arguments[index]); + } + } + } } + @SuppressWarnings("serial") + static class ServerFunction implements Function { + @Override + public String getId() { + return "serverFunction"; + } + + @Override + public void execute(FunctionContext functionContext) { + Object[] arguments = (Object[]) functionContext.getArguments(); + testFunctionRegion.put(arguments[0], arguments[1]); + functionContext.getResultSender().lastResult(null); + } + } } diff --git a/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java index b881b0da..6223d60b 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java @@ -24,8 +24,8 @@ import org.springframework.data.gemfire.process.support.ProcessUtils; import org.springframework.data.gemfire.test.support.FileSystemUtils; /** - * The GemFireBasedServerProcess class is a main Java class used to launch a GemFire Server - * using GemFire's ServerLauncher API. + * The {@link GemFireBasedServerProcess} class is a main Java class used to launch a GemFire Server + * using GemFire's {@link ServerLauncher} API. * * @author John Blum * @see org.apache.geode.distributed.ServerLauncher @@ -33,12 +33,12 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils; */ public class GemFireBasedServerProcess { - protected static final String DEFAULT_GEMFIRE_MEMBER_NAME = "SpringDataGemFire-Server"; - protected static final String DEFAULT_HTTP_SERVICE_PORT = "0"; - protected static final String DEFAULT_LOG_LEVEL = "warning"; - protected static final String DEFAULT_USE_CLUSTER_CONFIGURATION = "false"; + private static final String GEMFIRE_HTTP_SERVICE_PORT = "0"; + private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String GEMIRE_NAME = "SpringDataGemFireServer"; + private static final String GEMFIRE_USE_CLUSTER_CONFIGURATION = "false"; - public static void main(final String[] args) throws Throwable { + public static void main(String[] args) throws Throwable { runServer(args); registerShutdownHook(); @@ -49,11 +49,7 @@ public class GemFireBasedServerProcess { ProcessUtils.waitForStopSignal(); } - public static String getServerProcessControlFilename() { - return GemFireBasedServerProcess.class.getSimpleName().toLowerCase().concat(".pid"); - } - - private static ServerLauncher runServer(final String[] args) { + private static ServerLauncher runServer(String[] args) { ServerLauncher serverLauncher = buildServerLauncher(args); // start the GemFire Server process... @@ -62,28 +58,38 @@ public class GemFireBasedServerProcess { return serverLauncher; } - private static ServerLauncher buildServerLauncher(final String[] args) { + private static ServerLauncher buildServerLauncher(String[] args) { return new ServerLauncher.Builder(args) - .setMemberName(System.getProperty("gemfire.name", DEFAULT_GEMFIRE_MEMBER_NAME)) + .setMemberName(getProperty("gemfire.name", GEMIRE_NAME)) .setCommand(ServerLauncher.Command.START) .setDisableDefaultServer(true) .setRedirectOutput(false) - .set(DistributionConfig.HTTP_SERVICE_PORT_NAME, System.getProperty("spring.gemfire.http-service-port", - DEFAULT_HTTP_SERVICE_PORT)) - .set(DistributionConfig.JMX_MANAGER_NAME, String.valueOf(Boolean.TRUE)) - .set(DistributionConfig.JMX_MANAGER_START_NAME, String.valueOf(Boolean.FALSE)) - .set(DistributionConfig.LOG_LEVEL_NAME, System.getProperty("spring.gemfire.log-level", DEFAULT_LOG_LEVEL)) - .set(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME, System.getProperty("spring.gemfire.use-cluster-configuration", - DEFAULT_USE_CLUSTER_CONFIGURATION)) + .set(DistributionConfig.HTTP_SERVICE_PORT_NAME, + getProperty("spring.data.gemfire.http-service-port", GEMFIRE_HTTP_SERVICE_PORT)) + .set(DistributionConfig.JMX_MANAGER_NAME, Boolean.TRUE.toString()) + .set(DistributionConfig.JMX_MANAGER_START_NAME, Boolean.FALSE.toString()) + .set(DistributionConfig.LOG_LEVEL_NAME, + getProperty("spring.data.gemfire.log-level", GEMFIRE_LOG_LEVEL)) + .set(DistributionConfig.USE_CLUSTER_CONFIGURATION_NAME, + getProperty("spring.data.gemfire.use-cluster-configuration", GEMFIRE_USE_CLUSTER_CONFIGURATION)) .build(); } + private static String getProperty(String name, String defaultValue) { + return System.getProperty(name, defaultValue); + } + private static void registerShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - @Override public void run() { - ServerLauncher.getInstance().stop(); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + ServerLauncher serverLauncher = ServerLauncher.getInstance(); + + if (serverLauncher != null) { + serverLauncher.stop(); } })); } + public static String getServerProcessControlFilename() { + return GemFireBasedServerProcess.class.getSimpleName().toLowerCase().concat(".pid"); + } } diff --git a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java index 96910823..47587ca3 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java @@ -40,12 +40,12 @@ import org.springframework.data.gemfire.test.support.ThreadUtils; */ public class LocatorProcess { - public static final int DEFAULT_LOCATOR_PORT = 20668; + private static final int DEFAULT_LOCATOR_PORT = 20668; - public static final String DEFAULT_GEMFIRE_MEMBER_NAME = "SpringDataGemFire-Locator"; - public static final String DEFAULT_HOSTNAME_FOR_CLIENTS = "localhost"; - public static final String DEFAULT_HTTP_SERVICE_PORT = "0"; - public static final String DEFAULT_LOG_LEVEL = "config"; + private static final String GEMFIRE_NAME = "SpringDataGemFireLocator"; + private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String HOSTNAME_FOR_CLIENTS = "localhost"; + private static final String HTTP_SERVICE_PORT = "0"; public static void main(final String... args) throws IOException { //runLocator(); @@ -68,26 +68,27 @@ public class LocatorProcess { @SuppressWarnings("unused") private static InternalLocator runInternalLocator() throws IOException { String hostnameForClients = System.getProperty("spring.gemfire.hostname-for-clients", - DEFAULT_HOSTNAME_FOR_CLIENTS); + HOSTNAME_FOR_CLIENTS); - int locatorPort = Integer.getInteger("spring.gemfire.locator-port", DEFAULT_LOCATOR_PORT); + int locatorPort = Integer.getInteger("spring.data.gemfire.locator.port", DEFAULT_LOCATOR_PORT); - boolean loadClusterConfigurationFromDirectory = Boolean.getBoolean("spring.gemfire.load-cluster-configuration"); + boolean loadClusterConfigurationFromDirectory = + Boolean.getBoolean("spring.data.gemfire.load-cluster-configuration"); Properties distributedSystemProperties = new Properties(); distributedSystemProperties.setProperty(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, - String.valueOf(Boolean.getBoolean("spring.gemfire.enable-cluster-configuration"))); + String.valueOf(Boolean.getBoolean("spring.data.gemfire.enable-cluster-configuration"))); distributedSystemProperties.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, - System.getProperty("spring.gemfire.http-service-port", DEFAULT_HTTP_SERVICE_PORT)); + System.getProperty("spring.data.gemfire.http-service-port", HTTP_SERVICE_PORT)); distributedSystemProperties.setProperty(DistributionConfig.JMX_MANAGER_NAME, - System.getProperty("spring.gemfire.jmx-manager", Boolean.TRUE.toString())); + System.getProperty("spring.data.gemfire.jmx-manager", Boolean.TRUE.toString())); distributedSystemProperties.setProperty(DistributionConfig.JMX_MANAGER_START_NAME, - System.getProperty("spring.gemfire.jmx-manager-start", Boolean.FALSE.toString())); + System.getProperty("spring.data.gemfire.jmx-manager-start", Boolean.FALSE.toString())); distributedSystemProperties.setProperty(DistributionConfig.LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, String.valueOf(loadClusterConfigurationFromDirectory)); distributedSystemProperties.setProperty(DistributionConfig.LOG_LEVEL_NAME, - System.getProperty("spring.gemfire.log-level", DEFAULT_LOG_LEVEL)); + System.getProperty("spring.data.gemfire.log-level", GEMFIRE_LOG_LEVEL)); return InternalLocator.startLocator(locatorPort, null, null, null, null, null, distributedSystemProperties, true, true, hostnameForClients, loadClusterConfigurationFromDirectory); @@ -105,55 +106,59 @@ public class LocatorProcess { private static LocatorLauncher buildLocatorLauncher() { return new LocatorLauncher.Builder() - .setMemberName(DEFAULT_GEMFIRE_MEMBER_NAME) - .setHostnameForClients(System.getProperty("spring.gemfire.hostname-for-clients", - DEFAULT_HOSTNAME_FOR_CLIENTS)) - .setPort(Integer.getInteger("spring.gemfire.locator-port", DEFAULT_LOCATOR_PORT)) + .setMemberName(GEMFIRE_NAME) + .setHostnameForClients(getProperty("spring.data.gemfire.hostname-for-clients", HOSTNAME_FOR_CLIENTS)) + .setPort(getInteger("spring.data.gemfire.locator.port", DEFAULT_LOCATOR_PORT)) .setRedirectOutput(false) - .set(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, String.valueOf(Boolean.getBoolean( - "spring.gemfire.enable-cluster-configuration"))) - .set(DistributionConfig.HTTP_SERVICE_PORT_NAME, System.getProperty("spring.gemfire.http-service-port", - DEFAULT_HTTP_SERVICE_PORT)) - .set(DistributionConfig.JMX_MANAGER_NAME, String.valueOf(Boolean.TRUE)) - .set(DistributionConfig.JMX_MANAGER_START_NAME, String.valueOf(Boolean.FALSE)) - .set(DistributionConfig.LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, String.valueOf(Boolean.getBoolean( - "spring.gemfire.load-cluster-configuration"))) - .set(DistributionConfig.LOG_LEVEL_NAME, System.getProperty("spring.gemfire.log-level", DEFAULT_LOG_LEVEL)) + .set(DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME, + String.valueOf(getBoolean("spring.data.gemfire.enable-cluster-configuration"))) + .set(DistributionConfig.HTTP_SERVICE_PORT_NAME, + getProperty("spring.data.gemfire.http-service-port", HTTP_SERVICE_PORT)) + .set(DistributionConfig.JMX_MANAGER_NAME, Boolean.TRUE.toString()) + .set(DistributionConfig.JMX_MANAGER_START_NAME, Boolean.FALSE.toString()) + .set(DistributionConfig.LOAD_CLUSTER_CONFIG_FROM_DIR_NAME, + String.valueOf(getBoolean("spring.data.gemfire.load-cluster-configuration"))) + .set(DistributionConfig.LOG_LEVEL_NAME, + getProperty("spring.data.gemfire.log-level", GEMFIRE_LOG_LEVEL)) .build(); } + private static boolean getBoolean(String name) { + return Boolean.getBoolean(name); + } + + private static int getInteger(String name, int defaultValue) { + return Integer.getInteger(name, defaultValue); + } + + private static String getProperty(String name, String defaultValue) { + return System.getProperty(name, defaultValue); + } + + private static void registerShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Locator locator = GemfireUtils.getLocator(); + + if (locator != null) { + locator.stop(); + } + })); + } + + private static void waitForLocatorStart(final long milliseconds) { + InternalLocator locator = InternalLocator.getLocator(); + + if (isClusterConfigurationEnabled(locator)) { + ThreadUtils.timedWait(milliseconds, 500L, () -> !locator.isSharedConfigurationRunning()); + } + else { + LocatorLauncher.getInstance().waitOnStatusResponse( + milliseconds, Math.min(500L, milliseconds), TimeUnit.MILLISECONDS); + } + } + private static boolean isClusterConfigurationEnabled(final InternalLocator locator) { return (locator != null && Boolean.valueOf(locator.getDistributedSystem().getProperties().getProperty( DistributionConfig.ENABLE_CLUSTER_CONFIGURATION_NAME))); } - - private static void registerShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - @Override public void run() { - stopLocator(GemfireUtils.getLocator()); - } - - private void stopLocator(final Locator locator) { - if (locator != null) { - locator.stop(); - } - } - })); - } - - private static void waitForLocatorStart(final long milliseconds) { - final InternalLocator locator = InternalLocator.getLocator(); - - if (isClusterConfigurationEnabled(locator)) { - ThreadUtils.timedWait(milliseconds, 500, new ThreadUtils.WaitCondition() { - @Override public boolean waiting() { - return !locator.isSharedConfigurationRunning(); - } - }); - } - else { - LocatorLauncher.getInstance().waitOnStatusResponse(milliseconds, Math.min(500, milliseconds), - TimeUnit.MILLISECONDS); - } - } } diff --git a/src/test/java/org/springframework/data/gemfire/fork/ServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/ServerProcess.java index d8595021..d465e552 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/ServerProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/ServerProcess.java @@ -17,7 +17,10 @@ package org.springframework.data.gemfire.fork; import java.io.File; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.data.gemfire.process.support.ProcessUtils; @@ -35,23 +38,17 @@ import org.springframework.util.Assert; */ public class ServerProcess { - public static void main(final String[] args) throws Throwable { + private static final Logger logger = LoggerFactory.getLogger(ServerProcess.class); + + public static void main(String[] args) throws Throwable { ConfigurableApplicationContext applicationContext = null; try { - Assert.notEmpty(args, String.format("Usage: >java -cp ... %1$s %2$s", ServerProcess.class.getName(), - "classpath:/to/applicationContext.xml")); - - applicationContext = new ClassPathXmlApplicationContext(args[0]); - applicationContext.registerShutdownHook(); - - ProcessUtils.writePid(new File(FileSystemUtils.WORKING_DIRECTORY, getServerProcessControlFilename()), - ProcessUtils.currentPid()); - - ProcessUtils.waitForStopSignal(); + applicationContext = newApplicationContext(args); + waitForShutdown(); } catch (Throwable e) { - e.printStackTrace(System.err); + logger.debug("", e); throw e; } finally { @@ -59,11 +56,18 @@ public class ServerProcess { } } - public static String getServerProcessControlFilename() { - return ServerProcess.class.getSimpleName().toLowerCase().concat(".pid"); + private static ConfigurableApplicationContext newApplicationContext(String[] configLocations) { + Assert.notEmpty(configLocations, String.format("Usage: >java -cp ... %1$s %2$s", + ServerProcess.class.getName(), "classpath:/to/applicationContext.xml")); + + ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations); + + applicationContext.registerShutdownHook(); + + return applicationContext; } - protected static boolean close(final ConfigurableApplicationContext applicationContext) { + private static boolean close(ConfigurableApplicationContext applicationContext) { if (applicationContext != null) { applicationContext.close(); return !(applicationContext.isRunning() || applicationContext.isActive()); @@ -72,4 +76,14 @@ public class ServerProcess { return true; } + private static void waitForShutdown() throws IOException { + ProcessUtils.writePid(new File(FileSystemUtils.WORKING_DIRECTORY, getServerProcessControlFilename()), + ProcessUtils.currentPid()); + + ProcessUtils.waitForStopSignal(); + } + + public static String getServerProcessControlFilename() { + return ServerProcess.class.getSimpleName().toLowerCase().concat(".pid"); + } } diff --git a/src/test/java/org/springframework/data/gemfire/fork/SpringCacheServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/SpringCacheServerProcess.java deleted file mode 100644 index a792ed45..00000000 --- a/src/test/java/org/springframework/data/gemfire/fork/SpringCacheServerProcess.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2002-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.fork; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.data.gemfire.ForkUtil; - -/** - * @author David Turanski - * - */ -public class SpringCacheServerProcess { - public static void main(String[] args) { - ConfigurableApplicationContext ctx = null; - try { - ctx = new ClassPathXmlApplicationContext(args[0]); - ForkUtil.createControlFile(SpringCacheServerProcess.class.getName()); - - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); - System.out.println("Waiting for shutdown"); - bufferedReader.readLine(); - - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } finally { - if (ctx != null) { - ctx.close(); - } - } - } -} diff --git a/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java new file mode 100644 index 00000000..ebe3f092 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/fork/SpringContainerProcess.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-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.fork; + +import java.io.IOException; +import java.util.Scanner; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.data.gemfire.ForkUtil; + +/** + * {@link SpringContainerProcess} launches a Spring {@link ConfigurableApplicationContext} in this JVM process. + * + * @author David Turanski + * @author John Blum + * @see org.springframework.context.ConfigurableApplicationContext + * @see org.springframework.context.support.ClassPathXmlApplicationContext + */ +public class SpringContainerProcess { + + private static final Logger logger = LoggerFactory.getLogger(SpringContainerProcess.class); + + public static void main(String[] args) { + ConfigurableApplicationContext applicationContext = null; + + try { + applicationContext = newApplicationContext(args); + waitForShutdown(applicationContext); + } + catch (Exception e) { + logger.debug("", e); + System.exit(1); + } + finally { + close(applicationContext); + } + } + + private static ConfigurableApplicationContext newApplicationContext(String[] configLocations) { + ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations); + applicationContext.registerShutdownHook(); + return applicationContext; + } + + private static void close(ConfigurableApplicationContext applicationContext) { + if (applicationContext != null) { + applicationContext.close(); + } + } + + @SuppressWarnings({ "deprecation", "unused" }) + private static void waitForShutdown(ConfigurableApplicationContext applicationContext) throws IOException { + ForkUtil.createControlFile(SpringContainerProcess.class.getName()); + Scanner scanner = new Scanner(System.in); + scanner.nextLine(); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest.java index 824f2c21..b11ece71 100644 --- a/src/test/java/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -33,18 +32,21 @@ import org.apache.geode.pdx.PdxReader; import org.apache.geode.pdx.PdxSerializer; import org.apache.geode.pdx.PdxWriter; import org.apache.geode.pdx.internal.PdxInstanceEnum; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; +import org.springframework.data.gemfire.fork.ServerProcess; +import org.springframework.data.gemfire.fork.SpringContainerProcess; import org.springframework.data.gemfire.function.annotation.GemfireFunction; import org.springframework.data.gemfire.function.sample.ApplicationDomainFunctionExecutions; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -56,21 +58,23 @@ import org.springframework.util.ObjectUtils; * @author John Blum * @see org.junit.Test * @see org.junit.runner.RunWith - * @see org.springframework.data.gemfire.fork.SpringCacheServerProcess + * @see SpringContainerProcess * @see org.springframework.data.gemfire.function.annotation.GemfireFunction * @see org.springframework.data.gemfire.function.sample.ApplicationDomainFunctionExecutions * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner + * @see org.springframework.test.context.junit4.SpringRunner * @see org.apache.geode.cache.client.ClientCache * @see org.apache.geode.pdx.PdxInstance * @see org.apache.geode.pdx.PdxSerializer * @see org.apache.geode.pdx.internal.PdxInstanceEnum * @since 1.5.2 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") -public class ClientCacheFunctionExecutionWithPdxIntegrationTest { +public class ClientCacheFunctionExecutionWithPdxIntegrationTest extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; @Autowired private ClientCache gemfireClientCache; @@ -79,14 +83,22 @@ public class ClientCacheFunctionExecutionWithPdxIntegrationTest { private ApplicationDomainFunctionExecutions functionExecutions; @BeforeClass - @SuppressWarnings("deprecation") - public static void setupSpringGemFireServer() throws IOException { - ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + " " - + toPathname(ClientCacheFunctionExecutionWithPdxIntegrationTest.class).concat("-server-context.xml")); + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(ServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort), + getServerContextXmlFileLocation(ClientCacheFunctionExecutionWithPdxIntegrationTest.class)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); } - protected static String toPathname(final Class type) { - return type.getName().replace(".", "/"); + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); } protected PdxInstance toPdxInstance(final Map pdxData) { @@ -427,5 +439,4 @@ public class ClientCacheFunctionExecutionWithPdxIntegrationTest { return null; } } - } diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionIntegrationTests.java new file mode 100644 index 00000000..064bb4b5 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionIntegrationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2002-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.function.execution; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.geode.cache.CacheClosedException; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.client.Pool; +import org.apache.geode.cache.client.PoolManager; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; + +/** + * @author David Turanski + * @author John Blum + */ +public class FunctionExecutionIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static int availablePort; + + private static ProcessWrapper gemfireServer; + + private ClientCache gemfireCache = null; + + private Pool gemfirePool = null; + + private Region gemfireRegion = null; + + @BeforeClass + public static void startGemFireServer() throws Exception { + availablePort = findAvailablePort(); + + gemfireServer = run(FunctionCacheServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + @Before + public void setupGemFireClient() { + gemfireCache = new ClientCacheFactory() + .set("name", "FunctionExecutionIntegrationTests") + .set("log-level", "warning") + .setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", availablePort) + .create(); + + gemfirePool = PoolManager.find("DEFAULT"); + + gemfireRegion = gemfireCache.createClientRegionFactory(ClientRegionShortcut.PROXY) + .create("test-function"); + } + + @After + public void tearDownGemFireClient() { + if (gemfireCache != null) { + try { + gemfireCache.close(); + } + catch (CacheClosedException ignore) { + } + } + } + + @Test + public void basicFunctionExecutionsAreCorrect() { + verifyFunctionExecution(new PoolServerFunctionExecution(gemfirePool)); + verifyFunctionExecution(new RegionFunctionExecution(gemfireRegion)); + verifyFunctionExecution(new ServerFunctionExecution(gemfireCache)); + verifyFunctionExecution(new ServersFunctionExecution(gemfireCache)); + } + + private void verifyFunctionExecution(AbstractFunctionExecution functionExecution) { + Iterable results = functionExecution.setArgs("1", "2", "3").setFunctionId("echoFunction").execute(); + int count = 1; + + for (String result : results) { + assertThat(result).isEqualTo(String.valueOf(count++)); + } + } +} diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionTests.java b/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionTests.java deleted file mode 100644 index 64f14834..00000000 --- a/src/test/java/org/springframework/data/gemfire/function/execution/FunctionExecutionTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2002-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.function.execution; - -import static org.junit.Assert.assertEquals; - -import java.util.Iterator; -import java.util.Properties; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.cache.client.ClientRegionFactory; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.client.PoolFactory; -import org.apache.geode.cache.client.PoolManager; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; - -/** - * @author David Turanski - * - */ -public class FunctionExecutionTests { - - private static ClientCache cache = null; - - private static Pool pool = null; - - private static Region clientRegion = null; - - @BeforeClass - public static void startUp() throws Exception { - // Registers function "echoFunction" - ForkUtil.cacheServer(FunctionCacheServerProcess.class); - - Properties props = new Properties(); - props.put("mcast-port", "0"); - props.put("name", "function-client"); - props.put("log-level", "warning"); - - ClientCacheFactory ccf = new ClientCacheFactory(props); - ccf.setPoolSubscriptionEnabled(true); - cache = ccf.create(); - - PoolFactory pf = PoolManager.createFactory(); - pf.addServer("localhost", 40404); - pf.setSubscriptionEnabled(true); - pool = pf.create("client"); - - ClientRegionFactory crf = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); - crf.setPoolName("client"); - clientRegion = crf.create("test-function"); - } - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - if (clientRegion != null) { - clientRegion.destroyRegion(); - } - if (pool != null) { - pool.destroy(); - pool = null; - } - - if (cache != null) { - cache.close(); - } - cache = null; - } - - @Test - public void testBasicFunctionExecutions() { - verifyfunctionExecution(new RegionFunctionExecution(clientRegion)); - verifyfunctionExecution(new ServerFunctionExecution(cache)); - verifyfunctionExecution(new PoolServerFunctionExecution(pool)); - verifyfunctionExecution(new ServersFunctionExecution(cache)); - } - - - - private void verifyfunctionExecution(AbstractFunctionExecution functionExecution) { - Iterable results = functionExecution - .setArgs("1","2","3") - .setFunctionId("echoFunction") - .execute(); - - Iterator it = results.iterator(); - for (int i = 1; i<= 3; i++) { - assertEquals(String.valueOf(i),it.next()); - } - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests.java index a027a53e..16258770 100644 --- a/src/test/java/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests.java @@ -31,35 +31,46 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; +import org.springframework.data.gemfire.fork.ServerProcess; import org.springframework.data.gemfire.function.annotation.GemfireFunction; import org.springframework.data.gemfire.function.annotation.RegionData; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.stereotype.Component; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** * @author David Turanski * @author John Blum */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration @SuppressWarnings("unused") -public class FunctionIntegrationTests { +public class FunctionIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; @Resource(name = "test-region") private Region region; @BeforeClass - public static void startup() throws Exception { - ForkUtil.startCacheServer(SpringCacheServerProcess.class.getName() + - " /org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-server-context.xml"); + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(ServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort), + getServerContextXmlFileLocation(FunctionIntegrationTests.class)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); } @AfterClass - public static void shutdown() { - ForkUtil.sendSignal(); + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); } @Before @@ -111,9 +122,11 @@ public class FunctionIntegrationTests { } @Test + @SuppressWarnings("all") public void testArrayReturnTypes() { - Object result = new GemfireOnRegionFunctionTemplate(region).executeAndExtract("arrays", - new int[] { 1, 2, 3, 4, 5 }); + Object result = new GemfireOnRegionFunctionTemplate(region) + .executeAndExtract("arrays", new int[] { 1, 2, 3, 4, 5 }); + assertTrue(result.getClass().getName(), result instanceof int[]); assertEquals(5, ((int[]) result).length); } diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateIntegrationTests.java new file mode 100644 index 00000000..8bafbf58 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateIntegrationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2002-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.function.execution; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +import org.apache.geode.cache.CacheClosedException; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.client.Pool; +import org.apache.geode.cache.client.PoolManager; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; + +/** + * @author David Turanski + */ +public class GemfireFunctionTemplateIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static int availablePort; + + private static ProcessWrapper gemfireServer; + + private ClientCache gemfireCache = null; + + private Pool gemfirePool = null; + + private Region gemfireRegion = null; + + @BeforeClass + public static void startGemFireServer() throws Exception { + availablePort = findAvailablePort(); + + gemfireServer = run(FunctionCacheServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + @Before + public void setupGemFireClient() { + gemfireCache = new ClientCacheFactory() + .set("name", "GemfireFunctionTemplateIntegrationTests") + .set("log-level", "warning") + .setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", availablePort) + .create(); + + gemfirePool = PoolManager.find("DEFAULT"); + + gemfireRegion = gemfireCache.createClientRegionFactory(ClientRegionShortcut.PROXY) + .create("test-function"); + } + + @After + public void tearDownGemFireClient() { + if (gemfireCache != null) { + try { + gemfireCache.close(); + } + catch (CacheClosedException ignore) { + } + } + } + + @Test + public void testFunctionTemplates() { + verifyFunctionTemplateExecution(new GemfireOnRegionFunctionTemplate(gemfireRegion)); + verifyFunctionTemplateExecution(new GemfireOnServerFunctionTemplate(gemfireCache)); + verifyFunctionTemplateExecution(new GemfireOnServerFunctionTemplate(gemfirePool)); + verifyFunctionTemplateExecution(new GemfireOnServersFunctionTemplate(gemfireCache)); + verifyFunctionTemplateExecution(new GemfireOnServersFunctionTemplate(gemfirePool)); + } + + private void verifyFunctionTemplateExecution(GemfireFunctionOperations functionTemplate) { + Iterable results = functionTemplate.execute("echoFunction", "1", "2", "3"); + int count = 1; + + for (String result : results) { + assertThat(result).isEqualTo(String.valueOf(count++)); + } + } +} diff --git a/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateTests.java b/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateTests.java deleted file mode 100644 index 0b40337d..00000000 --- a/src/test/java/org/springframework/data/gemfire/function/execution/GemfireFunctionTemplateTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2002-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.function.execution; - -import static org.junit.Assert.assertEquals; - -import java.util.Iterator; -import java.util.Properties; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.cache.client.ClientRegionFactory; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.client.PoolFactory; -import org.apache.geode.cache.client.PoolManager; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.FunctionCacheServerProcess; - -/** - * @author David Turanski - * - */ -public class GemfireFunctionTemplateTests { - private static ClientCache cache = null; - - private static Pool pool = null; - - private static Region clientRegion = null; - - @BeforeClass - public static void startUp() throws Exception { - ForkUtil.cacheServer(FunctionCacheServerProcess.class); - - Properties props = new Properties(); - props.put("mcast-port", "0"); - props.put("name", "function-client"); - props.put("log-level", "warning"); - - ClientCacheFactory ccf = new ClientCacheFactory(props); - ccf.setPoolSubscriptionEnabled(true); - cache = ccf.create(); - - PoolFactory pf = PoolManager.createFactory(); - pf.addServer("localhost", 40404); - pf.setSubscriptionEnabled(true); - pool = pf.create("client"); - - ClientRegionFactory crf = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); - crf.setPoolName("client"); - clientRegion = crf.create("test-function"); - } - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - if (clientRegion != null) { - clientRegion.destroyRegion(); - } - if (pool != null) { - pool.destroy(); - pool = null; - } - - if (cache != null) { - cache.close(); - } - cache = null; - } - - @Test - public void testFunctionTemplates() { - verifyfunctionTemplateExecution( new GemfireOnServerFunctionTemplate(cache)); - verifyfunctionTemplateExecution( new GemfireOnServersFunctionTemplate(cache)); - verifyfunctionTemplateExecution( new GemfireOnRegionFunctionTemplate(clientRegion)); - verifyfunctionTemplateExecution( new GemfireOnServerFunctionTemplate(pool)); - verifyfunctionTemplateExecution( new GemfireOnServersFunctionTemplate(pool)); - } - - private void verifyfunctionTemplateExecution(GemfireFunctionOperations functionTemplate) { - Iterable results = functionTemplate.execute("echoFunction","1","2","3"); - - Iterator it = results.iterator(); - for (int i = 1; i<= 3; i++) { - assertEquals(String.valueOf(i),it.next()); - } - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerIntegrationTests.java new file mode 100644 index 00000000..248efb7b --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerIntegrationTests.java @@ -0,0 +1,115 @@ +/* + * Copyright 2011-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.listener; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.EventListener; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; + +import org.apache.geode.cache.CacheClosedException; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.query.CqEvent; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.data.gemfire.fork.CqCacheServerProcess; +import org.springframework.data.gemfire.listener.adapter.ContinuousQueryListenerAdapter; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; + +/** + * @author Costin Leau + */ +public class ListenerContainerIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static int availablePort; + + private static ProcessWrapper gemfireServer; + + private ClientCache gemfireCache = null; + + private final ContinuousQueryListenerAdapter adapter = new ContinuousQueryListenerAdapter(new EventListener() { + public void handleEvent(CqEvent event) { + cqEvents.add(event); + } + }); + + private ContinuousQueryListenerContainer container; + + private final List cqEvents = new CopyOnWriteArrayList<>(); + + @BeforeClass + public static void startGemFireServer() throws Exception { + availablePort = findAvailablePort(); + + gemfireServer = run(CqCacheServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + @Before + public void setupGemFireClient() throws Exception { + gemfireCache = new ClientCacheFactory() + .set("name", "ListenerContainerIntegrationTests") + .set("log-level", "warning") + .setPoolSubscriptionEnabled(true) + .addPoolServer(DEFAULT_HOSTNAME, availablePort) + .create(); + + String query = "SELECT * from /test-cq"; + + container = new ContinuousQueryListenerContainer(); + container.setBeanName("cqListenerContainer"); + container.setCache(gemfireCache); + container.afterPropertiesSet(); + container.addListener(new ContinuousQueryDefinition("test", query, adapter)); + container.start(); + } + + @After + public void tearDownGemFireClient() { + if (gemfireCache != null) { + try { + gemfireCache.close(); + } + catch (CacheClosedException ignore) { + } + } + } + + @Test + public void testContainer() throws Exception { + gemfireServer.signal(); + waitOn(() -> cqEvents.size() == 3, TimeUnit.SECONDS.toMillis(5)); + assertThat(cqEvents.size()).isEqualTo(3); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerTests.java b/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerTests.java deleted file mode 100644 index 2a5dda78..00000000 --- a/src/test/java/org/springframework/data/gemfire/listener/ListenerContainerTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2011-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.listener; - -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.apache.geode.cache.RegionService; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.query.CqEvent; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.listener.adapter.ContinuousQueryListenerAdapter; - -/** - * @author Costin Leau - */ -public class ListenerContainerTests { - - private final List bag = new ArrayList(); - protected ContinuousQueryListenerContainer container; - - private static RegionService cache = null; - private static Pool pool = null; - - private final Object handler = new Object() { - public void handleEvent(CqEvent event) { - bag.add(event); - } - }; - - private final ContinuousQueryListenerAdapter adapter = new ContinuousQueryListenerAdapter(handler); - - @BeforeClass - public static void startUp() throws Exception { - ForkUtil.cacheServer(); - - Properties props = new Properties(); - props.put("mcast-port", "0"); - props.put("name", "cq-client"); - props.put("log-level", "warning"); - - ClientCacheFactory ccf = new ClientCacheFactory(props); - ccf.setPoolSubscriptionEnabled(true); - cache = ccf.create(); - } - - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - - if (pool != null) { - pool.destroy(); - pool = null; - } - - if (cache != null) { - cache.close(); - } - cache = null; - } - - - @Before - public void setUp() throws Exception { - String query = "SELECT * from /test-cq"; - - container = new ContinuousQueryListenerContainer(); - container.setCache(cache); - container.setBeanName("container"); - container.afterPropertiesSet(); - container.addListener(new ContinuousQueryDefinition("test", query, adapter)); - } - - @Test - public void testContainer() throws Exception { - ForkUtil.sendSignal(); - Thread.sleep(3000); - System.out.println("Bag is " + bag); - ForkUtil.sendSignal(); - } -} diff --git a/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests.java new file mode 100644 index 00000000..310a21b4 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests.java @@ -0,0 +1,94 @@ +/* + * Copyright 2011-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.listener.adapter; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.Pool; +import org.apache.geode.cache.query.CqQuery; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.gemfire.fork.CqCacheServerProcess; +import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer; +import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author Costin Leau + * @author John Blum + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@SuppressWarnings("unused") +// TODO change this test to use mocks!! +public class ContainerXmlSetupIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; + + @BeforeClass + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); + + gemfireServer = run(CqCacheServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); + } + + @AfterClass + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + + @Autowired + private ApplicationContext applicationContext; + + @Test + public void containerSetup() throws Exception { + ContinuousQueryListenerContainer container = + applicationContext.getBean(ContinuousQueryListenerContainer.class); + + assertThat(container).isNotNull(); + assertThat(container.isRunning()).isTrue(); + assertThat(container).isSameAs(applicationContext.getBean("testContainerId", + ContinuousQueryListenerContainer.class)); + + ClientCache cache = applicationContext.getBean(ClientCache.class); + Pool pool = applicationContext.getBean(Pool.class); + + assertThat(cache.getName()).isEqualTo("ContainerXmlSetupIntegrationTests"); + assertThat(pool.getName()).isEqualTo("client"); + + CqQuery[] cacheCqs = cache.getQueryService().getCqs(); + CqQuery[] poolCqs = pool.getQueryService().getCqs(); + + assertThat(pool.getQueryService().getCq("test-bean-1")).isNotNull(); + assertThat(cacheCqs.length).isEqualTo(3); + assertThat(poolCqs.length).isEqualTo(3); + } +} diff --git a/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupTest.java b/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupTest.java deleted file mode 100644 index bf7fe055..00000000 --- a/src/test/java/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2011-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.listener.adapter; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.query.CqQuery; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * @author Costin Leau - * @author John Blum - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration("/org/springframework/data/gemfire/listener/container.xml") -@SuppressWarnings("unused") -public class ContainerXmlSetupTest { - - @BeforeClass - public static void init() { - ForkUtil.cacheServer(); - } - - @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); - } - - @Autowired - private ApplicationContext applicationContext; - - @Test - public void containerSetup() throws Exception { - ContinuousQueryListenerContainer container = applicationContext.getBean( - ContinuousQueryListenerContainer.class); - - assertNotNull(container); - assertTrue(container.isRunning()); - - // test getting container listener by bean ID - ContinuousQueryListenerContainer container2 = applicationContext.getBean("testContainerId", - ContinuousQueryListenerContainer.class); - - assertSame(container, container2); - - Cache cache = applicationContext.getBean("gemfireCache", Cache.class); - Pool pool = applicationContext.getBean("client", Pool.class); - - CqQuery[] cqs = cache.getQueryService().getCqs(); - CqQuery[] poolCqs = pool.getQueryService().getCqs(); - - assertTrue(pool.getQueryService().getCq("test-bean-1") != null); - assertEquals(3, cqs.length); - assertEquals(3, poolCqs.length); - } - -} diff --git a/src/test/java/org/springframework/data/gemfire/process/ProcessExecutor.java b/src/test/java/org/springframework/data/gemfire/process/ProcessExecutor.java index 0bb71420..8331fb41 100644 --- a/src/test/java/org/springframework/data/gemfire/process/ProcessExecutor.java +++ b/src/test/java/org/springframework/data/gemfire/process/ProcessExecutor.java @@ -16,6 +16,8 @@ package org.springframework.data.gemfire.process; +import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -48,6 +50,7 @@ public abstract class ProcessExecutor { public static final String JAVA_CLASSPATH = System.getProperty("java.class.path"); protected static final String SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX = "spring.gemfire."; + protected static final String SPRING_DATA_GEMFIRE_SYSTEM_PROPERTY_PREFIX = "spring.data.gemfire."; public static ProcessWrapper launch(Class type, String... args) throws IOException { return launch(FileSystemUtils.WORKING_DIRECTORY, type, args); @@ -78,7 +81,7 @@ public abstract class ProcessExecutor { Assert.notNull(type, "The main Java class to launch must not be null"); List command = new ArrayList<>(); - List programArgs = Collections.emptyList(); + List programArguments = new ArrayList<>(args.length); command.add(JAVA_EXE.getAbsolutePath()); command.add("-server"); @@ -87,28 +90,25 @@ public abstract class ProcessExecutor { command.add(StringUtils.hasText(classpath) ? classpath : JAVA_CLASSPATH); command.addAll(getSpringGemFireSystemProperties()); - if (args != null) { - programArgs = new ArrayList<>(args.length); - - for (String arg : args) { - if (isJvmOption(arg)) { - command.add(arg); - } - else if (!StringUtils.isEmpty(arg)) { - programArgs.add(arg); - } + for (String arg : nullSafeArray(args, String.class)) { + if (isJvmOption(arg)) { + command.add(arg); + } + else if (!StringUtils.isEmpty(arg)) { + programArguments.add(arg); } } command.add(type.getName()); - command.addAll(programArgs); + command.addAll(programArguments); return command.toArray(new String[command.size()]); } protected static Collection getSpringGemFireSystemProperties() { return System.getProperties().stringPropertyNames().stream() - .filter(property -> property.startsWith(SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX)) + .filter(property -> property.startsWith(SPRING_DATA_GEMFIRE_SYSTEM_PROPERTY_PREFIX) + || property.startsWith(SPRING_GEMFIRE_SYSTEM_PROPERTY_PREFIX)) .map(property -> String.format("-D%1$s=%2$s", property, System.getProperty(property))) .collect(Collectors.toList()); } diff --git a/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java b/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java index 4b2ceb4e..6570f7ae 100644 --- a/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java +++ b/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java @@ -22,6 +22,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; @@ -233,6 +234,22 @@ public class ProcessWrapper { Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown)); } + /* (non-Javadoc) */ + public void signal() { + try { + OutputStream outputStream = process.getOutputStream(); + outputStream.write("\n".getBytes()); + outputStream.flush(); + } + catch (IOException e) { + log.warning("Failed to signal process"); + + if (log.isLoggable(Level.FINE)) { + log.fine(ThrowableUtils.toString(e)); + } + } + } + /* (non-Javadoc) */ public void signalStop() { try { diff --git a/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests.java b/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java similarity index 54% rename from src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests.java rename to src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java index 741ecc03..5ebd19e8 100644 --- a/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests.java +++ b/src/test/java/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests.java @@ -1,11 +1,11 @@ /* * Copyright 2002-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. @@ -21,39 +21,50 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.ForkUtil; -import org.springframework.data.gemfire.fork.SpringCacheServerProcess; +import org.springframework.data.gemfire.fork.ServerProcess; +import org.springframework.data.gemfire.process.ProcessWrapper; import org.springframework.data.gemfire.repository.sample.Person; import org.springframework.data.gemfire.repository.sample.PersonRepository; +import org.springframework.data.gemfire.test.support.ClientServerIntegrationTestsSupport; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; /** * @author David Turanski * @author John Blum */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @ContextConfiguration -public class RepositoryClientRegionTests { +@SuppressWarnings("unused") +public class RepositoryClientRegionIntegrationTests extends ClientServerIntegrationTestsSupport { + + private static ProcessWrapper gemfireServer; @Autowired - PersonRepository repository; + private PersonRepository repository; @BeforeClass - public static void startUp() throws Exception { - System.setProperty("gemfire.log-level", "warning"); - ForkUtil.startCacheServer(String.format("%1$s %2$s", SpringCacheServerProcess.class.getName(), - "/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-server-context.xml")); - } + public static void startGemFireServer() throws Exception { + int availablePort = findAvailablePort(); - @Test - public void testFindAllAndCount() { - assertEquals(2, repository.count()); - assertEquals(2, ((Collection) repository.findAll()).size()); + gemfireServer = run(ServerProcess.class, + String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort), + getServerContextXmlFileLocation(RepositoryClientRegionIntegrationTests.class)); + + waitForServerToStart(DEFAULT_HOSTNAME, availablePort); + + System.setProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY, String.valueOf(availablePort)); } @AfterClass - public static void cleanUp() { - ForkUtil.sendSignal(); + public static void stopGemFireServer() { + System.clearProperty(GEMFIRE_CACHE_SERVER_PORT_PROPERTY); + stop(gemfireServer); + } + + @Test + public void findAllAndCountIsCorrect() { + assertEquals(2, repository.count()); + assertEquals(2, ((Collection) repository.findAll()).size()); } } 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 cbe4c501..32605e9f 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 @@ -18,10 +18,12 @@ package org.springframework.data.gemfire.test.support; import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.data.gemfire.process.ProcessExecutor.launch; import static org.springframework.data.gemfire.util.ArrayUtils.asArray; import java.io.File; import java.io.IOException; +import java.net.ServerSocket; import java.net.Socket; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -30,7 +32,6 @@ 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.ProcessExecutor; import org.springframework.data.gemfire.process.ProcessWrapper; import org.springframework.data.gemfire.util.CollectionUtils; @@ -40,6 +41,9 @@ import org.springframework.data.gemfire.util.CollectionUtils; * * @author John Blum * @see java.io.File + * @see java.net.ServerSocket + * @see java.net.Socket + * @see java.time.LocalDateTime * @see org.apache.geode.cache.server.CacheServer * @see org.springframework.context.annotation.AnnotationConfigApplicationContext * @see org.springframework.data.gemfire.process.ProcessExecutor @@ -51,15 +55,17 @@ import org.springframework.data.gemfire.util.CollectionUtils; @SuppressWarnings("unused") public class ClientServerIntegrationTestsSupport { - protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20); + protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(30); protected static final long DEFAULT_WAIT_INTERVAL = 500L; // milliseconds - protected static final String DEFAULT_GEMFIRE_LOG_FILE = "gemfire-server.log"; - protected static final String DEFAULT_GEMFIRE_LOG_LEVEL = "config"; - protected static final String DIRECTORY_DELETE_ON_EXIT_PROPERTY = "sdg.directory.delete-on-exit"; - protected static final String GEMFIRE_LOG_FILE_PROPERTY = "gemfire.log.file"; - protected static final String GEMFIRE_LOG_LEVEL_PROPERTY = "gemfire.log.level"; - protected static final String PROCESS_RUN_MANUAL_PROPERTY = "sdg.process.run.manual"; + protected static final String DEFAULT_HOSTNAME = "localhost"; + protected static final String DIRECTORY_DELETE_ON_EXIT_PROPERTY = "spring.data.gemfire.directory.delete-on-exit"; + protected static final String GEMFIRE_CACHE_SERVER_PORT_PROPERTY = "spring.data.gemfire.cache.server.port"; + protected static final String GEMFIRE_LOG_FILE = "gemfire-server.log"; + protected static final String GEMFIRE_LOG_FILE_PROPERTY = "spring.data.gemfire.gemfire.log.file"; + protected static final String GEMFIRE_LOG_LEVEL = "warning"; + protected static final String GEMFIRE_LOG_LEVEL_PROPERTY = "spring.data.gemfire.gemfire.log.level"; + protected static final String PROCESS_RUN_MANUAL_PROPERTY = "spring.data.gemfire.process.run-manual"; protected static final String SYSTEM_PROPERTIES_LOG_FILE = "system-properties.log"; protected static final String TEST_GEMFIRE_LOG_LEVEL = "warning"; @@ -91,6 +97,49 @@ public class ClientServerIntegrationTestsSupport { return directory; } + /* (non-Javadoc) */ + protected static int findAvailablePort() throws IOException { + ServerSocket serverSocket = null; + + try { + serverSocket = new ServerSocket(0); + return serverSocket.getLocalPort(); + } + finally { + SocketUtils.close(serverSocket); + } + } + + /* (non-Javadoc) */ + protected static String getClassNameAsPath(Class type) { + return type.getName().replaceAll("\\.", "/"); + } + + /* (non-Javadoc) */ + protected static String getClassNameAsPath(Object obj) { + return getClassNameAsPath(obj.getClass()); + } + + /* (non-Javadoc) */ + protected static String getPackageNameAsPath(Class type) { + return type.getPackage().getName().replaceAll("\\.", "/"); + } + + /* (non-Javadoc) */ + protected static String getPackageNameAsPath(Object obj) { + return getPackageNameAsPath(obj.getClass()); + } + + /* (non-Javadoc) */ + protected static String getContextXmlFileLocation(Class type) { + return getClassNameAsPath(type).concat("-context.xml"); + } + + /* (non-Javadoc) */ + protected static String getServerContextXmlFileLocation(Class type) { + return getClassNameAsPath(type).concat("-server-context.xml"); + } + /* (non-Javadoc) */ protected static boolean isDeleteDirectoryOnExit() { return Boolean.valueOf(System.getProperty(DIRECTORY_DELETE_ON_EXIT_PROPERTY, Boolean.TRUE.toString())); @@ -103,7 +152,7 @@ public class ClientServerIntegrationTestsSupport { /* (non-Javadoc) */ protected static String logFile() { - return logFile(DEFAULT_GEMFIRE_LOG_FILE); + return logFile(GEMFIRE_LOG_FILE); } /* (non-Javadoc) */ @@ -113,7 +162,7 @@ public class ClientServerIntegrationTestsSupport { /* (non-Javadoc) */ protected static String logLevel() { - return logLevel(DEFAULT_GEMFIRE_LOG_LEVEL); + return logLevel(GEMFIRE_LOG_LEVEL); } /* (non-Javadoc) */ @@ -134,8 +183,7 @@ public class ClientServerIntegrationTestsSupport { /* (non-Javadoc) */ protected static ProcessWrapper run(File workingDirectory, Class type, String... arguments) throws IOException { - return (isProcessRunManual() ? null - : ProcessExecutor.launch(createDirectory(workingDirectory), type, arguments)); + return (isProcessRunAuto() ? launch(createDirectory(workingDirectory), type, arguments) : null); } /* (non-Javadoc) */ @@ -147,8 +195,12 @@ public class ClientServerIntegrationTestsSupport { protected static ProcessWrapper run(File workingDirectory, String classpath, Class type, String... arguments) throws IOException { - return (isProcessRunManual() ? null - : ProcessExecutor.launch(createDirectory(workingDirectory), classpath, type, arguments)); + return (isProcessRunAuto() ? launch(createDirectory(workingDirectory), classpath, type, arguments) : null); + } + + /* (non-Javadoc) */ + protected static boolean isProcessRunAuto() { + return !isProcessRunManual(); } /* (non-Javadoc) */ @@ -232,4 +284,30 @@ public class ClientServerIntegrationTestsSupport { } }); } + + protected static boolean waitOn(Condition condition) { + return waitOn(condition, DEFAULT_WAIT_DURATION); + } + + @SuppressWarnings("all") + protected static boolean waitOn(Condition condition, long duration) { + long timeout = (System.currentTimeMillis() + duration); + + try { + while (!condition.evaluate() && System.currentTimeMillis() < timeout) { + synchronized (condition) { + TimeUnit.MILLISECONDS.timedWait(condition, DEFAULT_WAIT_INTERVAL); + } + } + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + return condition.evaluate(); + } + + protected interface Condition { + boolean evaluate(); + } } diff --git a/src/test/resources/org/springframework/data/gemfire/client/clientcache-with-subregion-config.xml b/src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-context.xml similarity index 59% rename from src/test/resources/org/springframework/data/gemfire/client/clientcache-with-subregion-config.xml rename to src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-context.xml index dbda3373..39e7f707 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/clientcache-with-subregion-config.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-context.xml @@ -1,17 +1,27 @@ - + + + + warning + + + - + diff --git a/src/test/resources/org/springframework/data/gemfire/client/servercache-with-region-for-client.xml b/src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-server-context.xml similarity index 78% rename from src/test/resources/org/springframework/data/gemfire/client/servercache-with-region-for-client.xml rename to src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-server-context.xml index bfecbaee..bd8c0251 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/servercache-with-region-for-client.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/ClientSubRegionIntegrationTests-server-context.xml @@ -1,14 +1,18 @@ + + GemFireServerWithRegionForClientConfig 0 @@ -17,7 +21,7 @@ - + diff --git a/src/test/resources/org/springframework/data/gemfire/client/datasource-client.xml b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-context.xml similarity index 76% rename from src/test/resources/org/springframework/data/gemfire/client/datasource-client.xml rename to src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-context.xml index 4cc727f8..b30ea618 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/datasource-client.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-context.xml @@ -1,16 +1,20 @@ + + - + diff --git a/src/test/resources/org/springframework/data/gemfire/client/datasource-server.xml b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-server-context.xml similarity index 73% rename from src/test/resources/org/springframework/data/gemfire/client/datasource-server.xml rename to src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-server-context.xml index 7172de90..9a251ede 100644 --- a/src/test/resources/org/springframework/data/gemfire/client/datasource-server.xml +++ b/src/test/resources/org/springframework/data/gemfire/client/GemFireDataSourceIntegrationTests-server-context.xml @@ -1,13 +1,16 @@ + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> + + DataSourceServerConfig @@ -17,7 +20,7 @@ - + diff --git a/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml b/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml deleted file mode 100644 index c752827c..00000000 --- a/src/test/resources/org/springframework/data/gemfire/client/datasource-client-with-regions.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest-context.xml b/src/test/resources/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest-context.xml index 6f2c8ea9..0a303370 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/xml/ContinuousQueryListenerContainerNamespaceTest-context.xml @@ -1,16 +1,20 @@ + + warning @@ -18,7 +22,7 @@ - + @@ -27,8 +31,8 @@ + auto-startup="false" error-handler="testErrorHandler" phase="4" + task-executor="testTaskExecutor"> diff --git a/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-context.xml b/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-context.xml index 263f77c5..029a0978 100644 --- a/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-context.xml @@ -13,19 +13,14 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd "> - - localhost - 12480 - - - + - config + warning - + diff --git a/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-server-context.xml b/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-server-context.xml index e7a30e68..f77d73df 100644 --- a/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-server-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest-server-context.xml @@ -10,14 +10,7 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd "> - - localhost - localhost - 2 - 12480 - - - + SpringGemFireServerFunctionCreationWithPdx @@ -41,8 +34,7 @@ - + diff --git a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml index ee8ac746..780f822a 100644 --- a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-context.xml @@ -1,24 +1,28 @@ + + - warning + error - - - - + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-server-context.xml b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-server-context.xml index 43db6257..af72a9b2 100644 --- a/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-server-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/function/execution/FunctionIntegrationTests-server-context.xml @@ -1,7 +1,7 @@ + + FunctionIntegrationTestsServerContext false 0 - warning + error - + diff --git a/src/test/resources/org/springframework/data/gemfire/listener/container.xml b/src/test/resources/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests-context.xml similarity index 82% rename from src/test/resources/org/springframework/data/gemfire/listener/container.xml rename to src/test/resources/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests-context.xml index 2178f3bb..93ad8e80 100644 --- a/src/test/resources/org/springframework/data/gemfire/listener/container.xml +++ b/src/test/resources/org/springframework/data/gemfire/listener/adapter/ContainerXmlSetupIntegrationTests-context.xml @@ -1,24 +1,29 @@ + + + ContainerXmlSetupIntegrationTests warning - + diff --git a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-context.xml new file mode 100644 index 00000000..1c66fd53 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-context.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + gemfire.log-level + warning + + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-server-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml similarity index 66% rename from src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-server-context.xml rename to src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml index fd7e4b23..d7206f08 100644 --- a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-server-context.xml +++ b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionIntegrationTests-server-context.xml @@ -1,28 +1,32 @@ + + - RepositoryClientRegionTestsServerContext + RepositoryClientRegionIntegrationTestsServer 0 warning - + - + - + diff --git a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-context.xml b/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-context.xml deleted file mode 100644 index f553472c..00000000 --- a/src/test/resources/org/springframework/data/gemfire/repository/config/RepositoryClientRegionTests-context.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - -