use of org.apache.activemq.artemis.core.server.group.impl.Response in project activemq-artemis by apache.
the class ClusteredGroupingTest method testTimeoutOnSending.
@Test
public void testTimeoutOnSending() throws Exception {
setupServer(0, isFileStorage(), isNetty());
setupServer(1, isFileStorage(), isNetty());
setupServer(2, isFileStorage(), isNetty());
setupClusterConnection("cluster0", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 0, 1, 2);
setupClusterConnection("cluster1", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 1, 0, 2);
setupClusterConnection("cluster2", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 2, 0, 1);
setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 1, 0);
setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 2, 0);
final CountDownLatch latch = new CountDownLatch(BindingsImpl.MAX_GROUP_RETRY);
setUpGroupHandler(new GroupingHandler() {
@Override
public void awaitBindings() throws Exception {
}
@Override
public void addListener(UnproposalListener listener) {
}
@Override
public void resendPending() throws Exception {
}
@Override
public void remove(SimpleString groupid, SimpleString clusterName) throws Exception {
}
@Override
public void forceRemove(SimpleString groupid, SimpleString clusterName) throws Exception {
}
@Override
public SimpleString getName() {
return null;
}
@Override
public void remove(SimpleString id, SimpleString groupId, int distance) {
// To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void start() throws Exception {
// To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void stop() throws Exception {
// To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isStarted() {
return false;
}
@Override
public Response propose(final Proposal proposal) throws Exception {
return null;
}
@Override
public void proposed(final Response response) throws Exception {
System.out.println("ClusteredGroupingTest.proposed");
}
@Override
public void sendProposalResponse(final Response response, final int distance) throws Exception {
System.out.println("ClusteredGroupingTest.send");
}
@Override
public Response receive(final Proposal proposal, final int distance) throws Exception {
latch.countDown();
return null;
}
@Override
public void onNotification(final Notification notification) {
System.out.println("ClusteredGroupingTest.onNotification " + notification);
}
@Override
public void addGroupBinding(final GroupBinding groupBinding) {
System.out.println("ClusteredGroupingTest.addGroupBinding");
}
@Override
public Response getProposal(final SimpleString fullID, boolean touchTime) {
return null;
}
}, 0);
startServers(0, 1, 2);
setupSessionFactory(0, isNetty());
setupSessionFactory(1, isNetty());
setupSessionFactory(2, isNetty());
createQueue(0, "queues.testaddress", "queue0", null, false);
createQueue(1, "queues.testaddress", "queue0", null, false);
createQueue(2, "queues.testaddress", "queue0", null, false);
addConsumer(0, 0, "queue0", null);
addConsumer(1, 1, "queue0", null);
addConsumer(2, 2, "queue0", null);
waitForBindings(0, "queues.testaddress", 1, 1, true);
waitForBindings(1, "queues.testaddress", 1, 1, true);
waitForBindings(2, "queues.testaddress", 1, 1, true);
waitForBindings(0, "queues.testaddress", 2, 2, false);
waitForBindings(1, "queues.testaddress", 2, 2, false);
waitForBindings(2, "queues.testaddress", 2, 2, false);
try {
sendWithProperty(1, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, new SimpleString("id1"));
// it should get the Retries on the latch
assertTrue(latch.await(10, TimeUnit.SECONDS));
} catch (Exception e) {
// To change body of catch statement use File | Settings | File Templates.
e.printStackTrace();
}
}
use of org.apache.activemq.artemis.core.server.group.impl.Response in project activemq-artemis by apache.
the class BindingsImpl method routeUsingStrictOrdering.
private void routeUsingStrictOrdering(final Message message, final RoutingContext context, final GroupingHandler groupingGroupingHandler, final SimpleString groupId, final int tries) throws Exception {
for (Map.Entry<SimpleString, List<Binding>> entry : routingNameBindingMap.entrySet()) {
SimpleString routingName = entry.getKey();
List<Binding> bindings = entry.getValue();
if (bindings == null) {
// ConcurrentHashMap behaviour!
continue;
}
// concat a full group id, this is for when a binding has multiple bindings
// NOTE: In case a dev ever change this rule, QueueImpl::unproposed is using this rule to determine if
// the binding belongs to its Queue before removing it
SimpleString fullID = groupId.concat(".").concat(routingName);
// see if there is already a response
Response resp = groupingGroupingHandler.getProposal(fullID, true);
if (resp == null) {
// ok let's find the next binding to propose
Binding theBinding = getNextBinding(message, routingName, bindings);
if (theBinding == null) {
continue;
}
resp = groupingGroupingHandler.propose(new Proposal(fullID, theBinding.getClusterName()));
if (resp == null) {
logger.debug("it got a timeout on propose, trying again, number of retries: " + tries);
// it timed out, so we will check it through routeAndcheckNull
theBinding = null;
}
// if our proposal was declined find the correct binding to use
if (resp != null && resp.getAlternativeClusterName() != null) {
theBinding = locateBinding(resp.getAlternativeClusterName(), bindings);
}
routeAndCheckNull(message, context, resp, theBinding, groupId, tries);
} else {
// ok, we need to find the binding and route it
Binding chosen = locateBinding(resp.getChosenClusterName(), bindings);
routeAndCheckNull(message, context, resp, chosen, groupId, tries);
}
}
}
use of org.apache.activemq.artemis.core.server.group.impl.Response in project activemq-artemis by apache.
the class ClusteredGroupingTest method testGroupingSimpleFail2nd.
// Fail a node where there's a consumer only.. with messages being sent by a node that is not the local
@Test
public void testGroupingSimpleFail2nd() throws Exception {
setupServer(0, isFileStorage(), isNetty());
setupServer(1, isFileStorage(), isNetty());
setupServer(2, isFileStorage(), isNetty());
setupClusterConnection("cluster0", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 0, 1, 2);
setupClusterConnection("cluster1", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 1, 0, 2);
setupClusterConnection("cluster2", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 2, 0, 1);
final int TIMEOUT_GROUPS = 5000;
setUpGroupHandler(GroupingHandlerConfiguration.TYPE.LOCAL, 0, TIMEOUT_GROUPS, -1, -1);
setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 1, TIMEOUT_GROUPS, -1, -1);
setUpGroupHandler(GroupingHandlerConfiguration.TYPE.REMOTE, 2, TIMEOUT_GROUPS, -1, -1);
startServers(0, 1, 2);
setupSessionFactory(0, isNetty());
setupSessionFactory(1, isNetty());
setupSessionFactory(2, isNetty());
createQueue(0, "queues.testaddress", "queue0", null, true);
createQueue(1, "queues.testaddress", "queue0", null, true);
createQueue(2, "queues.testaddress", "queue0", null, true);
addConsumer(0, 0, "queue0", null);
addConsumer(1, 1, "queue0", null);
addConsumer(2, 2, "queue0", null);
waitForBindings(0, "queues.testaddress", 1, 1, true);
waitForBindings(1, "queues.testaddress", 1, 1, true);
waitForBindings(2, "queues.testaddress", 1, 1, true);
waitForBindings(0, "queues.testaddress", 2, 2, false);
waitForBindings(1, "queues.testaddress", 2, 2, false);
waitForBindings(2, "queues.testaddress", 2, 2, false);
sendWithProperty(0, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, new SimpleString("id1"));
sendWithProperty(0, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, new SimpleString("id2"));
sendWithProperty(0, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, new SimpleString("id3"));
// It should receive one message on each server
ClientMessage msg = consumers[0].getConsumer().receive(1000);
assertNotNull(msg);
msg.acknowledge();
assertNull(consumers[0].getConsumer().receiveImmediate());
msg = consumers[1].getConsumer().receive(1000);
assertNotNull(msg);
msg.acknowledge();
SimpleString groupIDOnConsumer1 = msg.getSimpleStringProperty(Message.HDR_GROUP_ID);
assertNull(consumers[1].getConsumer().receiveImmediate());
msg = consumers[2].getConsumer().receive(1000);
assertNotNull(msg);
msg.acknowledge();
assertNull(consumers[2].getConsumer().receiveImmediate());
// it should be bound to server1 as we used the group from server1
sendWithProperty(2, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, groupIDOnConsumer1);
msg = consumers[1].getConsumer().receive(1000);
assertNotNull(msg);
msg.acknowledge();
closeAllConsumers();
closeAllSessionFactories();
SimpleString node1ID = servers[1].getNodeID();
// Validating if it's the right server
Response response = servers[0].getGroupingHandler().getProposal(groupIDOnConsumer1.concat(".").concat("queue0"), false);
assertTrue(response.getClusterName().toString().equals("queue0" + node1ID));
stopServers(0, 1, 2);
long time = System.currentTimeMillis();
startServers(2, 0);
assertTrue("The group start should have waited the timeout on groups", System.currentTimeMillis() >= time + TIMEOUT_GROUPS);
setupSessionFactory(0, isNetty());
setupSessionFactory(2, isNetty());
addConsumer(0, 0, "queue0", null);
addConsumer(2, 2, "queue0", null);
waitForBindings(0, "queues.testaddress", 1, 1, false);
waitForBindings(2, "queues.testaddress", 1, 1, false);
sendWithProperty(2, "queues.testaddress", 1, false, Message.HDR_GROUP_ID, groupIDOnConsumer1);
// server1 is dead, so either 0 or 2 should receive since the group is now dead
msg = consumers[0].getConsumer().receive(500);
if (msg == null) {
msg = consumers[2].getConsumer().receive(500);
}
response = servers[0].getGroupingHandler().getProposal(groupIDOnConsumer1.concat(".").concat("queue0"), false);
assertFalse("group should have been reassigned since server is not up yet", response.getClusterName().toString().equals("queue0" + node1ID));
assertNotNull(msg);
msg.acknowledge();
}
Aggregations