Search in sources :

Example 1 with Response

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();
    }
}
Also used : Response(org.apache.activemq.artemis.core.server.group.impl.Response) UnproposalListener(org.apache.activemq.artemis.core.server.group.UnproposalListener) GroupBinding(org.apache.activemq.artemis.core.server.group.impl.GroupBinding) GroupingHandler(org.apache.activemq.artemis.core.server.group.GroupingHandler) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) CountDownLatch(java.util.concurrent.CountDownLatch) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) Proposal(org.apache.activemq.artemis.core.server.group.impl.Proposal) Notification(org.apache.activemq.artemis.core.server.management.Notification) Test(org.junit.Test)

Example 2 with Response

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);
        }
    }
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding) Response(org.apache.activemq.artemis.core.server.group.impl.Response) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ArrayList(java.util.ArrayList) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Proposal(org.apache.activemq.artemis.core.server.group.impl.Proposal)

Example 3 with Response

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();
}
Also used : Response(org.apache.activemq.artemis.core.server.group.impl.Response) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) Test(org.junit.Test)

Aggregations

SimpleString (org.apache.activemq.artemis.api.core.SimpleString)3 Response (org.apache.activemq.artemis.core.server.group.impl.Response)3 Proposal (org.apache.activemq.artemis.core.server.group.impl.Proposal)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)1 ClientMessage (org.apache.activemq.artemis.api.core.client.ClientMessage)1 Binding (org.apache.activemq.artemis.core.postoffice.Binding)1 RemoteQueueBinding (org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding)1 GroupingHandler (org.apache.activemq.artemis.core.server.group.GroupingHandler)1 UnproposalListener (org.apache.activemq.artemis.core.server.group.UnproposalListener)1 GroupBinding (org.apache.activemq.artemis.core.server.group.impl.GroupBinding)1 Notification (org.apache.activemq.artemis.core.server.management.Notification)1