/* * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.rpc.impl; import junit.framework.TestCase; import org.exoplatform.container.PortalContainer; import org.exoplatform.container.configuration.ConfigurationManager; import org.exoplatform.container.xml.InitParams; import org.exoplatform.container.xml.ValueParam; import org.exoplatform.services.rpc.RPCException; import org.exoplatform.services.rpc.RemoteCommand; import org.exoplatform.services.rpc.SingleMethodCallCommand; import org.exoplatform.services.rpc.TopologyChangeEvent; import org.exoplatform.services.rpc.TopologyChangeListener; import org.exoplatform.services.rpc.impl.AbstractRPCService.MemberHasLeftException; import org.exoplatform.services.rpc.jgv3.RPCServiceImpl; import org.jgroups.Address; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; /** * This is the unit test class for the service {@link RPCServiceImpl} * * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas Filotto</a> * @version $Id$ * */ public class TestRPCServiceImpl extends TestCase { private PortalContainer container; private ConfigurationManager configManager; public void setUp() throws Exception { container = PortalContainer.getInstance(); configManager = (ConfigurationManager)container.getComponentInstanceOfType(ConfigurationManager.class); } public void testParameters() { InitParams params = null; try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a IllegalArgumentException since the jgroups config cannot be found"); } catch (IllegalArgumentException e) { // OK } params = new InitParams(); try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a IllegalArgumentException since the jgroups config cannot be found"); } catch (IllegalArgumentException e) { // OK } ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); params.addParameter(paramConf); try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a IllegalArgumentException since the jgroups config cannot be found"); } catch (IllegalArgumentException e) { // OK } paramConf.setValue("fakePath"); try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a IllegalArgumentException since the jgroups config cannot be found"); } catch (IllegalArgumentException e) { // OK } paramConf.setValue("jar:/conf/portal/udp.xml"); RPCServiceImpl service = null; try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(RPCServiceImpl.DEFAULT_TIMEOUT, service.getDefaultTimeout()); assertEquals(RPCServiceImpl.DEFAULT_RETRY_TIMEOUT, service.getRetryTimeout()); assertEquals(true, service.isAllowFailover()); assertEquals(RPCServiceImpl.CLUSTER_NAME + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } ValueParam paramTimeout = new ValueParam(); paramTimeout.setName(RPCServiceImpl.PARAM_DEFAULT_TIMEOUT); paramTimeout.setValue("fakeValue"); params.addParameter(paramTimeout); try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a NumberFormatException since the timeout is not properly set"); } catch (NumberFormatException e) { // OK } paramTimeout.setValue("60"); try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(60, service.getDefaultTimeout()); assertEquals(RPCServiceImpl.DEFAULT_RETRY_TIMEOUT, service.getRetryTimeout()); assertEquals(true, service.isAllowFailover()); assertEquals(RPCServiceImpl.CLUSTER_NAME + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } ValueParam paramRetryTimeout = new ValueParam(); paramRetryTimeout.setName(RPCServiceImpl.PARAM_RETRY_TIMEOUT); paramRetryTimeout.setValue("fakeValue"); params.addParameter(paramRetryTimeout); try { new RPCServiceImpl(container.getContext(), params, configManager); fail("We expect a NumberFormatException since the retry timeout is not properly set"); } catch (NumberFormatException e) { // OK } paramRetryTimeout.setValue("60"); try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(60, service.getDefaultTimeout()); assertEquals(60, service.getRetryTimeout()); assertEquals(true, service.isAllowFailover()); assertEquals(RPCServiceImpl.CLUSTER_NAME + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } ValueParam paramAllowFailover = new ValueParam(); paramAllowFailover.setName(RPCServiceImpl.PARAM_ALLOW_FAILOVER); paramAllowFailover.setValue("fakeValue"); params.addParameter(paramAllowFailover); try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(60, service.getDefaultTimeout()); assertEquals(60, service.getRetryTimeout()); assertEquals(false, service.isAllowFailover()); assertEquals(RPCServiceImpl.CLUSTER_NAME + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } paramAllowFailover.setValue("TRUE"); try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(60, service.getDefaultTimeout()); assertEquals(60, service.getRetryTimeout()); assertEquals(true, service.isAllowFailover()); assertEquals(RPCServiceImpl.CLUSTER_NAME + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } ValueParam paramClusterName = new ValueParam(); paramClusterName.setName(RPCServiceImpl.PARAM_CLUSTER_NAME); paramClusterName.setValue("MyName"); params.addParameter(paramClusterName); try { service = new RPCServiceImpl(container.getContext(), params, configManager); assertEquals(60, service.getDefaultTimeout()); assertEquals(paramClusterName.getValue() + "-" + container.getContext().getName(), service.getClusterName()); } finally { if (service != null) { service.stop(); } } } public void testStates() throws Exception { InitParams params = new InitParams(); ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); paramConf.setValue("jar:/conf/portal/udp.xml"); params.addParameter(paramConf); RPCServiceImpl service = null; RemoteCommand foo = new RemoteCommand() { public String getId() { return "foo"; } public String execute(Serializable[] args) throws Throwable { return null; } }; try { service = new RPCServiceImpl(container.getContext(), params, configManager); service.registerCommand(foo); try { service.executeCommandOnAllNodes(foo, true); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnAllNodes(foo, 10); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(foo, true); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(foo, 10); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.isCoordinator(); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } service.start(); assertEquals(true, service.isCoordinator()); service.executeCommandOnAllNodes(foo, true); service.executeCommandOnAllNodes(foo, 10); service.executeCommandOnCoordinator(foo, true); service.executeCommandOnCoordinator(foo, 10); } finally { if (service != null) { service.stop(); } } try { service.executeCommandOnAllNodes(foo, true); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnAllNodes(foo, 10); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(foo, true); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(foo, 10); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } } public void testCommands() throws Exception { InitParams params = new InitParams(); ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); paramConf.setValue("jar:/conf/portal/udp.xml"); params.addParameter(paramConf); RPCServiceImpl service = null; try { service = new RPCServiceImpl(container.getContext(), params, configManager); RemoteCommand fake = new RemoteCommand() { public String getId() { return "fake"; } public String execute(Serializable[] args) throws Throwable { return null; } }; RemoteCommand fake2 = new RemoteCommand() { public String getId() { return "fake2"; } public String execute(Serializable[] args) throws Throwable { return null; } }; RemoteCommand fake2_Unregistered = new RemoteCommand() { public String getId() { return "fake2"; } public String execute(Serializable[] args) throws Throwable { return null; } }; service.registerCommand(fake2); RemoteCommand Exception = new RemoteCommand() { public String getId() { return "Exception"; } public String execute(Serializable[] args) throws Throwable { throw new Exception("MyException"); } }; service.registerCommand(Exception); RemoteCommand Error = new RemoteCommand() { public String getId() { return "Error"; } public String execute(Serializable[] args) throws Throwable { throw new Error("MyError"); } } ; service.registerCommand(Error); RemoteCommand StringValue = new RemoteCommand() { public String getId() { return "StringValue"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service.registerCommand(StringValue); RemoteCommand NullValue = new RemoteCommand() { public String getId() { return "NullValue"; } public String execute(Serializable[] args) throws Throwable { return null; } }; service.registerCommand(NullValue); RemoteCommand LongTask = new RemoteCommand() { public String getId() { return "LongTask"; } public String execute(Serializable[] args) throws Throwable { Thread.sleep(2000); return null; } }; service.registerCommand(LongTask); service.start(); try { service.executeCommandOnAllNodes(fake, true); fail("We expect a RPCException since the command is unknown"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(fake, true); fail("We expect a RPCException since the command is unknown"); } catch (RPCException e) { // OK } try { service.executeCommandOnAllNodes(fake2_Unregistered, true); fail("We expect a RPCException since the command is unknown"); } catch (RPCException e) { // OK } try { service.executeCommandOnCoordinator(fake2_Unregistered, true); fail("We expect a RPCException since the command is unknown"); } catch (RPCException e) { // OK } List<Object> result; result = service.executeCommandOnAllNodes(Exception, true); assertTrue(result != null && result.size() == 1); assertTrue("We expect a RPCException since one node could not execute the command", result.get(0) instanceof RPCException); try { service.executeCommandOnCoordinator(Exception, true); fail("We expect a RPCException since one node could not execute the command"); } catch (RPCException e) { // OK } result = service.executeCommandOnAllNodes(Error, true); assertTrue(result != null && result.size() == 1); assertTrue("We expect a RPCException since one node could not execute the command", result.get(0) instanceof RPCException); try { service.executeCommandOnCoordinator(Error, true); fail("We expect a RPCException since one node could not execute the command"); } catch (RPCException e) { // OK } result = service.executeCommandOnAllNodes(LongTask, true); assertNotNull(result); assertTrue(result.size() == 1); assertNull(result.get(0)); Object o = service.executeCommandOnCoordinator(LongTask, true); assertNull(o); result = service.executeCommandOnAllNodes(LongTask, 1000); assertNotNull(result); assertTrue(result.size() == 1); assertTrue("We expect an RPCException due to a Replication Timeout", result.get(0) instanceof RPCException); try { service.executeCommandOnCoordinator(LongTask, 1000); fail("We expect an RPCException due to a Replication Timeout"); } catch (RPCException e) { // OK } result = service.executeCommandOnAllNodes(LongTask, false); assertNotNull(result); assertTrue(result.isEmpty()); assertNull(service.executeCommandOnCoordinator(LongTask, false)); result = service.executeCommandOnAllNodes(StringValue, true); assertNotNull(result); assertTrue(result.size() == 1); assertEquals("OK", result.get(0)); o = service.executeCommandOnCoordinator(StringValue, true); assertEquals("OK", o); result = service.executeCommandOnAllNodes(NullValue, true); assertNotNull(result); assertTrue(result.size() == 1); assertNull(result.get(0)); o = service.executeCommandOnCoordinator(NullValue, true); assertNull(o); } finally { if (service != null) { service.stop(); } } } public void testSeveralNodes() throws Exception { InitParams params = new InitParams(); ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); paramConf.setValue("jar:/conf/portal/udp.xml"); params.addParameter(paramConf); RPCServiceImpl service1 = null, service2 = null; try { service1 = new RPCServiceImpl(container.getContext(), params, configManager); service2 = new RPCServiceImpl(container.getContext(), params, configManager); RemoteCommand CmdUnknownOnNode2 = new RemoteCommand() { public String getId() { return "CmdUnknownOnNode2"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service1.registerCommand(CmdUnknownOnNode2); RemoteCommand ExceptionOnNode2 = new RemoteCommand() { public String getId() { return "ExceptionOnNode2"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service1.registerCommand(ExceptionOnNode2); RemoteCommand ErrorOnNode2 = new RemoteCommand() { public String getId() { return "ErrorOnNode2"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service1.registerCommand(ErrorOnNode2); RemoteCommand LongTaskOnNode2 = new RemoteCommand() { public String getId() { return "LongTaskOnNode2"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service1.registerCommand(LongTaskOnNode2); service1.registerCommand(new RemoteCommand() { public String getId() { return "LongTask"; } public String execute(Serializable[] args) throws Throwable { Thread.sleep(3000); return "OldCoordinator"; } }); service1.registerCommand(new RemoteCommand() { public String getId() { return "OK"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }); service2.registerCommand(new RemoteCommand() { public String getId() { return "ExceptionOnNode2"; } public String execute(Serializable[] args) throws Throwable { throw new Exception("MyException"); } }); service2.registerCommand(new RemoteCommand() { public String getId() { return "ErrorOnNode2"; } public String execute(Serializable[] args) throws Throwable { throw new Error("MyError"); } }); service2.registerCommand(new RemoteCommand() { public String getId() { return "LongTaskOnNode2"; } public String execute(Serializable[] args) throws Throwable { Thread.sleep(2000); return null; } }); RemoteCommand OK = new RemoteCommand() { public String getId() { return "OK"; } public String execute(Serializable[] args) throws Throwable { return "OK"; } }; service2.registerCommand(OK); final RemoteCommand LongTask = new RemoteCommand() { public String getId() { return "LongTask"; } public String execute(Serializable[] args) throws Throwable { return "NewCoordinator"; } }; service2.registerCommand(LongTask); MyListener listener1 = new MyListener(); service1.registerTopologyChangeListener(listener1); MyListener listener2 = new MyListener(); service2.registerTopologyChangeListener(listener2); assertFalse(listener1.coordinatorHasChanged); assertFalse(listener1.isCoordinator); assertEquals(0, listener1.count); assertFalse(listener2.coordinatorHasChanged); assertFalse(listener2.isCoordinator); assertEquals(0, listener2.count); service1.start(); assertFalse(listener1.coordinatorHasChanged); assertTrue(listener1.isCoordinator); assertEquals(1, listener1.count); assertFalse(listener2.coordinatorHasChanged); assertFalse(listener2.isCoordinator); assertEquals(0, listener2.count); service2.start(); assertFalse(listener1.coordinatorHasChanged); assertTrue(listener1.isCoordinator); assertEquals(2, listener1.count); assertFalse(listener2.coordinatorHasChanged); assertFalse(listener2.isCoordinator); assertEquals(1, listener2.count); assertEquals(true, service1.isCoordinator()); assertEquals(false, service2.isCoordinator()); List<Object> result; Object o; result = service1.executeCommandOnAllNodes(CmdUnknownOnNode2, true); assertTrue(result != null && result.size() == 2); assertEquals("OK", result.get(0)); assertTrue("We expect a RPCException since the command is unknown on node 2", result.get(1) instanceof RPCException); o = service1.executeCommandOnCoordinator(CmdUnknownOnNode2, true); assertEquals("OK", o); result = service1.executeCommandOnAllNodes(ExceptionOnNode2, true); assertTrue(result != null && result.size() == 2); assertEquals("OK", result.get(0)); assertTrue("We expect a RPCException since the command fails on node 2", result.get(1) instanceof RPCException); o = service1.executeCommandOnCoordinator(ExceptionOnNode2, true); assertEquals("OK", o); result = service1.executeCommandOnAllNodes(ErrorOnNode2, true); assertTrue(result != null && result.size() == 2); assertEquals("OK", result.get(0)); assertTrue("We expect a RPCException since the command fails on node 2", result.get(1) instanceof RPCException); o = service1.executeCommandOnCoordinator(ErrorOnNode2, true); assertEquals("OK", o); result = service1.executeCommandOnAllNodes(LongTaskOnNode2, 1000); assertNotNull(result); assertTrue(result.size() == 2); assertEquals("OK", result.get(0)); assertTrue("We expect an RPCException due to a Replication Timeout", result.get(1) instanceof RPCException); o = service1.executeCommandOnCoordinator(LongTaskOnNode2, 1000); assertEquals("OK", o); List<Address> allMembers = service1.members; List<Address> coordinatorOnly = new ArrayList<Address>(1); coordinatorOnly.add(service1.coordinator); final RPCServiceImpl service = service2; final AtomicReference<Throwable> error = new AtomicReference<Throwable>(); final CountDownLatch doneSignal = new CountDownLatch(1); Thread t = new Thread() { @Override public void run() { try { Object o = service.executeCommandOnCoordinator(LongTask, true); assertEquals("NewCoordinator", o); } catch (Throwable e) { error.set(e); e.printStackTrace(); } finally { doneSignal.countDown(); } } }; t.start(); service1.stop(); listener2.waitTopologyChange(); assertFalse(listener1.coordinatorHasChanged); assertTrue(listener1.isCoordinator); assertEquals(2, listener1.count); assertTrue(listener2.coordinatorHasChanged); assertTrue(listener2.isCoordinator); assertEquals(2, listener2.count); doneSignal.await(); assertNull(error.get() != null ? error.get().getMessage() : "", error.get()); result = service2.excecuteCommand(allMembers, OK, true, 0); assertNotNull(result); assertTrue(result.size() == 2); assertTrue("We expect an RPCException due to a member that has left", result.get(0) instanceof MemberHasLeftException); assertEquals("OK", result.get(1)); result = service2.excecuteCommand(coordinatorOnly, OK, true, 0); assertNotNull(result); assertTrue(result.size() == 1); assertTrue("We expect an RPCException due to a member that has left", result.get(0) instanceof MemberHasLeftException); try { service1.isCoordinator(); fail("We expect a RPCException since the current state is not the expected one"); } catch (RPCException e) { // OK } assertEquals(true, service2.isCoordinator()); } finally { if (service1 != null) { service1.stop(); } if (service2 != null) { service2.stop(); } } } public void testSingleMethodCallCommand() throws Exception { try { new SingleMethodCallCommand(null, null); fail("we expect an IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK } MyService myService = new MyService(); try { new SingleMethodCallCommand(myService, null); fail("we expect an IllegalArgumentException"); } catch (IllegalArgumentException e) { // OK } try { new SingleMethodCallCommand(myService, "foo"); fail("we expect an NoSuchMethodException"); } catch (NoSuchMethodException e) { // OK } try { new SingleMethodCallCommand(myService, "getPrivateName"); fail("we expect an IllegalArgumentException since only the public methods are allowed"); } catch (IllegalArgumentException e) { // OK } InitParams params = new InitParams(); ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); paramConf.setValue("jar:/conf/portal/udp.xml"); params.addParameter(paramConf); RPCServiceImpl service = null; try { service = new RPCServiceImpl(container.getContext(), params, configManager); RemoteCommand getName = service.registerCommand(new SingleMethodCallCommand(myService, "getName")); RemoteCommand add = service.registerCommand(new SingleMethodCallCommand(myService, "add", int.class)); RemoteCommand evaluate1 = service.registerCommand(new SingleMethodCallCommand(myService, "evaluate", int[].class)); RemoteCommand evaluate2 = service.registerCommand(new SingleMethodCallCommand(myService, "evaluate", List.class)); RemoteCommand total1 = service.registerCommand(new SingleMethodCallCommand(myService, "total", int.class)); RemoteCommand total2 = service.registerCommand(new SingleMethodCallCommand(myService, "total", int.class, int.class)); RemoteCommand total3 = service.registerCommand(new SingleMethodCallCommand(myService, "total", int[].class)); RemoteCommand total4 = service.registerCommand(new SingleMethodCallCommand(myService, "total", String.class, long.class, int[].class)); RemoteCommand testTypes1 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", String[].class)); RemoteCommand testTypes2 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", int[].class)); RemoteCommand testTypes3 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", long[].class)); RemoteCommand testTypes4 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", byte[].class)); RemoteCommand testTypes5 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", short[].class)); RemoteCommand testTypes6 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", char[].class)); RemoteCommand testTypes7 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", double[].class)); RemoteCommand testTypes8 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", float[].class)); RemoteCommand testTypes9 = service.registerCommand(new SingleMethodCallCommand(myService, "testTypes", boolean[].class)); service.start(); List<Object> result; assertEquals("name", service.executeCommandOnCoordinator(getName, true)); result = service.executeCommandOnAllNodes(getName, true); assertTrue(result != null && result.size() == 1); assertEquals("name", result.get(0)); assertEquals(10, service.executeCommandOnCoordinator(add, true, 10)); result = service.executeCommandOnAllNodes(add, true, 10); assertTrue(result != null && result.size() == 1); assertEquals(20, result.get(0)); assertEquals(100, service.executeCommandOnCoordinator(evaluate1, true, new int[]{10, 10, 10, 30, 40})); result = service.executeCommandOnAllNodes(evaluate1, true, new int[]{10, 10, 10, 30, 40}); assertTrue(result != null && result.size() == 1); assertEquals(100, result.get(0)); List<Integer> values = new ArrayList<Integer>(); values.add(10); values.add(10); values.add(10); values.add(30); values.add(40); assertEquals(100, service.executeCommandOnCoordinator(evaluate2, true, (Serializable)values)); result = service.executeCommandOnAllNodes(evaluate2, true, (Serializable)values); assertTrue(result != null && result.size() == 1); assertEquals(100, result.get(0)); assertEquals(10, service.executeCommandOnCoordinator(total1, true, 10)); result = service.executeCommandOnAllNodes(total1, true, 10); assertTrue(result != null && result.size() == 1); assertEquals(10, result.get(0)); assertEquals(20, service.executeCommandOnCoordinator(total2, true, 10, 10)); result = service.executeCommandOnAllNodes(total2, true, 10, 10); assertTrue(result != null && result.size() == 1); assertEquals(20, result.get(0)); assertEquals(100, service.executeCommandOnCoordinator(total3, true, new int[]{10, 10, 10, 30, 40})); result = service.executeCommandOnAllNodes(total3, true, new int[]{10, 10, 10, 30, 40}); assertTrue(result != null && result.size() == 1); assertEquals(100, result.get(0)); assertEquals(100, service.executeCommandOnCoordinator(total4, true, "foo", 50, new int[]{10, 10, 10, 30, 40})); result = service.executeCommandOnAllNodes(total4, true, "foo", 50, new int[]{10, 10, 10, 30, 40}); assertTrue(result != null && result.size() == 1); assertEquals(100, result.get(0)); assertEquals(0, service.executeCommandOnCoordinator(total4, true, "foo", 50, null)); result = service.executeCommandOnAllNodes(total4, true, "foo", 50, null); assertTrue(result != null && result.size() == 1); assertEquals(0, result.get(0)); try { service.executeCommandOnCoordinator(total4, true, "foo", 50); fail("We expect a RPCException since the list of arguments mismatch with what is expected"); } catch (RPCException e) { // OK } result = service.executeCommandOnAllNodes(total4, true, "foo", 50); assertTrue(result != null && result.size() == 1); assertTrue("We expect a RPCException since the list of arguments mismatch with what is expected", result.get(0) instanceof RPCException); assertEquals("foo", service.executeCommandOnCoordinator(testTypes1, true, (Serializable)new String[]{"foo"})); result = service.executeCommandOnAllNodes(testTypes1, true, (Serializable)new String[]{"foo"}); assertTrue(result != null && result.size() == 1); assertEquals("foo", result.get(0)); assertEquals(10, service.executeCommandOnCoordinator(testTypes2, true, new int[]{10})); result = service.executeCommandOnAllNodes(testTypes2, true, new int[]{10}); assertTrue(result != null && result.size() == 1); assertEquals(10, result.get(0)); assertEquals(11L, service.executeCommandOnCoordinator(testTypes3, true, new long[]{10})); result = service.executeCommandOnAllNodes(testTypes3, true, new long[]{10}); assertTrue(result != null && result.size() == 1); assertEquals(11L, result.get(0)); assertEquals((byte)12, service.executeCommandOnCoordinator(testTypes4, true, new byte[]{10})); result = service.executeCommandOnAllNodes(testTypes4, true, new byte[]{10}); assertTrue(result != null && result.size() == 1); assertEquals((byte)12, result.get(0)); assertEquals((short)13, service.executeCommandOnCoordinator(testTypes5, true, new short[]{10})); result = service.executeCommandOnAllNodes(testTypes5, true, new short[]{10}); assertTrue(result != null && result.size() == 1); assertEquals((short)13, result.get(0)); assertEquals('a', service.executeCommandOnCoordinator(testTypes6, true, new char[]{'a'})); result = service.executeCommandOnAllNodes(testTypes6, true, new char[]{'a'}); assertTrue(result != null && result.size() == 1); assertEquals('a', result.get(0)); assertEquals(10.5, service.executeCommandOnCoordinator(testTypes7, true, new double[]{10})); result = service.executeCommandOnAllNodes(testTypes7, true, new double[]{10}); assertTrue(result != null && result.size() == 1); assertEquals(10.5, result.get(0)); assertEquals((float)11.5, service.executeCommandOnCoordinator(testTypes8, true, new float[]{10})); result = service.executeCommandOnAllNodes(testTypes8, true, new float[]{10}); assertTrue(result != null && result.size() == 1); assertEquals((float)11.5, result.get(0)); assertEquals(true, service.executeCommandOnCoordinator(testTypes9, true, new boolean[]{true})); result = service.executeCommandOnAllNodes(testTypes9, true, new boolean[]{true}); assertTrue(result != null && result.size() == 1); assertEquals(true, result.get(0)); } finally { if (service != null) { service.stop(); } } } public static class MyService { private int value = 0; public int add(int i) { return value += i; } @SuppressWarnings("unused") private String getPrivateName() { return "name"; } public String getName() { return "name"; } public int total(int i) { return i; } public int total(int i1, int i2) { return i1 + i2; } public int total(int... values) { int total = 0; for (int i : values) { total += i; } return total; } public int total(String s, long l, int... values) { int total = 0; if (values != null) { for (int i : values) { total += i; } } return total; } public int evaluate(int[] values) { int total = 0; for (int i : values) { total += i; } return total; } public int evaluate(List<Integer> values) { int total = 0; for (int i : values) { total += i; } return total; } public String testTypes(String... values) { return values[0]; } public boolean testTypes(boolean... values) { return values[0]; } public char testTypes(char... values) { return values[0]; } public double testTypes(double... values) { return values[0] + 0.5; } public float testTypes(float... values) { return (float)(values[0] + 1.5); } public int testTypes(int... values) { return values[0]; } public long testTypes(long... values) { return values[0] + 1; } public byte testTypes(byte... values) { return (byte)(values[0] + 2); } public short testTypes(short... values) { return (short)(values[0] + 3); } } public void testExecOnCoordinator() throws Exception { InitParams params = new InitParams(); ValueParam paramConf = new ValueParam(); paramConf.setName(RPCServiceImpl.PARAM_JGROUPS_CONFIG); paramConf.setValue("jar:/conf/portal/udp.xml"); params.addParameter(paramConf); final List<Boolean> calledCommands = Collections.synchronizedList(new ArrayList<Boolean>()); RPCServiceImpl service1 = null; RPCServiceImpl service2 = null; try { service1 = new RPCServiceImpl(container.getContext(), params, configManager); RemoteCommand service1Cmd = new RemoteCommand() { public String getId() { return "CoordinatorExecutedCommand"; } public String execute(Serializable[] args) throws Throwable { calledCommands.add(Boolean.TRUE); return "service 1"; } }; service1.registerCommand(service1Cmd); service2 = new RPCServiceImpl(container.getContext(), params, configManager); RemoteCommand service2Cmd = new RemoteCommand() { public String getId() { return "CoordinatorExecutedCommand"; } public String execute(Serializable[] args) throws Throwable { calledCommands.add(Boolean.TRUE); return "service 2"; } }; service2.registerCommand(service2Cmd); // starting services service1.start(); service2.start(); Object o = service1.executeCommandOnCoordinator(service1Cmd, true); assertEquals("service 1", o); // it should be executed once assertEquals(1, calledCommands.size()); } finally { if (service1 != null) { service1.stop(); } if (service2 != null) { service2.stop(); } } } private static class MyListener implements TopologyChangeListener { private boolean coordinatorHasChanged; private boolean isCoordinator; private int count; private CountDownLatch lock = new CountDownLatch(2); /** * @see org.exoplatform.services.rpc.TopologyChangeListener#onChange(org.exoplatform.services.rpc.TopologyChangeEvent) */ public void onChange(TopologyChangeEvent event) { this.coordinatorHasChanged = event.isCoordinatorHasChanged(); this.isCoordinator = event.isCoordinator(); count++; lock.countDown(); } public void waitTopologyChange() throws InterruptedException { lock.await(); } } }