amqpactivemq-artemisjboss-amq

AMQPNETLITE - ActiveMQ Artemis (Red Hat AMQ) - autocreate multi-consumer multicast queue


This qeuestion is on consuming the messages using AMQP in .Net. The documentation recommends amqpnetlite: https://access.redhat.com/documentation/en-us/red_hat_amq/7.0/html-single/using_the_amq_.net_client/index

On subscribing to an address using AMQPNetLite, the address and the queue will be auto-created. The auto-created queue is always "unicast" though. I have not been able to auto-create

  1. a multicast queue
  2. that allowed any number of consumers.

Code:

private async Task RenewSession()
{
    Connect = await Connection.Factory.CreateAsync(new Address("amqp://admin:admin@localhost:5672"), new Open() {ContainerId = "client-1"});
    MqSession = new Session(Connect);
    var receiver = new ReceiverLink(MqSession, DEFAULT_SUBSCRIPTION_NAME, GetSource("test-topic"), null);
    receiver.Start(100, OnMessage);
}

private Source GetSource(string address)
{
    var source = new Source
    {
        Address = address,
        ExpiryPolicy = new Symbol("never"),
        Durable = 2,
        DefaultOutcome = new Modified
        {
            DeliveryFailed = true,
            UndeliverableHere = false
        }
    };
    return source;
}

Maybe I am missing some flags?


Solution

  • in AMQP, you choose between autocreating a queue (anycast routing) or a topic (multicast routing) by setting a capability.

    The capability should be either new Symbol("queue") or new Symbol("topic").

    public class SimpleAmqpTest
    {
        [Fact]
        public async Task TestHelloWorld()
        {
            Address address = new Address("amqp://guest:guest@localhost:5672");
            Connection connection = await Connection.Factory.CreateAsync(address);
            Session session = new Session(connection);
    
            Message message = new Message("Hello AMQP");
    
            Target target = new Target
            {
                Address = "q1",
                Capabilities = new Symbol[] { new Symbol("queue") }
            };
    
            SenderLink sender = new SenderLink(session, "sender-link", target, null);
            await sender.SendAsync(message);
    
            Source source = new Source
            {
                Address = "q1",
                Capabilities = new Symbol[] { new Symbol("queue") }
            };
    
            ReceiverLink receiver = new ReceiverLink(session, "receiver-link", source, null);
            message = await receiver.ReceiveAsync();
            receiver.Accept(message);
    
            await sender.CloseAsync();
            await receiver.CloseAsync();
            await session.CloseAsync();
            await connection.CloseAsync();
        }
    }
    

    Have a look at https://github.com/Azure/amqpnetlite/issues/286, where the code comes from.

    You can choose whether the default routing will be multicast or anycast by setting default-address-routing-type in broker.xml, everything documented at https://activemq.apache.org/artemis/docs/2.6.0/address-model.html

    The broker's multicastPrefix and anycastPrefix feature is not implemented for AMQP. https://issues.jboss.org/browse/ENTMQBR-795