Search in sources :

Example 6 with ClientConsumer

use of org.apache.activemq.artemis.api.core.client.ClientConsumer in project activemq-artemis by apache.

the class ActiveMQSession method createConsumer.

private ActiveMQMessageConsumer createConsumer(final ActiveMQDestination dest, final String subscriptionName, String selectorString, final boolean noLocal, ConsumerDurability durability) throws JMSException {
    try {
        selectorString = "".equals(selectorString) ? null : selectorString;
        if (noLocal) {
            connection.setHasNoLocal();
            String filter;
            if (connection.getClientID() != null) {
                filter = ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString() + "<>'" + connection.getClientID() + "'";
            } else {
                filter = ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString() + "<>'" + connection.getUID() + "'";
            }
            if (selectorString != null) {
                selectorString += " AND " + filter;
            } else {
                selectorString = filter;
            }
        }
        SimpleString coreFilterString = null;
        if (selectorString != null) {
            coreFilterString = new SimpleString(SelectorTranslator.convertToActiveMQFilterString(selectorString));
        }
        ClientConsumer consumer;
        SimpleString autoDeleteQueueName = null;
        if (dest.isQueue()) {
            AddressQuery response = session.addressQuery(dest.getSimpleAddress());
            /* The address query will send back exists=true even if the node only has a REMOTE binding for the destination.
             * Therefore, we must check if the queue names list contains the exact name of the address to know whether or
             * not a LOCAL binding for the address exists. If no LOCAL binding exists then it should be created here.
             */
            if (!response.isExists() || !response.getQueueNames().contains(dest.getSimpleAddress())) {
                if (response.isAutoCreateQueues()) {
                    try {
                        createQueue(dest, RoutingType.ANYCAST, dest.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                    } catch (ActiveMQQueueExistsException e) {
                    // The queue was created by another client/admin between the query check and send create queue packet
                    }
                } else {
                    throw new InvalidDestinationException("Destination " + dest.getName() + " does not exist");
                }
            }
            connection.addKnownDestination(dest.getSimpleAddress());
            consumer = session.createConsumer(dest.getSimpleAddress(), coreFilterString, false);
        } else {
            AddressQuery response = session.addressQuery(dest.getSimpleAddress());
            if (!response.isExists()) {
                if (response.isAutoCreateAddresses()) {
                    session.createAddress(dest.getSimpleAddress(), RoutingType.MULTICAST, true);
                } else {
                    throw new InvalidDestinationException("Topic " + dest.getName() + " does not exist");
                }
            }
            connection.addKnownDestination(dest.getSimpleAddress());
            SimpleString queueName;
            if (subscriptionName == null) {
                if (durability != ConsumerDurability.NON_DURABLE)
                    throw new RuntimeException("Subscription name cannot be null for durable topic consumer");
                // Non durable sub
                queueName = new SimpleString(UUID.randomUUID().toString());
                createTemporaryQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                consumer = session.createConsumer(queueName, null, false);
                autoDeleteQueueName = queueName;
            } else {
                // Durable sub
                if (durability != ConsumerDurability.DURABLE)
                    throw new RuntimeException("Subscription name must be null for non-durable topic consumer");
                if (connection.getClientID() == null) {
                    throw new IllegalStateException("Cannot create durable subscription - client ID has not been set");
                }
                if (dest.isTemporary()) {
                    throw new InvalidDestinationException("Cannot create a durable subscription on a temporary topic");
                }
                queueName = ActiveMQDestination.createQueueNameForSubscription(true, connection.getClientID(), subscriptionName);
                QueueQuery subResponse = session.queueQuery(queueName);
                if (!subResponse.isExists()) {
                    // durable subscription queues are not technically considered to be auto-created
                    createQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                } else {
                    // Already exists
                    if (subResponse.getConsumerCount() > 0) {
                        throw new IllegalStateException("Cannot create a subscriber on the durable subscription since it already has subscriber(s)");
                    }
                    // From javax.jms.Session Javadoc (and also JMS 1.1 6.11.1):
                    // A client can change an existing durable subscription by
                    // creating a durable TopicSubscriber with the same name and
                    // a new topic and/or message selector.
                    // Changing a durable subscriber is equivalent to unsubscribing
                    // (deleting) the old one and creating a new one.
                    SimpleString oldFilterString = subResponse.getFilterString();
                    boolean selectorChanged = coreFilterString == null && oldFilterString != null || oldFilterString == null && coreFilterString != null || oldFilterString != null && coreFilterString != null && !oldFilterString.equals(coreFilterString);
                    SimpleString oldTopicName = subResponse.getAddress();
                    boolean topicChanged = !oldTopicName.equals(dest.getSimpleAddress());
                    if (selectorChanged || topicChanged) {
                        // Delete the old durable sub
                        session.deleteQueue(queueName);
                        // Create the new one
                        createQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                    }
                }
                consumer = session.createConsumer(queueName, null, false);
            }
        }
        ActiveMQMessageConsumer jbc = new ActiveMQMessageConsumer(options, connection, this, consumer, noLocal, dest, selectorString, autoDeleteQueueName);
        consumers.add(jbc);
        return jbc;
    } catch (ActiveMQException e) {
        throw JMSExceptionHelper.convertFromActiveMQException(e);
    }
}
Also used : IllegalStateException(javax.jms.IllegalStateException) AddressQuery(org.apache.activemq.artemis.api.core.client.ClientSession.AddressQuery) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQQueueExistsException(org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) InvalidDestinationException(javax.jms.InvalidDestinationException) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) QueueQuery(org.apache.activemq.artemis.api.core.client.ClientSession.QueueQuery)

Example 7 with ClientConsumer

use of org.apache.activemq.artemis.api.core.client.ClientConsumer in project activemq-artemis by apache.

the class ConsumerWindowSizeTest method testMultipleImmediate.

@Test
public void testMultipleImmediate() throws Exception {
    final int NUMBER_OF_MESSAGES = 200;
    ActiveMQServer server = createServer(false, isNetty());
    server.start();
    locator.setConsumerWindowSize(0);
    final ClientSessionFactory sf = createSessionFactory(locator);
    {
        ClientSession session = sf.createSession(false, false, false);
        session.createQueue("testWindow", "testWindow", true);
        session.close();
    }
    Thread[] threads = new Thread[10];
    final AtomicInteger errors = new AtomicInteger(0);
    final CountDownLatch latchStart = new CountDownLatch(1);
    final AtomicInteger received = new AtomicInteger(0);
    for (int i = 0; i < threads.length; i++) {
        threads[i] = new Thread() {

            @Override
            public void run() {
                try {
                    ClientSession session = sf.createSession(false, false);
                    ClientConsumer consumer = session.createConsumer("testWindow");
                    session.start();
                    latchStart.await(10, TimeUnit.SECONDS);
                    while (true) {
                        ClientMessage msg = consumer.receiveImmediate();
                        if (msg == null) {
                            break;
                        }
                        msg.acknowledge();
                        session.commit();
                        received.incrementAndGet();
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                    errors.incrementAndGet();
                }
            }
        };
        threads[i].start();
    }
    ClientSession senderSession = sf.createSession(false, false);
    ClientProducer producer = senderSession.createProducer("testWindow");
    ClientMessage sent = senderSession.createMessage(true);
    sent.putStringProperty("hello", "world");
    for (int i = 0; i < NUMBER_OF_MESSAGES; i++) {
        producer.send(sent);
        senderSession.commit();
    }
    latchStart.countDown();
    for (Thread t : threads) {
        t.join();
    }
    Assert.assertEquals(0, errors.get());
    Assert.assertEquals(NUMBER_OF_MESSAGES, received.get());
}
Also used : ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) CountDownLatch(java.util.concurrent.CountDownLatch) ActiveMQServer(org.apache.activemq.artemis.core.server.ActiveMQServer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) Test(org.junit.Test)

Example 8 with ClientConsumer

use of org.apache.activemq.artemis.api.core.client.ClientConsumer in project activemq-artemis by apache.

the class ConsumerWindowSizeTest method internalTestSlowConsumerNoBuffer.

private void internalTestSlowConsumerNoBuffer(final boolean largeMessages) throws Exception {
    ActiveMQServer server = createServer(false, isNetty());
    ClientSession sessionB = null;
    ClientSession session = null;
    try {
        final int numberOfMessages = 100;
        server.start();
        locator.setConsumerWindowSize(0);
        if (largeMessages) {
            locator.setMinLargeMessageSize(100);
        }
        ClientSessionFactory sf = createSessionFactory(locator);
        session = sf.createSession(false, true, true);
        SimpleString ADDRESS = addressA;
        session.createQueue(ADDRESS, ADDRESS, true);
        sessionB = sf.createSession(false, true, true);
        sessionB.start();
        session.start();
        ClientConsumerInternal consNeverUsed = (ClientConsumerInternal) sessionB.createConsumer(ADDRESS);
        ClientProducer prod = session.createProducer(ADDRESS);
        // This will force a credit to be sent, but if the message wasn't received we need to take out that credit from
        // the server
        // or the client will be buffering messages
        Assert.assertNull(consNeverUsed.receive(1));
        ClientMessage msg = createTextMessage(session, "This one will expire");
        if (largeMessages) {
            msg.getBodyBuffer().writeBytes(new byte[600]);
        }
        msg.setExpiration(System.currentTimeMillis() + 100);
        prod.send(msg);
        msg = createTextMessage(session, "First-on-non-buffered");
        prod.send(msg);
        Thread.sleep(110);
        // It will be able to receive another message, but it shouldn't send a credit again, as the credit was already
        // sent
        msg = consNeverUsed.receive(TIMEOUT * 1000);
        Assert.assertNotNull(msg);
        Assert.assertEquals("First-on-non-buffered", getTextMessage(msg));
        msg.acknowledge();
        ClientConsumer cons1 = session.createConsumer(ADDRESS);
        for (int i = 0; i < numberOfMessages; i++) {
            msg = createTextMessage(session, "Msg" + i);
            if (largeMessages) {
                msg.getBodyBuffer().writeBytes(new byte[600]);
            }
            prod.send(msg);
        }
        for (int i = 0; i < numberOfMessages; i++) {
            msg = cons1.receive(1000);
            Assert.assertNotNull("expected message at i = " + i, msg);
            Assert.assertEquals("Msg" + i, getTextMessage(msg));
            msg.acknowledge();
        }
        Assert.assertEquals(0, consNeverUsed.getBufferSize());
        session.close();
        session = null;
        sessionB.close();
        sessionB = null;
        Assert.assertEquals(0, getMessageCount(server, ADDRESS.toString()));
    } finally {
        try {
            if (session != null) {
                session.close();
            }
            if (sessionB != null) {
                sessionB.close();
            }
        } catch (Exception ignored) {
        }
    }
}
Also used : ActiveMQServer(org.apache.activemq.artemis.core.server.ActiveMQServer) ClientConsumerInternal(org.apache.activemq.artemis.core.client.impl.ClientConsumerInternal) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) IOException(java.io.IOException)

Example 9 with ClientConsumer

use of org.apache.activemq.artemis.api.core.client.ClientConsumer in project activemq-artemis by apache.

the class ConsumerWindowSizeTest method testSendWindowSize.

/*
   * tests send window size. we do this by having 2 receivers on the q. since we roundrobin the consumer for delivery we
   * know if consumer 1 has received n messages then consumer 2 must have also have received n messages or at least up
   * to its window size
   * */
@Test
public void testSendWindowSize() throws Exception {
    ActiveMQServer messagingService = createServer(false, isNetty());
    locator.setBlockOnNonDurableSend(false);
    messagingService.start();
    int numMessage = 100;
    locator.setConsumerWindowSize(numMessage * getMessageEncodeSize(addressA));
    ClientSessionFactory cf = createSessionFactory(locator);
    ClientSession sendSession = cf.createSession(false, true, true);
    ClientSession receiveSession = cf.createSession(false, true, true);
    sendSession.createQueue(addressA, queueA, false);
    ClientConsumer receivingConsumer = receiveSession.createConsumer(queueA);
    ClientSession session = cf.createSession(false, true, true);
    ClientProducer cp = sendSession.createProducer(addressA);
    ClientConsumer cc = session.createConsumer(queueA);
    session.start();
    receiveSession.start();
    for (int i = 0; i < numMessage * 4; i++) {
        cp.send(sendSession.createMessage(false));
    }
    for (int i = 0; i < numMessage * 2; i++) {
        ClientMessage m = receivingConsumer.receive(5000);
        Assert.assertNotNull(m);
        m.acknowledge();
    }
    receiveSession.close();
    for (int i = 0; i < numMessage * 2; i++) {
        ClientMessage m = cc.receive(5000);
        Assert.assertNotNull(m);
        m.acknowledge();
    }
    session.close();
    sendSession.close();
    Assert.assertEquals(0, getMessageCount(messagingService, queueA.toString()));
}
Also used : ActiveMQServer(org.apache.activemq.artemis.core.server.ActiveMQServer) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) Test(org.junit.Test)

Example 10 with ClientConsumer

use of org.apache.activemq.artemis.api.core.client.ClientConsumer in project activemq-artemis by apache.

the class ConsumerWindowSizeTest method testReceiveImmediateWithZeroWindow3.

// https://jira.jboss.org/jira/browse/HORNETQ-385
@Test
public void testReceiveImmediateWithZeroWindow3() throws Exception {
    ActiveMQServer server = createServer(false, isNetty());
    server.start();
    locator.setConsumerWindowSize(0);
    ClientSessionFactory sf = createSessionFactory(locator);
    ClientSession session = sf.createSession(false, false, false);
    session.createQueue("testWindow", "testWindow", true);
    session.close();
    int numConsumers = 5;
    ArrayList<ClientConsumer> consumers = new ArrayList<>();
    ArrayList<ClientSession> sessions = new ArrayList<>();
    for (int i = 0; i < numConsumers; i++) {
        ClientSession session1 = sf.createSession();
        ClientConsumer consumer = session1.createConsumer("testWindow");
        consumers.add(consumer);
        session1.start();
        sessions.add(session1);
        consumer.receive(10);
    }
    ClientSession senderSession = sf.createSession(false, false);
    ClientProducer producer = senderSession.createProducer("testWindow");
    ClientMessage sent = senderSession.createMessage(true);
    sent.putStringProperty("hello", "world");
    producer.send(sent);
    senderSession.commit();
    senderSession.start();
    ClientConsumer consumer = consumers.get(2);
    ClientMessage received = consumer.receive(1000);
    Assert.assertNotNull(received);
    for (ClientSession tmpSess : sessions) {
        tmpSess.close();
    }
    senderSession.close();
}
Also used : ActiveMQServer(org.apache.activemq.artemis.core.server.ActiveMQServer) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) ArrayList(java.util.ArrayList) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) ClientConsumer(org.apache.activemq.artemis.api.core.client.ClientConsumer) ClientProducer(org.apache.activemq.artemis.api.core.client.ClientProducer) Test(org.junit.Test)

Aggregations

ClientConsumer (org.apache.activemq.artemis.api.core.client.ClientConsumer)720 ClientProducer (org.apache.activemq.artemis.api.core.client.ClientProducer)642 ClientMessage (org.apache.activemq.artemis.api.core.client.ClientMessage)624 Test (org.junit.Test)584 ClientSession (org.apache.activemq.artemis.api.core.client.ClientSession)569 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)409 ClientSessionFactory (org.apache.activemq.artemis.api.core.client.ClientSessionFactory)348 ServerLocator (org.apache.activemq.artemis.api.core.client.ServerLocator)154 ActiveMQServer (org.apache.activemq.artemis.core.server.ActiveMQServer)132 AddressSettings (org.apache.activemq.artemis.core.settings.impl.AddressSettings)88 Configuration (org.apache.activemq.artemis.core.config.Configuration)81 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)79 CountDownLatch (java.util.concurrent.CountDownLatch)72 Queue (org.apache.activemq.artemis.core.server.Queue)63 DivertConfiguration (org.apache.activemq.artemis.core.config.DivertConfiguration)62 Xid (javax.transaction.xa.Xid)55 StoreConfiguration (org.apache.activemq.artemis.core.config.StoreConfiguration)52 HashMap (java.util.HashMap)48 DatabaseStorageConfiguration (org.apache.activemq.artemis.core.config.storage.DatabaseStorageConfiguration)46 ArrayList (java.util.ArrayList)44