use of org.exoplatform.services.rpc.impl.AbstractRPCService.MemberHasLeftException in project kernel by exoplatform.
the class TestRPCServiceImpl method testSeveralNodes.
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();
}
}
}
Aggregations