Search in sources :

Example 1 with Consumer

use of org.apache.activemq.artemis.core.server.Consumer in project activemq-artemis by apache.

the class QueueControlImpl method listConsumersAsJSON.

@Override
public String listConsumersAsJSON() throws Exception {
    checkStarted();
    clearIO();
    try {
        Collection<Consumer> consumers = queue.getConsumers();
        JsonArrayBuilder jsonArray = JsonLoader.createArrayBuilder();
        for (Consumer consumer : consumers) {
            if (consumer instanceof ServerConsumer) {
                ServerConsumer serverConsumer = (ServerConsumer) consumer;
                JsonObjectBuilder obj = JsonLoader.createObjectBuilder().add("consumerID", serverConsumer.getID()).add("connectionID", serverConsumer.getConnectionID().toString()).add("sessionID", serverConsumer.getSessionID()).add("browseOnly", serverConsumer.isBrowseOnly()).add("creationTime", serverConsumer.getCreationTime());
                jsonArray.add(obj);
            }
        }
        return jsonArray.build().toString();
    } finally {
        blockOnIO();
    }
}
Also used : ServerConsumer(org.apache.activemq.artemis.core.server.ServerConsumer) Consumer(org.apache.activemq.artemis.core.server.Consumer) JsonArrayBuilder(javax.json.JsonArrayBuilder) ServerConsumer(org.apache.activemq.artemis.core.server.ServerConsumer) JsonObjectBuilder(javax.json.JsonObjectBuilder)

Example 2 with Consumer

use of org.apache.activemq.artemis.core.server.Consumer in project activemq-artemis by apache.

the class ConsumerWindowSizeTest method testNoWindowRoundRobin.

private void testNoWindowRoundRobin(final boolean largeMessages) throws Exception {
    ActiveMQServer server = createServer(false, isNetty());
    ClientSession sessionA = null;
    ClientSession sessionB = null;
    try {
        final int numberOfMessages = 100;
        server.start();
        locator.setConsumerWindowSize(-1);
        if (largeMessages) {
            locator.setMinLargeMessageSize(100);
        }
        ClientSessionFactory sf = createSessionFactory(locator);
        sessionA = sf.createSession(false, true, true);
        SimpleString ADDRESS = new SimpleString("some-queue");
        sessionA.createQueue(ADDRESS, ADDRESS, true);
        sessionB = sf.createSession(false, true, true);
        sessionA.start();
        sessionB.start();
        ClientConsumerInternal consA = (ClientConsumerInternal) sessionA.createConsumer(ADDRESS);
        ClientConsumerInternal consB = (ClientConsumerInternal) sessionB.createConsumer(ADDRESS);
        {
            // We can only guarantee round robing with WindowSize = -1, after the ServerConsumer object received
            // SessionConsumerFlowCreditMessage(-1)
            // Since that is done asynchronously we verify that the information was received before we proceed on
            // sending messages or else the distribution won't be
            // even as expected by the test
            Bindings bindings = server.getPostOffice().getBindingsForAddress(ADDRESS);
            Assert.assertEquals(1, bindings.getBindings().size());
            for (Binding binding : bindings.getBindings()) {
                Collection<Consumer> consumers = ((QueueBinding) binding).getQueue().getConsumers();
                for (Consumer consumer : consumers) {
                    ServerConsumerImpl consumerImpl = (ServerConsumerImpl) consumer;
                    long timeout = System.currentTimeMillis() + 5000;
                    while (timeout > System.currentTimeMillis() && consumerImpl.getAvailableCredits() != null) {
                        Thread.sleep(10);
                    }
                    Assert.assertNull(consumerImpl.getAvailableCredits());
                }
            }
        }
        ClientProducer prod = sessionA.createProducer(ADDRESS);
        for (int i = 0; i < numberOfMessages; i++) {
            ClientMessage msg = createTextMessage(sessionA, "Msg" + i);
            if (largeMessages) {
                msg.getBodyBuffer().writeBytes(new byte[600]);
            }
            prod.send(msg);
        }
        long timeout = System.currentTimeMillis() + TIMEOUT * 1000;
        boolean foundA = false;
        boolean foundB = false;
        do {
            foundA = consA.getBufferSize() == numberOfMessages / 2;
            foundB = consB.getBufferSize() == numberOfMessages / 2;
            Thread.sleep(10);
        } while ((!foundA || !foundB) && System.currentTimeMillis() < timeout);
        Assert.assertTrue("ConsumerA didn't receive the expected number of messages on buffer (consA=" + consA.getBufferSize() + ", consB=" + consB.getBufferSize() + ") foundA = " + foundA + " foundB = " + foundB, foundA);
        Assert.assertTrue("ConsumerB didn't receive the expected number of messages on buffer (consA=" + consA.getBufferSize() + ", consB=" + consB.getBufferSize() + ") foundA = " + foundA + " foundB = " + foundB, foundB);
    } finally {
        try {
            if (sessionA != null) {
                sessionA.close();
            }
            if (sessionB != null) {
                sessionB.close();
            }
        } catch (Exception ignored) {
        }
    }
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) QueueBinding(org.apache.activemq.artemis.core.postoffice.QueueBinding) ClientConsumerInternal(org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal) QueueBinding(org.apache.activemq.artemis.core.postoffice.QueueBinding) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) Bindings(org.apache.activemq.artemis.core.postoffice.Bindings) IOException(java.io.IOException) ServerConsumerImpl(org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl) ActiveMQServer(org.apache.activemq.artemis.core.server.ActiveMQServer) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) Consumer(org.apache.activemq.artemis.core.server.Consumer) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) Collection(java.util.Collection) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer)

Example 3 with Consumer

use of org.apache.activemq.artemis.core.server.Consumer in project activemq-artemis by apache.

the class QueueImpl method deliver.

/**
 * This method will deliver as many messages as possible until all consumers are busy or there
 * are no more matching or available messages.
 */
private void deliver() {
    if (logger.isDebugEnabled()) {
        logger.debug(this + " doing deliver. messageReferences=" + messageReferences.size());
    }
    doInternalPoll();
    // Either the iterator is empty or the consumer is busy
    int noDelivery = 0;
    int size = 0;
    int endPos = -1;
    int handled = 0;
    long timeout = System.currentTimeMillis() + DELIVERY_TIMEOUT;
    while (true) {
        if (handled == MAX_DELIVERIES_IN_LOOP) {
            // Schedule another one - we do this to prevent a single thread getting caught up in this loop for too
            // long
            deliverAsync();
            return;
        }
        if (System.currentTimeMillis() > timeout) {
            if (logger.isTraceEnabled()) {
                logger.trace("delivery has been running for too long. Scheduling another delivery task now");
            }
            deliverAsync();
            return;
        }
        MessageReference ref;
        Consumer handledconsumer = null;
        synchronized (this) {
            // Need to do these checks inside the synchronized
            if (paused || consumerList.isEmpty()) {
                return;
            }
            if (messageReferences.size() == 0) {
                break;
            }
            if (endPos < 0 || consumersChanged) {
                consumersChanged = false;
                size = consumerList.size();
                endPos = pos - 1;
                if (endPos < 0) {
                    endPos = size - 1;
                    noDelivery = 0;
                }
            }
            ConsumerHolder holder = consumerList.get(pos);
            Consumer consumer = holder.consumer;
            Consumer groupConsumer = null;
            if (holder.iter == null) {
                holder.iter = messageReferences.iterator();
            }
            if (holder.iter.hasNext()) {
                ref = holder.iter.next();
            } else {
                ref = null;
            }
            if (ref == null) {
                noDelivery++;
            } else {
                if (checkExpired(ref)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Reference " + ref + " being expired");
                    }
                    holder.iter.remove();
                    refRemoved(ref);
                    handled++;
                    continue;
                }
                if (logger.isTraceEnabled()) {
                    logger.trace("Queue " + this.getName() + " is delivering reference " + ref);
                }
                // If a group id is set, then this overrides the consumer chosen round-robin
                SimpleString groupID = extractGroupID(ref);
                if (groupID != null) {
                    groupConsumer = groups.get(groupID);
                    if (groupConsumer != null) {
                        consumer = groupConsumer;
                    }
                }
                if (exclusive) {
                    consumer = consumerList.get(0).consumer;
                }
                HandleStatus status = handle(ref, consumer);
                if (status == HandleStatus.HANDLED) {
                    deliveriesInTransit.countUp();
                    handledconsumer = consumer;
                    holder.iter.remove();
                    refRemoved(ref);
                    if (groupID != null && groupConsumer == null) {
                        groups.put(groupID, consumer);
                    }
                    handled++;
                } else if (status == HandleStatus.BUSY) {
                    try {
                        holder.iter.repeat();
                    } catch (NoSuchElementException e) {
                        // this could happen if there was an exception on the queue handling
                        // and it returned BUSY because of that exception
                        // 
                        // We will just log it as there's nothing else we can do now.
                        logger.warn(e.getMessage(), e);
                    }
                    noDelivery++;
                } else if (status == HandleStatus.NO_MATCH) {
                // nothing to be done on this case, the iterators will just jump next
                }
            }
            if (pos == endPos) {
                if (noDelivery == size) {
                    if (handledconsumer != null) {
                        // this shouldn't really happen,
                        // however I'm keeping this as an assertion case future developers ever change the logic here on this class
                        ActiveMQServerLogger.LOGGER.nonDeliveryHandled();
                    } else {
                        if (logger.isDebugEnabled()) {
                            logger.debug(this + "::All the consumers were busy, giving up now");
                        }
                        break;
                    }
                }
                noDelivery = 0;
            }
            // When using group we don't need to load balance to the next position
            if (!exclusive && groupConsumer == null) {
                pos++;
            }
            if (pos >= size) {
                pos = 0;
            }
        }
        if (handledconsumer != null) {
            proceedDeliver(handledconsumer, ref);
        }
    }
    checkDepage();
}
Also used : Consumer(org.apache.activemq.artemis.core.server.Consumer) HandleStatus(org.apache.activemq.artemis.core.server.HandleStatus) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) NoSuchElementException(java.util.NoSuchElementException)

Example 4 with Consumer

use of org.apache.activemq.artemis.core.server.Consumer in project activemq-artemis by apache.

the class QueueImpl method deliverDirect.

/*
    * This method delivers the reference on the callers thread - this can give us better latency in the case there is nothing in the queue
    */
private boolean deliverDirect(final MessageReference ref) {
    synchronized (this) {
        if (!supportsDirectDeliver) {
            // this would protect any eventual bug
            return false;
        }
        if (paused || consumerList.isEmpty()) {
            return false;
        }
        if (checkExpired(ref)) {
            return true;
        }
        int startPos = pos;
        int size = consumerList.size();
        while (true) {
            ConsumerHolder holder = consumerList.get(pos);
            Consumer consumer = holder.consumer;
            Consumer groupConsumer = null;
            // If a group id is set, then this overrides the consumer chosen round-robin
            SimpleString groupID = extractGroupID(ref);
            if (groupID != null) {
                groupConsumer = groups.get(groupID);
                if (groupConsumer != null) {
                    consumer = groupConsumer;
                }
            }
            if (exclusive) {
                consumer = consumerList.get(0).consumer;
            }
            // Only move onto the next position if the consumer on the current position was used.
            if (!exclusive && groupConsumer == null) {
                pos++;
            }
            if (pos == size) {
                pos = 0;
            }
            HandleStatus status = handle(ref, consumer);
            if (status == HandleStatus.HANDLED) {
                if (groupID != null && groupConsumer == null) {
                    groups.put(groupID, consumer);
                }
                messagesAdded.incrementAndGet();
                deliveriesInTransit.countUp();
                proceedDeliver(consumer, ref);
                return true;
            }
            if (pos == startPos) {
                // Tried them all
                break;
            }
        }
        return false;
    }
}
Also used : Consumer(org.apache.activemq.artemis.core.server.Consumer) HandleStatus(org.apache.activemq.artemis.core.server.HandleStatus) SimpleString(org.apache.activemq.artemis.api.core.SimpleString)

Example 5 with Consumer

use of org.apache.activemq.artemis.core.server.Consumer in project activemq-artemis by apache.

the class ActiveMQServerControlImpl method closeConsumerConnectionsForAddress.

@Override
public boolean closeConsumerConnectionsForAddress(final String address) {
    boolean closed = false;
    checkStarted();
    clearIO();
    try {
        for (Binding binding : postOffice.getMatchingBindings(SimpleString.toSimpleString(address)).getBindings()) {
            if (binding instanceof LocalQueueBinding) {
                Queue queue = ((LocalQueueBinding) binding).getQueue();
                for (Consumer consumer : queue.getConsumers()) {
                    if (consumer instanceof ServerConsumer) {
                        ServerConsumer serverConsumer = (ServerConsumer) consumer;
                        RemotingConnection connection = null;
                        for (RemotingConnection potentialConnection : remotingService.getConnections()) {
                            if (potentialConnection.getID().toString().equals(serverConsumer.getConnectionID())) {
                                connection = potentialConnection;
                            }
                        }
                        if (connection != null) {
                            remotingService.removeConnection(connection.getID());
                            connection.fail(ActiveMQMessageBundle.BUNDLE.consumerConnectionsClosedByManagement(address));
                            closed = true;
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        ActiveMQServerLogger.LOGGER.failedToCloseConsumerConnectionsForAddress(address, e);
    } finally {
        blockOnIO();
    }
    return closed;
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) LocalQueueBinding(org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding) Consumer(org.apache.activemq.artemis.core.server.Consumer) ServerConsumer(org.apache.activemq.artemis.core.server.ServerConsumer) RemotingConnection(org.apache.activemq.artemis.spi.core.protocol.RemotingConnection) ServerConsumer(org.apache.activemq.artemis.core.server.ServerConsumer) Queue(org.apache.activemq.artemis.core.server.Queue) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ListenerNotFoundException(javax.management.ListenerNotFoundException) ActiveMQAddressDoesNotExistException(org.apache.activemq.artemis.api.core.ActiveMQAddressDoesNotExistException)

Aggregations

Consumer (org.apache.activemq.artemis.core.server.Consumer)8 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)4 Binding (org.apache.activemq.artemis.core.postoffice.Binding)2 HandleStatus (org.apache.activemq.artemis.core.server.HandleStatus)2 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)2 ServerConsumer (org.apache.activemq.artemis.core.server.ServerConsumer)2 QueueImpl (org.apache.activemq.artemis.core.server.impl.QueueImpl)2 FakeConsumer (org.apache.activemq.artemis.tests.unit.core.server.impl.fakes.FakeConsumer)2 Test (org.junit.Test)2 IOException (java.io.IOException)1 Collection (java.util.Collection)1 NoSuchElementException (java.util.NoSuchElementException)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 JsonArrayBuilder (javax.json.JsonArrayBuilder)1 JsonObjectBuilder (javax.json.JsonObjectBuilder)1 ListenerNotFoundException (javax.management.ListenerNotFoundException)1 ActiveMQAddressDoesNotExistException (org.apache.activemq.artemis.api.core.ActiveMQAddressDoesNotExistException)1 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)1 ClientConsumer (org.apache.activemq.artemis.api.core.client.ClientConsumer)1 ClientMessage (org.apache.activemq.artemis.api.core.client.ClientMessage)1