Closed thorstenhirsch closed 8 months ago
This is likely controlled via either connection properties, link properties, or a combination of both. Either way, it's specific to Artemis as these are not governed by the AMQP 1.0 spec. I did some searching through the Artemis codebase but didn't find anything obvious.
One thing you can try is to use a tool like Wireshark (it knows how to decode AMQP frames) to inspect the traffic when creating a queue with the JMS client to see what connection and/or link properties are sent from the client.
Found it in the Artemis code:
public static final byte QUEUE_TYPE = 0x00;
public static final byte TOPIC_TYPE = 0x01;
public static final byte TEMP_QUEUE_TYPE = 0x02;
public static final byte TEMP_TOPIC_TYPE = 0x03;
...and...
routingType = getMessageAnnotation(AMQPMessageSupport.JMS_DEST_TYPE_MSG_ANNOTATION);
if (routingType != null) {
if (AMQPMessageSupport.QUEUE_TYPE == ((Number) routingType).byteValue() || AMQPMessageSupport.TEMP_QUEUE_TYPE == ((Number) routingType).byteValue()) {
return RoutingType.ANYCAST;
} else if (AMQPMessageSupport.TOPIC_TYPE == ((Number) routingType).byteValue() || AMQPMessageSupport.TEMP_TOPIC_TYPE == ((Number) routingType).byteValue()) {
return RoutingType.MULTICAST;
}
}
...and...
public static final Symbol JMS_DEST_TYPE_MSG_ANNOTATION = getSymbol("x-opt-jms-dest");
...and when looking at the message structure it turns out, that these annotations are go-amqp's DeliveryAnnotations. Guess now I have everything I need regarding ANYCAST/MULTICAST. 😀
I keep this issue open, because I still need to find a solution for the random id in ContainerID.Name
.
Did you look through the Artemis codebase to see how they determine the queue name?
Well, I've found this in the Artemis docs:
By default any receiving link that attaches to an address that has only
multicast
enabled will be treated as a subscription and a corresponding subscription queue will be created. If the Terminus Durability is eitherUNSETTLED_STATE
orCONFIGURATION
then the queue will be made durable (similar to a JMS durable subscription) and given a name made up from the container id and the link name, something likemy-container-id:my-link-name
.
I'm interested in these durable subscription queues. From my tests I would conclude the queue name (in go-amqp terms) is ContainerID.Name(ReciverOptions)
. Actually I wonder why the link name is mentioned in the Artemis docs at this point, because we're only talking about the subscriber, which is the target node. But in the AMQP 1.0 specification in section 2.6.1 a link name is defined by the target AND THE SOURCE node:
A link’s name uniquely identifies the link from the container of the source to the container of the target node
So I'm not 100% sure, yet, but to me it looks like a qpid/proton receiver only sets the ContainerID
and leaves the Name(ReciverOptions)
empty while go-amqp sets either of them to a unique ID if it's empty. Thus with go-amqp it's currently not possible to give durable subscription queues a name without a .
and at least one character to the left and to the right of it.
Or did I miss something?
Per 2.7.3 the link's name is mandatory, so we cannot omit it.
What parameters are you passing to Session.NewReceiver()
?
receiverOptions := &amqp.ReceiverOptions{
Durability: amqp.DurabilityUnsettledState,
Name: "amcName",
SourceDurability: amqp.DurabilityUnsettledState,
TargetAddress: "queue1",
}
receiver, err := session.NewReceiver(ctx, "queue1", receiverOptions)
And if you create a receiver with the same configuration via JMS the name ends up being different on the Artemis side right? Have you tried using Wireshark to see how the frames differ?
Got it. I had to add SourceCapabilities to the receiverOptions:
receiverOptions := &amqp.ReceiverOptions{
SourceCapabilities: []string{"queue"},
}
This is how Artemis decides to create an anycast queue.
Trying to use go-amqp with Artemis the same way as amqp-10-jms-spring-boot uses Artemis. I have 2 problems with ad-hoc creation of queues I couldn't solve, yet:
routing-type=multicast
, while the JMS client creates queues withrouting-type=anycast
(unicast). How can I switch toanycast
... I don't this it's an applicationProperty, is it?ContainerID.Name
. The ContainerID is in the ConnOptions, the Name in the ReceiverOptions. Leaving either empty will result in a random unique string, so it doesn't seem possible to get a simple queue name w/o a dot in the middle like "queue1".So this an address+queue I'd like to create (same name, anycast):
And this is what go-amqp creates (ContainerID.Name, multicast):
Any chance to enhance go-amqp with the behaviour I'd like to have?