I read the hornetQ documentation, confused a lot. Can someone give an exact example to create a JMS topic in hornetQ. I mean the xml configurations in hornetq-jms.xml and hornetq-configuration.xml. assume we have a topic named top and 2 subscribers named: sub1, sub2. what I get is that we should define two queues(one for each subscribers) and bind them to an address which is the topic name actually, but how the subscriber would know they should connect to which one?(They only know the topic name)
I think you are confused by the way HornetQ handles topics internaly in contrast to the way the JMS specification describes topics.
Let's start with the JMS specification. Here you have one topic, where n subscribers can listen to the messages, that will be published by a client. In JMS we talk only about the destination in singular, eg. we'll send a message to the topic, or the queue respectively.
HornetQ is a JMS Provider - a server that implements the JMS specification, so Java-clients can connect to it, and use the JMS-API. The JMS Provider might change, but the code should still work when using another JMS provider.
However, HornetQ does not distinguish internally the destinations (topic or queue), since it tries to be a generic messaging middleware. In HornetQ all topics or queues are implemented as "addresses" and "queues". When you use the HornetQ API (CoreAPI) instead of the JMS-API, you have to deal with such things. You should read the Address section in the HornetQ documentation:
In core, there is no concept of a Topic, Topic is a JMS only term.
Instead, in core, we just deal with addresses and queues.
For example, a JMS topic would be implemented by a single address to
which many queues are bound. Each queue represents a subscription of
the topic. A JMS Queue would be implemented as a single address to
which one queue is bound - that queue represents the JMS queue.
For an example how to use a topic with JMS via HornetQ, I stongly recommend the examples that come with HornetQ itself. After donwloading and extracting the hornetq archive, just go to the examples/jms/topic directory and see the readme.html for a brief overview how to implement and how to execute the example (mvn verify).
Related
I'm using ActiveMQ Artemis messaging system, and I'm testing my setup with STOMP (stomp.py).
I created an "address" on Artemis called Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic, and attached two queues to it:
Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue (multicast)
Site.SOF.Order.Fulfillment.Submission.ActiveOmni.log.queue (multicast)
Here are the exported bindings:
<bindings>
<address-binding routing-types="ANYCAST" name="DLQ" id="2"/>
<address-binding routing-types="ANYCAST" name="ExpiryQueue" id="6"/>
<address-binding routing-types="MULTICAST" name="activemq.notifications" id="10"/>
<address-binding routing-types="MULTICAST" name="Site.SOF.Order.Fulfillment.Submission.Topic" id="92"/>
<queue-binding address="Site.SOF.Order.Fulfillment.Submission.Topic" filter-string="" name="Site.SOF.Order.Fulfillment.Submission.log.Queue" id="97" routing-type="MULTICAST"/>
<queue-binding address="DLQ" filter-string="" name="DLQ" id="4" routing-type="ANYCAST"/>
<queue-binding address="ExpiryQueue" filter-string="" name="ExpiryQueue" id="8" routing-type="ANYCAST"/>
<queue-binding address="Site.SOF.Order.Fulfillment.Submission.Topic" filter-string="" name="Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Queue" id="94" routing-type="MULTICAST"/>
</bindings>
I created a user with access to Site.*
So how do I access the queues? For example, if I use the stomp.py command line tool like so:
> subscribe Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue
I get the error:
[username] does not have permission='CREATE_ADDRESS' on address Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue
So I try adding /queue/ to the front, as I've seen in the tutorials
> subscribe /queue/Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue
But I get the same error:
[username] does not have permission='CREATE_ADDRESS' on address /queue/Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue
I can send to the topic/address without trouble. The following results in a "hello" message appearing in both queues.
send Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic "hello"
Is this a naming convention I'm missing? Or a way to specify topic vs queue? What am I missing here that's too obvious to be clearly documented?
Let me provide some background information first...
The ActiveMQ Artemis address model includes 3 main elements - addresses, queues, and routing types. These are low-level entities which are used to implement all the different semantics for all the different protocols and configurations the broker supports.
STOMP, by contrast, just supports ambiguous "destinations." The STOMP 1.2 specification says this about destinations:
A STOMP server is modelled as a set of destinations to which messages can be sent. The STOMP protocol treats destinations as opaque string and their syntax is server implementation specific. Additionally STOMP does not define what the delivery semantics of destinations should be. The delivery, or “message exchange”, semantics of destinations can vary from server to server and even from destination to destination. This allows servers to be creative with the semantics that they can support with STOMP.
In the core address model messages are sent to addresses and consumed from queues. Addresses and queues are named independently so the names that the core producer and consumer use can be different.
ActiveMQ Artemis supports both point-to-point and pub/sub semantics for STOMP destinations. You can read more about how to configure these semantics in the latest ActiveMQ Artemis STOMP documentation.
In the STOMP point-to-point use-case a message is sent to a destination and consumed from that same destination. The name that both the STOMP producer and consumer use are the same. In order to support these semantics the broker uses a core address and a core anycast queue with the same name.
In the STOMP pub/sub use-case a client creates a subscription on a destination which it can then use to receive messages sent to that destination. The name that both the STOMP subscriber and producer use are the same. In order to support these semantics the broker uses a core address and a core multicast queue with different names. The name of the core queue is generated by the broker automatically. The subscriber can then receive the messages directly from the underlying core subscription queue.
All this stuff is done behind the scenes for STOMP clients, but it's important to understand how STOMP maps to ActiveMQ Artemis' address model so you can configure things appropriately
In your case you've configured an address with 2 multicast queues and you're trying to consume from those queues. This use-case is a mix between point-to-point and pub/sub because you have statically defined queues (i.e. not queues auto-created by the broker in response to a subscriber) but the queues are multicast. These queues are like statically configured durable subscriptions. To access the queues directly you need to use their fully-qualified queue name (i.e. FQQN) from your client. The FQQN follows the pattern of <address>::<queue> so in your case you'd use either
Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic::Site.SOF.Order.Fulfillment.Submission.ActiveOmni.queue
or
Site.SOF.Order.Fulfillment.Submission.ActiveOmni.Topic::Site.SOF.Order.Fulfillment.Submission.ActiveOmni.log.queue
Is there a way to implement a topology with ActiveMQ, where P is a publisher, s_a is a subscriber of service A and s_b1 and s_b2 are subscribers of service B. The latter are set in a cluster for load balancing (so s_b1 or s_b2 gets a message but not both).
Is there a way to combine publish-subscribe with a peer-to-peer messaging so one of the subscribers would be a queue which two consumers are listening on?
Thanks,
Gil
Yes this can be done.
You may want to look at Apache ActiveMQ Artemis which implements JMS 2.0 and support what you ask for out of the box. JMS 2.0 allows multiple subscribers per topic to load balance a cluster.
For ActiveMQ and JMS 1.0 you can use Virtual Destinations instead. They work with naming conventions.
If you name your topic: VirtualTopic.StockPrice and publish messages to it, you will be able to consume from queues named Consumer.Consumer1.VirtualTopic.StockPrice, Consumer.Consumer2.VirtualTopic.StockPrice etc. Consumer1 can be anything.
You can reconfigure ActiveMQ to use other names for Virtual Destinations (prefix, suffix etc).
I am trying to understand JMS.
What is the difference between ActiveMQ and JMS
can pool the data from NON ActiveMQ with ActiveMQ plugin in Spring?
Thanks ,In advance
JMS is a specification. JMS has three main parts to it. The first is the producer, which is nothing more than a bean that submits a "message" to a JMS broker (#2) (the system that manages messages between producers and consumers). In this case, ActiveMQ is the broker. Once the broker receives a message, the consumer (#3), or Message-Driven Bean (MDB), processes the message.
If you want to work with JMS, you'll just write both your producer/consumer code using the JMS API, but behind the scenes there is a "resource adapter" that is a special ActiveMQ driver that will connect to an ActiveMQ instance and do the management for you.
Have a look at this post I made recently. I'm still trying to figure out the best way to write JMS beans, but I've got the basics down.
The accepted answer emphasizes what is the structure of JMS is. Not disagreeing just want to add to it in case anyone else wants to know. ActiveMQ could be a JMS supplier. A JMS supplier shapes the computer program system for encouraging the utilize of JMS concepts interior an application. A single node of ActiveMQ which permits clients to associate to it and utilize these informing concepts is called an "ActiveMQ Broker."
Enterprises feel this disparity with business actions such as mergers and acquisitions. This creates the need to maintain an increasingly heterogeneous collection of business applications. As your enterprise grows, so does the need to allow all of these platforms to share data. A number of architectural patterns exist today which help to solve this problem.
Some other examples of JMS providers are:
HornetQ.
RabbitMQ.
SonicMQ.
Winsows Azure Messaging
The following example shows a simple configuration of an ActiveMQ connection:
<jms:config name="JMS_Config">
<jms:active-mq-connection >
<jms:factory-configuration brokerUrl="tcp://localhost:61616" />
</jms:active-mq-connection>
</jms:config>
This post explains a detailed difference between the ActiveMQ and JMS (or maybe about the details of their specifications). Hope it clears your concepts.
In websphere app server 6.1, when i want to set up JMS, I need to set up a topic, and i need to set up queues and then in MQ explorer I create a subscription between the topic and the queues. Now this configuration is for a publish /subscribe model. If something is published to the topic, all queues will pick up the message.
So how do we do point to point messaging in websphere? I ask this question because I thought topic is for publish subscribe model. And queue is for point to point messaging. But in WAS, the two are mixed up.
The two aren't mixed up. There's no contradiction here, really.
The publish/subscribe model uses a topic (to which "things" are published), and a set of queues that are set to consume that topic.
The point-to-point model uses a queue; the "producing" application puts messages in the queue, and the "consuming" application gets messages from that queue.
Therefore, there's no contradiction. Remember, topics and queues are just "tools" to implement publish/subscribe or point-to-point topologies.
In other queue managers it is possible to setup a bridge between a queue to a topic so that publishers and subscribers does not need to know that they are using a topic:
Example in TIBCO EMS
create Bridge source=queue:QName
target=topic:TName
create Bridge
source=topic:TName target=queue:QName
How do I do this in WMQ?
See WebSphere MQ V7.0 Features and Enhancements page 47, it mentions the use of Alias queues and administrative subscriptions
WebSphere MQ V7.0 introduces an
extension to the alias queue object
that allows it to be resolved to the
new topic object. This is useful for
migrating point-to-point messaging
applications to the Publish/Subscribe
model. A traditional point-to-point
application that puts messages into
WebSphere MQ can operate as a
publisher without any code changes by
utilizing an alias queue that resolves
to a topic object. This is implemented
administratively by defining a topic
object that maps to an appropriate
topic string on which the messages are
to be published. The original local
queue is deleted and replaced by an
alias queue of the same name that
resolves to the topic object. Also
note that a point-to-point application
that gets messages from WebSphere MQ
can operate as a subscriber without
any code changes by defining an
administrative subscription to a
topic.
Example 9.3 on page 220 shows how to setup a administrative subscription from a Topic to a destination queue
DEFINE SUB(SUB.RETAIL.CAT) TOPICOBJ(MATT.RETAIL.CAT) DESTCLAS(MANAGED)
DEFINE SUB(SUB.MATTRETCAT) TOPICSTR(‘matt/retail/cat’) DESTCLAS(MANAGED)
DEFINE SUB(SUB.PROVCAT) TOPICSTR(‘matt/retail/cat’) DEST(SUB.PROVCAT.DESTQ)