SGF-593 - Refactor failing client/server integration tests due to static port allocation.

This commit is contained in:
John Blum
2017-02-04 22:45:55 -08:00
parent fd8c16b9b5
commit 6290d1ee0c
49 changed files with 1519 additions and 1225 deletions

View File

@@ -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()]));

View File

@@ -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<String> buildJavaCommand(String arguments) {
return buildJavaCommand(arguments.split("\\s+"));
}
List<String> command = new ArrayList<String>(args.length + 3);
private static List<String> buildJavaCommand(String[] args) {
List<String> 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<String> 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();
}
}

View File

@@ -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() {

View File

@@ -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

View File

@@ -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<Long, Person> peopleRegion(GemFireCache gemfireCache) {
@Bean(name = "People")
LocalRegionFactoryBean<Long, Person> peopleRegion(GemFireCache gemfireCache) {
LocalRegionFactoryBean<Long, Person> peopleRegion = new LocalRegionFactoryBean<Long, Person>();
peopleRegion.setCache(gemfireCache);

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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<String> 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");
}
}

View File

@@ -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<String> 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();
}
}

View File

@@ -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();
}
}

View File

@@ -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<Long, String> exampleRegion(GemFireCache gemfireCache,
RegionAttributes<Long, String> exampleAttributes) {
ClientRegionFactoryBean<Long, String> exampleRegion = new ClientRegionFactoryBean<Long, String>();
ClientRegionFactoryBean<Long, String> exampleRegion = new ClientRegionFactoryBean<>();
exampleRegion.setCache(gemfireCache);
exampleRegion.setAttributes(exampleAttributes);
@@ -136,5 +136,4 @@ public class LocalOnlyClientCacheIntegrationTest {
return exampleRegionAttributes;
}
}
}

View File

@@ -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"));
}
}

View File

@@ -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<String, Integer> regionFactory = cache.createRegionFactory();
regionFactory.setDataPolicy(DataPolicy.REPLICATE);
regionFactory.setScope(Scope.DISTRIBUTED_ACK);
Region<String, Integer> 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!");
}
}

View File

@@ -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<String, Integer> 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<String, Integer> 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();
}
}

View File

@@ -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<Object,Object> testRegion;
private static final int DEFAULT_CACHE_SERVER_PORT = 40404;
private static Region<Object,Object> 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<Object,Object> regionFactory = gemfireCache.createRegionFactory(RegionShortcut.REPLICATE);
Cache cache = new CacheFactory(props).create();
regionFactory.setScope(Scope.DISTRIBUTED_ACK);
// Create region.
RegionFactory<Object,Object> 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);
}
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}
}

View File

@@ -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");
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -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<String, Object> pdxData) {
@@ -427,5 +439,4 @@ public class ClientCacheFunctionExecutionWithPdxIntegrationTest {
return null;
}
}
}

View File

@@ -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<String, String> 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.<String, String>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<String> results = functionExecution.setArgs("1", "2", "3").setFunctionId("echoFunction").execute();
int count = 1;
for (String result : results) {
assertThat(result).isEqualTo(String.valueOf(count++));
}
}
}

View File

@@ -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<String, Integer> 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<String, Integer> 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<String> results = functionExecution
.setArgs("1","2","3")
.setFunctionId("echoFunction")
.execute();
Iterator<String> it = results.iterator();
for (int i = 1; i<= 3; i++) {
assertEquals(String.valueOf(i),it.next());
}
}
}

View File

@@ -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<String, Integer> 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);
}

View File

@@ -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<String, String> 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.<String, String>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<String> results = functionTemplate.execute("echoFunction", "1", "2", "3");
int count = 1;
for (String result : results) {
assertThat(result).isEqualTo(String.valueOf(count++));
}
}
}

View File

@@ -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<String, Integer> 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<String, Integer> 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<String> results = functionTemplate.execute("echoFunction","1","2","3");
Iterator<String> it = results.iterator();
for (int i = 1; i<= 3; i++) {
assertEquals(String.valueOf(i),it.next());
}
}
}

View File

@@ -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<CqEvent> 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);
}
}

View File

@@ -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<CqEvent> bag = new ArrayList<CqEvent>();
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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<String> command = new ArrayList<>();
List<String> programArgs = Collections.emptyList();
List<String> 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<? extends String> 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());
}

View File

@@ -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 {

View File

@@ -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<Person>) 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<Person>) repository.findAll()).size());
}
}

View File

@@ -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();
}
}