You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@activemq.apache.org by "Andrew Finnell (JIRA)" <ji...@apache.org> on 2016/10/28 21:23:58 UTC

[jira] [Comment Edited] (ARTEMIS-322) Implement Topic Auto-create

    [ https://issues.apache.org/jira/browse/ARTEMIS-322?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15616607#comment-15616607 ] 

Andrew Finnell edited comment on ARTEMIS-322 at 10/28/16 9:23 PM:
------------------------------------------------------------------

I appreciate the willingness to ensure this is a configurable option. I am curious what the reasonable Use Case is for _enforcing_ Topic's to be created at an Administrative level? Or a better question is, what is the Use Case for a product *failing* if a Topic has not been created via the Administrative Console? This very question had resulted in a lengthly debate back in the day when JBoss MQ was just getting started.

The specification states that the creation, deletion and management of Topic's are out of the JMS scope. The API and specification provides for a TemporaryTopic for 'reply scenarios', however, that topic can only be used by the TopicConnection which created it. Meaning any sort of TopicConnection pool becomes untenable. There were also issues with Selectors so that wasn't usable either. 

Then we had to deal with the Use Case of creating unique, per-client, durable queue's on an as-needed basis. For example, a client is launched which receives a live stream of events. That client is meant to be long running and always up to date. The idea would be to create a Durable Subscriber on a brand new Unique Queue which receives the events for that Client. The client could then specifiy any filtering criteria when registering for the events. Due to Client's having access to different sets of Events based on ACL's, or potentially being slightly off from one another it isn't possible to have a single _known_ queue ahead of time. And again, TempTopic's cannot be durable and are stuck to that TopicConnection. The client crashes, gets disconnected, or uses a connection pool and TempTopic's cannot be used. 

In today's age of Messaging systems all these problems aren't really issues anymore. Routes and Exchanges in AMQP solve so many problem. Modern JMS implementations do very well with JMSReplyTo, Selector's and allowing on-demand queue's/topic's to be created. 

I bring all this up because at the end of the day it literally took 3 lines of code to change JBoss MQ (which i did on my own fork of the code) to allow for the creation of dynamic queues. And the merge requests were denied as the specification didn't account for the administration of queues and topics. The bigger issue was that JBoss MQ was ALSO lacking any sort of reasonable API and CLI interface to administer the queues. So to make an application work a person had to log into the administrator console and add every single Topic and Queue along with any permissions, if needed, before the application would work.

Again, thank you for taking the time to take into consideration the idea that there are valid use cases for wanting to dynamically create topics and queues. Making it configurable provides the best of both. JBoss MQ (aka JBoss Messaging) was the ONLY Broker to enforce this restriction making it all the more incredulous. Now that we have a protocol AND specification of AMQP, that seems to be the way forward. It handles exponentially more scenarios then the JMS API. 

Thank you all for the work you do.


was (Author: andrew.finnell):
I appreciate the willingness to ensure this is a configurable option. I am curious what the reasonable Use Case is for _enforcing_ Topic's to be created at an Administrative level? Or a better question is, what is the Use Case for a product *failing* if a Topic has not been created via the Administrative Console? This very question had resulted in a lengthly debate back in the day when JBoss MQ was just getting started.

The specification states that the creation, deletion and management of Topic's are out of the JMS scope. The API and specification provides for a TemporaryTopic for 'replie scenarios', however, that topic can only be used by the TopicConnection which created it. Meaning any sort of TopicConnection pool becomes untenable. There were also issues with Selectors so that wasn't usable either. 

Then we had to deal with the Use Case of creating unique, per-client, durable queue's on an as-needed basis. For example, a client is launched which receives a live stream of events. That client is meant to be long running and always up to date. The idea would be to create a Durable Subscriber on a brand new Unique Queue which receives the events for that Client. The client could then specifiy any filtering criteria when registering for the events. Due to Client's having access to different sets of Events based on ACL's, or potentially being slightly off from one another it isn't possible to have a single _known_ queue ahead of time. And again, TempTopic's cannot be durable and are stuck to that TopicConnection. The client crashes, gets disconnected, or uses a connection pool and TempTopic's cannot be used. 

In today's age of Messaging systems all these problems aren't really issues anymore. Routes and Exchanges in AMQP solve so many problem. Modern JMS implementations do very well with JMSReplyTo, Selector's and allowing on-demand queue's/topic's to be created. 

I bring all this up because at the end of the day it literally took 3 lines of code to change JBoss MQ (which i did on my own fork of the code) to allow for the creation of dynamic queues. And the merge requests were denied as the specification didn't account for the administration of queues and topics. The bigger issue was that JBoss MQ was ALSO lacking any sort of reasonable API and CLI interface to administer the queues. So to make an application work a person had to log into the administrator console and add every single Topic and Queue along with any permissions, if needed, before the application would work.

Again, thank you for taking the time to take into consideration the idea that there are valid use cases for wanting to dynamically create topics and queues. Making it configurable provides the best of both. JBoss MQ (aka JBoss Messaging) was the ONLY Broker to enforce this restriction making it all the more incredulous. Now that we have a protocol AND specification of AMQP, that seems to be the way forward. It handles exponentially more scenarios then the JMS API. 

Thank you all for the work you do.

> Implement Topic Auto-create
> ---------------------------
>
>                 Key: ARTEMIS-322
>                 URL: https://issues.apache.org/jira/browse/ARTEMIS-322
>             Project: ActiveMQ Artemis
>          Issue Type: New Feature
>          Components: Broker
>    Affects Versions: 1.1.0
>         Environment: CentOS, Java 1.7, Eclipse, Artemis 1.1.0
>            Reporter: Roan
>            Assignee: Justin Bertram
>              Labels: newbie
>             Fix For: 1.3.0
>
>
> I was running a Topic example, as listed bellow.
> {code:title=TestCase.java|borderStyle=solid}
> @Test
> 	public void testSendTextMessageToDestination() throws Exception {
> 		Publisher pub = new Publisher();
> 		pub.create("5", "topic");
> 		pub.sendName("Roan", "Monteiro");
> 		String greeting1 = new Subscriber().getGreeting(1000);
> 		assertEquals("Hello Roan Monteiro!", greeting1);
> 		pub.closeConnection();
> 	}
> {code}
> Where my publisher and subscriber are:
> {code:title=Publisher.java|borderStyle=solid}
> package com.redhat.messaging.topicagents;
> import javax.jms.Connection;
> import javax.jms.ConnectionFactory;
> import javax.jms.JMSException;
> import javax.jms.MessageProducer;
> import javax.jms.Session;
> import javax.jms.TextMessage;
> import javax.jms.Topic;
> import org.apache.activemq.artemis.api.core.TransportConfiguration;
> import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
> import org.apache.activemq.artemis.api.jms.JMSFactoryType;
> import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
> /**
>  * Non-Durable Subscrition
>  * @author roanbrasil
>  *
>  */
> public class Publisher {
>     private static final Logger LOGGER = LoggerFactory
>             .getLogger(Publisher.class);
>     private String clientId;
>     private Connection connection;
>     private Session session;
>     private MessageProducer messageProducer;
>     public void create(String clientId, String topicName) throws JMSException {
>         this.clientId = clientId;
>         // create a Connection Factory
>         TransportConfiguration transportConfiguration = new TransportConfiguration(
> 				NettyConnectorFactory.class.getName());
> 		ConnectionFactory cf = ActiveMQJMSClient
> 				.createConnectionFactoryWithoutHA(JMSFactoryType.TOPIC_CF,
> 						transportConfiguration);
>         // create a Connection
>         connection = cf.createConnection();
>         connection.setClientID(clientId);
>         // create a Session
>         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
>         // create the Topic to which messages will be sent
>         Topic topic = session.createTopic(topicName);
>         // create a MessageProducer for sending messages
>         messageProducer = session.createProducer(topic);
>     }
>     public void closeConnection() throws JMSException {
>         connection.close();
>     }
>     public void sendName(String firstName, String lastName) throws JMSException {
>         String text = firstName + " " + lastName;
>         // create a JMS TextMessage
>         TextMessage textMessage = session.createTextMessage(text);
>         // send the message to the topic destination
>         messageProducer.send(textMessage);
>         LOGGER.debug(clientId + ": sent message with text='{}'", text);
>     }
> }
> {code}
> {code:title=Subscriber.java|borderStyle=solid}
> package com.redhat.messaging.topicagents;
> import javax.jms.Connection;
> import javax.jms.ConnectionFactory;
> import javax.jms.JMSException;
> import javax.jms.Message;
> import javax.jms.MessageConsumer;
> import javax.jms.Session;
> import javax.jms.TextMessage;
> import javax.jms.Topic;
> import org.apache.activemq.artemis.api.core.TransportConfiguration;
> import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
> import org.apache.activemq.artemis.api.jms.JMSFactoryType;
> import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
> import org.slf4j.Logger;
> import org.slf4j.LoggerFactory;
> public class Subscriber {
>     private static final Logger LOGGER = LoggerFactory
>             .getLogger(Subscriber.class);
>     private static final String NO_GREETING = "no greeting";
>     private String clientId;
>     private Connection connection;
>     private Session session;
>     private MessageConsumer messageConsumer;
>     public void create(String clientId, String topicName) throws JMSException {
>         this.clientId = clientId;
>      // create a Connection Factory
>         TransportConfiguration transportConfiguration = new TransportConfiguration(
> 				NettyConnectorFactory.class.getName());
> 		ConnectionFactory cf = ActiveMQJMSClient
> 				.createConnectionFactoryWithoutHA(JMSFactoryType.TOPIC_CF,
> 						transportConfiguration);
>         // create a Connection
>         connection = cf.createConnection();
>         connection.setClientID(clientId);
>         // create a Session
>         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
>         // create the Topic from which messages will be received
>         Topic topic = session.createTopic(topicName);
>         // create a MessageConsumer for receiving messages
>         messageConsumer = session.createConsumer(topic);
>         // start the connection in order to receive messages
>         connection.start();
>     }
>     public void closeConnection() throws JMSException {
>         connection.close();
>     }
>     public String getGreeting(int timeout) throws JMSException {
>         String greeting = NO_GREETING;
>         // read a message from the topic destination
>         Message message = messageConsumer.receive(timeout);
>         // check if a message was received
>         if (message != null) {
>             // cast the message to the correct type
>             TextMessage textMessage = (TextMessage) message;
>             // retrieve the message content
>             String text = textMessage.getText();
>             LOGGER.debug(clientId + ": received message with text='{}'", text);
>             // create greeting
>             greeting = "Hello " + text + "!";
>         } else {
>             LOGGER.debug(clientId + ": no message received");
>         }
>         LOGGER.info("greeting={}", greeting);
>         return greeting;
>     }
> }
> {code}
> When I got to ChannelImpl.class is created a temporary Topic which the name is jms.temptopic.topic. On the packet variable the type is 49 and the channel Id is 11. But the sendBlocking return the response variable with no queueNames and setting exists as false, I believe this queueName should come with topic name and the exists variable as true value.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)