merge 1.3.x into master
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* Copyright 2011 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.
|
||||
@@ -35,24 +35,27 @@ public class ForkUtil {
|
||||
|
||||
public static OutputStream cloneJVM(String argument) {
|
||||
String cp = System.getProperty("java.class.path");
|
||||
String home = System.getProperty("java.home");
|
||||
String home = System.getProperty("java.home");
|
||||
|
||||
Process proc = null;
|
||||
String sp = System.getProperty("file.separator");
|
||||
String java = home + sp + "bin" + sp + "java";
|
||||
String argCp = " -cp " + cp;
|
||||
String argClass = argument;
|
||||
String cmd = java + "-cp " + cp + " " + argClass;
|
||||
|
||||
final Process proc;
|
||||
String cmd = java + argCp + " " + argClass;
|
||||
try {
|
||||
ProcessBuilder builder = new ProcessBuilder(java , "-cp", cp, argClass);
|
||||
builder.redirectErrorStream(true);
|
||||
proc = builder.start();
|
||||
//ProcessBuilder builder = new ProcessBuilder(cmd, argCp, argClass);
|
||||
//builder.redirectErrorStream(true);
|
||||
proc = Runtime.getRuntime().exec(cmd);
|
||||
} catch (IOException ioe) {
|
||||
throw new IllegalStateException("Cannot start command " + cmd, ioe);
|
||||
}
|
||||
|
||||
System.out.println("Started fork from command\n" + cmd);
|
||||
|
||||
final BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
final Process p = proc;
|
||||
|
||||
final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
final AtomicBoolean run = new AtomicBoolean(true);
|
||||
|
||||
Thread reader = new Thread(new Runnable() {
|
||||
@@ -80,11 +83,11 @@ public class ForkUtil {
|
||||
System.out.println("Stopping fork...");
|
||||
run.set(false);
|
||||
os = null;
|
||||
if (proc != null)
|
||||
proc.destroy();
|
||||
if (p != null)
|
||||
p.destroy();
|
||||
|
||||
try {
|
||||
proc.waitFor();
|
||||
p.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
@@ -95,9 +98,17 @@ public class ForkUtil {
|
||||
os = proc.getOutputStream();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
public static OutputStream cacheServer(Class<?> clazz) {
|
||||
return startCacheServer(clazz.getName());
|
||||
}
|
||||
|
||||
public static OutputStream cacheServer() {
|
||||
String className = "org.springframework.data.gemfire.fork.CacheServerProcess";
|
||||
return startCacheServer("org.springframework.data.gemfire.fork.CacheServerProcess");
|
||||
}
|
||||
|
||||
private static OutputStream startCacheServer(String className) {
|
||||
|
||||
if (controlFileExists(className)) {
|
||||
deleteControlFile(className);
|
||||
}
|
||||
@@ -131,22 +142,17 @@ public class ForkUtil {
|
||||
}
|
||||
|
||||
public static boolean deleteControlFile(String name) {
|
||||
String path = getControlFilePath(name);
|
||||
String path = TEMP_DIR + File.separator + name;
|
||||
return new File(path).delete();
|
||||
}
|
||||
|
||||
public static boolean createControlFile(String name) throws IOException {
|
||||
String path = getControlFilePath(name);
|
||||
System.out.println("creating " + path);
|
||||
String path = TEMP_DIR + File.separator + name;
|
||||
return new File(path).createNewFile();
|
||||
}
|
||||
|
||||
public static boolean controlFileExists(String name) {
|
||||
String path = getControlFilePath(name);
|
||||
String path = TEMP_DIR + File.separator + name;
|
||||
return new File(path).exists();
|
||||
}
|
||||
|
||||
private static String getControlFilePath(String name) {
|
||||
return TEMP_DIR.endsWith(File.separator)? TEMP_DIR + name : TEMP_DIR + File.separator + name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2011 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.springframework.data.gemfire.ForkUtil;
|
||||
import org.springframework.data.gemfire.function.MethodInvokingFunction;
|
||||
|
||||
import com.gemstone.gemfire.cache.AttributesFactory;
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.CacheFactory;
|
||||
import com.gemstone.gemfire.cache.DataPolicy;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.Scope;
|
||||
import com.gemstone.gemfire.cache.execute.FunctionAdapter;
|
||||
import com.gemstone.gemfire.cache.execute.FunctionContext;
|
||||
import com.gemstone.gemfire.cache.execute.FunctionService;
|
||||
import com.gemstone.gemfire.cache.server.CacheServer;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class FunctionCacheServerProcess {
|
||||
static Region testRegion;
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("name", "CqServer");
|
||||
props.setProperty("log-level", "config");
|
||||
|
||||
System.out.println("\nConnecting to the distributed system and creating the cache.");
|
||||
DistributedSystem ds = DistributedSystem.connect(props);
|
||||
Cache cache = CacheFactory.create(ds);
|
||||
|
||||
// Create region.
|
||||
AttributesFactory factory = new AttributesFactory();
|
||||
factory.setDataPolicy(DataPolicy.REPLICATE);
|
||||
factory.setScope(Scope.DISTRIBUTED_ACK);
|
||||
testRegion = cache.createRegion("test-function", factory.create());
|
||||
System.out.println("Test region, " + testRegion.getFullPath() + ", created in cache.");
|
||||
|
||||
// Start Cache Server.
|
||||
CacheServer server = cache.addCacheServer();
|
||||
server.setPort(40404);
|
||||
server.setNotifyBySubscription(true);
|
||||
server.start();
|
||||
System.out.println("Server started");
|
||||
|
||||
|
||||
testRegion.put("one", 1);
|
||||
testRegion.put("two", 2);
|
||||
testRegion.put("three", 3);
|
||||
|
||||
FunctionService.registerFunction(new ServerFunction());
|
||||
|
||||
FunctionService.registerFunction(new MethodInvokingFunction());
|
||||
|
||||
ForkUtil.createControlFile(FunctionCacheServerProcess.class.getName());
|
||||
|
||||
System.out.println("Waiting for shutdown");
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
|
||||
bufferedReader.readLine();
|
||||
}
|
||||
|
||||
static class ServerFunction extends FunctionAdapter {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.gemstone.gemfire.cache.execute.FunctionAdapter#execute(com.gemstone.gemfire.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 com.gemstone.gemfire.cache.execute.FunctionAdapter#getId()
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return "serverFunction";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
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;
|
||||
import org.springframework.data.gemfire.function.foo.Foo;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
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 testRegionExecution() {
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class, "oneArg", "one");
|
||||
RegionFunctionExecution<Integer> execution = new RegionFunctionExecution<Integer>(clientRegion,
|
||||
new MethodInvokingFunction(), invocation);
|
||||
|
||||
int result = execution.executeAndExtract();
|
||||
assertEquals(1, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegionExecutionWithRegisteredFunction() {
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class, "oneArg", "one");
|
||||
RegionFunctionExecution<Integer> execution = new RegionFunctionExecution<Integer>(clientRegion,
|
||||
new MethodInvokingFunction().getId(), invocation);
|
||||
int result = execution.executeAndExtract();
|
||||
assertEquals(1, result);
|
||||
}
|
||||
|
||||
// TODO: Filter only works on partitioned region. No effect here, but server
|
||||
// won't start with a partitioned region. Probably because no locator
|
||||
@Test
|
||||
public void testRegionExecutionWithFilter() {
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class, "oneArg", "one");
|
||||
Set<String> keys = new HashSet<String>();
|
||||
keys.add("two");
|
||||
RegionFunctionExecution<Integer> execution = new RegionFunctionExecution<Integer>(clientRegion,
|
||||
new MethodInvokingFunction().getId(), invocation);
|
||||
execution.setKeys(keys);
|
||||
Integer result = execution.executeAndExtract();
|
||||
// assertEquals(null,result.get(0));
|
||||
assertEquals(1, result.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegionExecutionForMap() {
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class, "getMapWithNoArgs");
|
||||
RegionFunctionExecution<Map<String, Integer>> execution = new RegionFunctionExecution<Map<String, Integer>>(
|
||||
clientRegion, new MethodInvokingFunction().getId(), invocation);
|
||||
execution.execute();
|
||||
|
||||
Map<String, Integer> result = execution.executeAndExtract();
|
||||
assertTrue(result.containsKey("one"));
|
||||
assertEquals(1, result.get("one").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServersExecutionWithRegisteredFunction() {
|
||||
assertNull(clientRegion.get("four"));
|
||||
ServersFunctionExecution<?> execution = new ServersFunctionExecution<Object>(cache, "serverFunction", "four", new Integer(
|
||||
4));
|
||||
execution.execute();
|
||||
assertNotNull(clientRegion.get("four"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerExecutionWithRegisteredFunction() {
|
||||
assertNull(clientRegion.get("five"));
|
||||
ServerFunctionExecution<?> execution = new ServerFunctionExecution<Object>(cache, "serverFunction", "five", new Integer(5));
|
||||
Object result = execution.executeAndExtract();
|
||||
assertNull(result);
|
||||
assertNotNull(clientRegion.get("five"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
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 static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
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.function.foo.Foo;
|
||||
import org.springframework.data.gemfire.function.foo.IFoo;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class GemfireFunctionProxyFactoryBeanTest {
|
||||
|
||||
private GemfireFunctionOperations<?> functionOperations;
|
||||
static Log logger = LogFactory.getLog(GemfireFunctionProxyFactoryBeanTest.class);
|
||||
|
||||
@Autowired
|
||||
private IFoo foo;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
private Region<String,Integer> region;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() {
|
||||
assertNotNull(foo);
|
||||
functionOperations = mock(GemfireFunctionOperations.class);
|
||||
|
||||
region = context.getBean("someRegion",Region.class);
|
||||
assertNotNull(region);
|
||||
|
||||
region.put("one",1);
|
||||
region.put("two",2);
|
||||
region.put("three",3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstance() throws Exception {
|
||||
GemfireFunctionOperations<?> functionOperations = mock(GemfireFunctionOperations.class);
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class,Foo.class.getName(),functionOperations);
|
||||
IFoo foo = (IFoo)proxy.getObject();
|
||||
assertTrue(foo instanceof FilterAware);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetFilter() throws Exception {
|
||||
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class,Foo.class.getName(),functionOperations);
|
||||
IFoo foo = (IFoo)proxy.getObject();
|
||||
|
||||
Set<String> filter = Collections.singleton("foo");
|
||||
Object obj = ((FilterAware) foo).setFilter(filter);
|
||||
assertSame(obj,foo);
|
||||
assertSame(filter,proxy.getFilter());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRemoteExecutionOneArg() {
|
||||
assertEquals(1,foo.oneArg("one").intValue());
|
||||
((FilterAware)foo).setFilter(Collections.singleton("one"));
|
||||
assertEquals(1,foo.oneArg("one").intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoteExecutionTwoArg() {
|
||||
assertEquals(3,foo.twoArg("one","two").intValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRemoteExectionArrayList() {
|
||||
ArrayList<Integer> ints = new ArrayList<Integer>(Arrays.asList(new Integer[]{1,2,3}));
|
||||
assertEquals(1,foo.collections(ints).get(0).intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoteExectionMap() {
|
||||
Map<String,Integer> result = foo.getMapWithNoArgs();
|
||||
assertEquals(1,result.get("one").intValue());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
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;
|
||||
import org.springframework.data.gemfire.function.foo.Foo;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
|
||||
/**
|
||||
* @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 testExecuteOnRegion() {
|
||||
GemfireFunctionOperations<Integer> functionTemplate = new GemfireFunctionTemplate<Integer>(cache);
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"oneArg", "two");
|
||||
List<Integer> result = functionTemplate.executeOnRegion(new MethodInvokingFunction().getId(),"test-function",invocation);
|
||||
assertEquals(2,result.get(0).intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnRegionAndExtract() {
|
||||
GemfireFunctionOperations<Integer> functionTemplate = new GemfireFunctionTemplate<Integer>(cache);
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"twoArg", "two","three");
|
||||
int result = functionTemplate.executeOnRegionAndExtract(new MethodInvokingFunction(),"test-function",invocation);
|
||||
assertEquals(5,result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteOnServer() {
|
||||
assertNull(clientRegion.get("four"));
|
||||
GemfireFunctionOperations<?> functionTemplate = new GemfireFunctionTemplate<Object>(cache);
|
||||
functionTemplate.executeOnServers("serverFunction","four",4);
|
||||
assertEquals(4,clientRegion.get("four").intValue());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.ForkUtil;
|
||||
import org.springframework.data.gemfire.GemfireCallback;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.function.foo.Foo;
|
||||
|
||||
import com.gemstone.gemfire.GemFireCheckedException;
|
||||
import com.gemstone.gemfire.GemFireException;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.cache.client.PoolFactory;
|
||||
import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
import com.gemstone.gemfire.cache.execute.Execution;
|
||||
import com.gemstone.gemfire.cache.execute.FunctionService;
|
||||
import com.gemstone.gemfire.cache.execute.ResultCollector;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
public class MethodInvokingFunctionTests {
|
||||
private static ClientCache cache = null;
|
||||
|
||||
private static MethodInvokingFunction methodInvokingFunction = new MethodInvokingFunction();
|
||||
private static Pool pool = null;
|
||||
|
||||
private static Region<String,Integer> clientRegion = null;
|
||||
|
||||
private static GemfireTemplate gemfireTemplate;
|
||||
|
||||
@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();
|
||||
|
||||
PoolFactory pf = PoolManager.createFactory();
|
||||
pf.addServer("localhost", 40404);
|
||||
pf.setSubscriptionEnabled(true);
|
||||
pool = pf.create("client");
|
||||
|
||||
ClientRegionFactory<String, Integer> crf = cache.createClientRegionFactory(ClientRegionShortcut.LOCAL);
|
||||
crf.setPoolName("client");
|
||||
clientRegion = crf.create("test-cq");
|
||||
|
||||
gemfireTemplate = new GemfireTemplate(clientRegion);
|
||||
|
||||
ForkUtil.sendSignal();
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
@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 testInvokeRemoteFunctionOneArg() throws Exception {
|
||||
|
||||
gemfireTemplate.setExposeNativeRegion(true);
|
||||
|
||||
Integer val = gemfireTemplate.execute(new GemfireCallback<Integer>() {
|
||||
|
||||
public Integer doInGemfire(@SuppressWarnings("rawtypes") Region region) throws GemFireCheckedException, GemFireException {
|
||||
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"oneArg","one");
|
||||
Execution execution = FunctionService.onRegion(region);
|
||||
ResultCollector<?, ?> resultsCollector = execution.withArgs(invocation).execute(methodInvokingFunction);
|
||||
ArrayList<?> result = (ArrayList<?>)resultsCollector.getResult();
|
||||
return (Integer)result.get(0);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(1,val.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeRemoteFunctionTwoArgs() throws Exception {
|
||||
|
||||
gemfireTemplate.setExposeNativeRegion(true);
|
||||
|
||||
Integer val = gemfireTemplate.execute(new GemfireCallback<Integer>() {
|
||||
|
||||
public Integer doInGemfire(@SuppressWarnings("rawtypes") Region region) throws GemFireCheckedException, GemFireException {
|
||||
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"twoArg","one","three");
|
||||
Execution execution = FunctionService.onRegion(region);
|
||||
ResultCollector<?, ?> resultsCollector = execution.withArgs(invocation).execute(methodInvokingFunction);
|
||||
ArrayList<?> result = (ArrayList<?>)resultsCollector.getResult();
|
||||
return (Integer)result.get(0);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(4,val.intValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeRemoteFunctionCollections() throws Exception {
|
||||
|
||||
gemfireTemplate.setExposeNativeRegion(true);
|
||||
|
||||
List<Integer> val = gemfireTemplate.execute(new GemfireCallback<List<Integer>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Integer> doInGemfire(@SuppressWarnings("rawtypes") Region region) throws GemFireCheckedException, GemFireException {
|
||||
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(new Integer[]{1,2,3,4,5}));
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"collections",list);
|
||||
Execution execution = FunctionService.onRegion(region);
|
||||
|
||||
ResultCollector<?, ?> resultsCollector = execution.withArgs(invocation).execute(methodInvokingFunction);
|
||||
ArrayList<?> result = (ArrayList<?>)resultsCollector.getResult();
|
||||
//If result type is a list, Gemfire merges it into the results.
|
||||
return (List<Integer>)result;
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(5,val.size());
|
||||
for (int i=0; i<5; i++) {
|
||||
assertEquals(i+1,val.get(i).intValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeRemoteFunctionMap() throws Exception {
|
||||
|
||||
gemfireTemplate.setExposeNativeRegion(true);
|
||||
|
||||
Map<String, Integer> val = gemfireTemplate.execute(new GemfireCallback<Map<String, Integer>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Integer> doInGemfire(@SuppressWarnings("rawtypes") Region region) throws GemFireCheckedException, GemFireException {
|
||||
RemoteMethodInvocation invocation = new RemoteMethodInvocation(Foo.class,"getMapWithNoArgs");
|
||||
Execution execution = FunctionService.onRegion(region);
|
||||
ResultCollector<?, ?> resultsCollector = execution.withArgs(invocation).execute(methodInvokingFunction);
|
||||
ArrayList<?> result = (ArrayList<?>)resultsCollector.getResult();
|
||||
return (Map<String, Integer>)result.get(0);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(3,val.size());
|
||||
for (int i=0; i<3; i++) {
|
||||
assertTrue(val.values().contains(i+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.config;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.execute.Function;
|
||||
import com.gemstone.gemfire.cache.execute.FunctionService;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class AnnotationDrivenFunctionsTest {
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void testAnnotatedFunctions() {
|
||||
|
||||
assertTrue(FunctionService.isRegistered(FooFunction.class.getName()+".foo"));
|
||||
|
||||
Function function = FunctionService.getFunction(FooFunction.class.getName()+".foo");
|
||||
assertFalse(function.isHA());
|
||||
assertFalse(function.optimizeForWrite());
|
||||
assertFalse(function.hasResult());
|
||||
|
||||
assertTrue(FunctionService.isRegistered(FooFunction.class.getName()+".bar"));
|
||||
function = FunctionService.getFunction(FooFunction.class.getName()+".bar");
|
||||
assertTrue(function.isHA());
|
||||
assertFalse(function.optimizeForWrite());
|
||||
assertTrue(function.hasResult());
|
||||
|
||||
assertTrue(FunctionService.isRegistered("foo"));
|
||||
function = FunctionService.getFunction("foo");
|
||||
assertTrue(function.isHA());
|
||||
assertTrue(function.optimizeForWrite());
|
||||
assertTrue(function.hasResult());
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class FooFunction {
|
||||
@GemfireFunction
|
||||
public void foo () {
|
||||
}
|
||||
|
||||
@GemfireFunction(HA=true,optimizeForWrite=false)
|
||||
public String bar () {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Component
|
||||
public static class Foo2Function {
|
||||
@GemfireFunction(id="foo", HA=true,optimizeForWrite=true)
|
||||
public List<String> foo (Object someVal, @RegionData Map<?,?> region, Object someOtherValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@GemfireFunction(id="injectMultipleRegions", HA=true,optimizeForWrite=true)
|
||||
public List<String> injectMultipleRegions (@RegionData("someRegion") Map<?,?> someRegion, @RegionData("someOtherRegion") Map<?,?> someOtherRegion) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.foo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
public class Foo implements IFoo {
|
||||
|
||||
private Map<String, Integer> dataSet;
|
||||
|
||||
public Foo(Map<String, Integer> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
public Foo() {
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.foo.IFoo#oneArg(java.lang.String)
|
||||
*/
|
||||
public Integer oneArg(String key) {
|
||||
|
||||
return dataSet.get(key);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.foo.IFoo#twoArg(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public Integer twoArg(String akey, String bkey) {
|
||||
if (dataSet.get(akey) != null && dataSet.get(bkey) != null) {
|
||||
return dataSet.get(akey) + dataSet.get(bkey);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.foo.IFoo#collections(java.util.List)
|
||||
*/
|
||||
public List<Integer> collections(List<Integer> args) {
|
||||
return args;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.foo.IFoo#getMapWithNoArgs()
|
||||
*/
|
||||
public Map<String, Integer> getMapWithNoArgs() {
|
||||
if (dataSet.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HashMap<String, Integer>(dataSet);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.foo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
public interface IFoo {
|
||||
|
||||
public abstract Integer oneArg(String key);
|
||||
|
||||
public abstract Integer twoArg(String akey, String bkey);
|
||||
|
||||
public abstract List<Integer> collections(List<Integer> args);
|
||||
|
||||
public abstract Map<String, Integer> getMapWithNoArgs();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user