You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by astepanenko <an...@gmail.com> on 2007/05/12 21:03:33 UTC

Correct way to removeDestinations()

Dear Developers,

I my project I need to create and remove destinations (Queues) for
connecting/disconnecting clients frequently. After reading a bit on JMS
topics I got a feeling that in general dynamic creation of queues/topics is
not encouraged. But I need to do that anyway.
Sometimes I also need to remove all queues at a Broker instance except of my
CONTROL_QUEUE. So, in DELETE_QUEUES onMessage() handler I do:

ObjectName[] queues = brokerService.getAdminView().getQueues();

then for each queue received I check if it's not a CONTROL_QUEUE and do:

brokerService.getAdminView().removeQueue(qName);

The problem is that after the above deletion I create new queues at the
Broker but it appears that DELETE_QUEUES message processing still not
finished at the time I call jmsSession.createQueue() and as a result I get
my newly created queues deleted too.
Both DELETE_QUEUES message is sent and new queues are created from the same
remote client, so in the logs two operations appear one after another with
smth like 4 seconds interval. But at the broker side, we noticed that each
queue deletion takes too much time, smth like 1 second per each queue. 

Later in the sources of BrokerView.removeQueue(String name) I found:

broker.removeDestination(getConnectionContext(broker.getContextBroker()),
new ActiveMQQueue(name), 1000);

The last parameter is timeout in milliseconds and it explained why each
queue deletion takes up-to 1 second.

So, finally the call to removeQueue() ends up in
AbstractRegion.removeDestination(...) which actually synchronizes on
destinationsMutex and then removes the destination.

Taking the above into account, what would be the correct and efficient (not
waiting for timeout) way to remove queues (and topics) from Broker? Should I
iterate over the queue subscribers and try to force them to close and then
remove the destination? I also do not get JMSException("Destination still
has an active subscription:" ...) since the Broker waits for timeout.

I also noticed that there is no control over timeout value from the user
perspective, since getAdminView().removeQueue() doesn't let you to specify
one.

Any help is much appreciated.

Thank you in advance,
Andrew
-- 
View this message in context: http://www.nabble.com/Correct-way-to-removeDestinations%28%29-tf3732843s2354.html#a10448825
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.


Re: Correct way to removeDestinations()

Posted by James Strachan <ja...@gmail.com>.
On 5/14/07, astepanenko <an...@gmail.com> wrote:
>
> Hello James,
>
> thank you very much for your reply.
> Per your questions about why would we like to delete queues, the answer is
> that we do not re-use queues for an extra security measure, we don't re-use
> queues having the same name.  Rather we create a new queue for the Client
> each time it connects.

Sounds like you want to use temporary queues which do this already.

-- 
James
-------
http://macstrac.blogspot.com/

Re: Correct way to removeDestinations()

Posted by astepanenko <an...@gmail.com>.
Hello James,

thank you very much for your reply.
Per your questions about why would we like to delete queues, the answer is
that we do not re-use queues for an extra security measure, we don't re-use
queues having the same name.  Rather we create a new queue for the Client
each time it connects.  In this case we are simulating a failure and so the
queues must be removed to avoid having them lie around.  When we are
monitoring the AMQ we also don't want to see old un-used queues, even if
they don't take up much resources.  Note there will be however thousands of
clients which would equate to thousands of unused queues if we didn't delete
them.

So, currently the solution I think of is to add another method to
AbstractRegion class, called removeDestinations(List<String> destsToRemove)
that would remove destinations which match the provided names in one single
acquire-release-destinations-mutex step, and thus to avoid waiting for
destinationsMutex during one by one deletion of destinations.

Does the above make sense? Is there any better solution?

Thank you in advance,
Andrew.





James.Strachan wrote:
> 
> On 5/12/07, astepanenko <an...@gmail.com> wrote:
>> Dear Developers,
>>
>> I my project I need to create and remove destinations (Queues) for
>> connecting/disconnecting clients frequently. After reading a bit on JMS
>> topics I got a feeling that in general dynamic creation of queues/topics
>> is
>> not encouraged.
> 
> Not at all - be totally dynamic if you like
> 
> 
>> But I need to do that anyway.
>> Sometimes I also need to remove all queues at a Broker instance except of
>> my
>> CONTROL_QUEUE. So, in DELETE_QUEUES onMessage() handler I do:
>>
>> ObjectName[] queues = brokerService.getAdminView().getQueues();
>>
>> then for each queue received I check if it's not a CONTROL_QUEUE and do:
>>
>> brokerService.getAdminView().removeQueue(qName);
> 
> Why do you need to delete a queue? FWIW purging a queue is more usual
> 
> 
>> The problem is that after the above deletion I create new queues at the
>> Broker but it appears that DELETE_QUEUES message processing still not
>> finished at the time I call jmsSession.createQueue() and as a result I
>> get
>> my newly created queues deleted too.
>> Both DELETE_QUEUES message is sent and new queues are created from the
>> same
>> remote client, so in the logs two operations appear one after another
>> with
>> smth like 4 seconds interval. But at the broker side, we noticed that
>> each
>> queue deletion takes too much time, smth like 1 second per each queue.
>>
>> Later in the sources of BrokerView.removeQueue(String name) I found:
>>
>> broker.removeDestination(getConnectionContext(broker.getContextBroker()),
>> new ActiveMQQueue(name), 1000);
>>
>> The last parameter is timeout in milliseconds and it explained why each
>> queue deletion takes up-to 1 second.
>>
>> So, finally the call to removeQueue() ends up in
>> AbstractRegion.removeDestination(...) which actually synchronizes on
>> destinationsMutex and then removes the destination.
>>
>> Taking the above into account, what would be the correct and efficient
>> (not
>> waiting for timeout) way to remove queues (and topics) from Broker?
> 
> I still don't get why you really care about removing a queue; surely
> just purging it would do the trick?
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Correct-way-to-removeDestinations%28%29-tf3732843s2354.html#a10610678
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.


Re: Correct way to removeDestinations()

Posted by James Strachan <ja...@gmail.com>.
On 5/12/07, astepanenko <an...@gmail.com> wrote:
> Dear Developers,
>
> I my project I need to create and remove destinations (Queues) for
> connecting/disconnecting clients frequently. After reading a bit on JMS
> topics I got a feeling that in general dynamic creation of queues/topics is
> not encouraged.

Not at all - be totally dynamic if you like


> But I need to do that anyway.
> Sometimes I also need to remove all queues at a Broker instance except of my
> CONTROL_QUEUE. So, in DELETE_QUEUES onMessage() handler I do:
>
> ObjectName[] queues = brokerService.getAdminView().getQueues();
>
> then for each queue received I check if it's not a CONTROL_QUEUE and do:
>
> brokerService.getAdminView().removeQueue(qName);

Why do you need to delete a queue? FWIW purging a queue is more usual


> The problem is that after the above deletion I create new queues at the
> Broker but it appears that DELETE_QUEUES message processing still not
> finished at the time I call jmsSession.createQueue() and as a result I get
> my newly created queues deleted too.
> Both DELETE_QUEUES message is sent and new queues are created from the same
> remote client, so in the logs two operations appear one after another with
> smth like 4 seconds interval. But at the broker side, we noticed that each
> queue deletion takes too much time, smth like 1 second per each queue.
>
> Later in the sources of BrokerView.removeQueue(String name) I found:
>
> broker.removeDestination(getConnectionContext(broker.getContextBroker()),
> new ActiveMQQueue(name), 1000);
>
> The last parameter is timeout in milliseconds and it explained why each
> queue deletion takes up-to 1 second.
>
> So, finally the call to removeQueue() ends up in
> AbstractRegion.removeDestination(...) which actually synchronizes on
> destinationsMutex and then removes the destination.
>
> Taking the above into account, what would be the correct and efficient (not
> waiting for timeout) way to remove queues (and topics) from Broker?

I still don't get why you really care about removing a queue; surely
just purging it would do the trick?

-- 
James
-------
http://macstrac.blogspot.com/

Re: Correct way to removeDestinations()

Posted by bhartsb <bh...@cox.net>.
The reasons we need to delete were given as item 3 and 4.  So will the method
Andrew gave work?   The method was: "add another method to AbstractRegion
class, called removeDestinations(List<String> destsToRemove) that would
remove destinations which match the provided names in one single
acquire-release-destinations-mutex step, and thus to avoid waiting for
destinationsMutex during one by one deletion of destinations. "

Regarding security, am I incorrect in thinking that giving untrusted clients
the credentials to access the AMQ broker and (dynamically) create queues is
a security risk?  If I have thousands of clients and any hacker acquires
these credentials then they can stage an attack on the AMQ.  

My business case is such that regular queues are the best fit, and surely
other people working with AMQ, who are using regular queues widely (meaning
AMQ is available over the Internet), are taking a security risk of attack
with the current implementation.  Am I wrong in my thinking?





James.Strachan wrote:
> 
> On 5/15/07, bhartsb <bh...@cox.net> wrote:
>>
>>
>> We have a couple of issues that seem to preclude using temporary queues:
>>
>> 1.  Our C++ clients that use the queues are utilizing STOMP to do so (we
>> can't afford the time to retrofit the C++ apps for openwire at this
>> juncture).  STOMP as I understand does not support temporary queues.
>>
>> 2.  Our C++ clients may temporarily lose a connection to the queues, but
>> reconnect quickly.  In this case we don't want to lose any messages.  It
>> seems from posts that a loss of connection would mean that the msgs in
>> the
>> queues (or still being added) are lost, because the queue connection
>> would
>> not be re-established.  (Note: if the connection is lost for a long
>> period
>> then we do want to create a new queue).
>>
>> 3.  We have our server telling the client applications, what queues to
>> connect to.  The Clients have no knowledge themselves of the queue they
>> need
>> to connect to, and it can be that a producer will connect before a
>> consumer
>> or vice versa.
>>
>> 4.  We don't want client applications to be able to create queues
>> themselves
>> (only publish or consume).  If we did allow them create/destroy
>> priviledge
>> then we would have to give the clients the proper JAAS credentials to
>> allow
>> this.  But the client apps. will be in the public domain.  If they have
>> such
>> credentials then there is a risk that a hacker could get one Client's
>> credentials and gain access to the AMQ broker.  This leaves the AMQ
>> vulnerable to attack.  This is not a risk we want to take.
>>
>> Now if I am wrong about 4 being a security/attack risk, then we could
>> have
>> the server pass the temporary queue name to the producer and consumer
>> apps.
>> But am I wrong?
>>
>> Finally, you mentioned to Andrew that AMQ queues are dynamic, but I don't
>> see this as being the case if they can't be programatically deleted.  I
>> assume you weren't just talking about temporary queues when you said
>> queues
>> are dynamic.
> 
> Any messaging client can talk to any new dynamic destination whenever
> they like (assuming the security allows this) - there is no
> administration required to create a queue - thats why I said they were
> dynamic.
> 
>> Please respond if you can to this and Andrews' prior question about his
>> method of deleting queues (see his last post), and thank you.
> 
> So i still don't get why you insist on deleting queues, rather than
> just purging them.
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Correct-way-to-removeDestinations%28%29-tf3732843s2354.html#a10630854
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.


Re: Correct way to removeDestinations()

Posted by James Strachan <ja...@gmail.com>.
On 5/15/07, bhartsb <bh...@cox.net> wrote:
>
>
> We have a couple of issues that seem to preclude using temporary queues:
>
> 1.  Our C++ clients that use the queues are utilizing STOMP to do so (we
> can't afford the time to retrofit the C++ apps for openwire at this
> juncture).  STOMP as I understand does not support temporary queues.
>
> 2.  Our C++ clients may temporarily lose a connection to the queues, but
> reconnect quickly.  In this case we don't want to lose any messages.  It
> seems from posts that a loss of connection would mean that the msgs in the
> queues (or still being added) are lost, because the queue connection would
> not be re-established.  (Note: if the connection is lost for a long period
> then we do want to create a new queue).
>
> 3.  We have our server telling the client applications, what queues to
> connect to.  The Clients have no knowledge themselves of the queue they need
> to connect to, and it can be that a producer will connect before a consumer
> or vice versa.
>
> 4.  We don't want client applications to be able to create queues themselves
> (only publish or consume).  If we did allow them create/destroy priviledge
> then we would have to give the clients the proper JAAS credentials to allow
> this.  But the client apps. will be in the public domain.  If they have such
> credentials then there is a risk that a hacker could get one Client's
> credentials and gain access to the AMQ broker.  This leaves the AMQ
> vulnerable to attack.  This is not a risk we want to take.
>
> Now if I am wrong about 4 being a security/attack risk, then we could have
> the server pass the temporary queue name to the producer and consumer apps.
> But am I wrong?
>
> Finally, you mentioned to Andrew that AMQ queues are dynamic, but I don't
> see this as being the case if they can't be programatically deleted.  I
> assume you weren't just talking about temporary queues when you said queues
> are dynamic.

Any messaging client can talk to any new dynamic destination whenever
they like (assuming the security allows this) - there is no
administration required to create a queue - thats why I said they were
dynamic.

> Please respond if you can to this and Andrews' prior question about his
> method of deleting queues (see his last post), and thank you.

So i still don't get why you insist on deleting queues, rather than
just purging them.

-- 
James
-------
http://macstrac.blogspot.com/

Re: Correct way to removeDestinations()

Posted by bhartsb <bh...@cox.net>.

We have a couple of issues that seem to preclude using temporary queues:

1.  Our C++ clients that use the queues are utilizing STOMP to do so (we
can't afford the time to retrofit the C++ apps for openwire at this
juncture).  STOMP as I understand does not support temporary queues.

2.  Our C++ clients may temporarily lose a connection to the queues, but
reconnect quickly.  In this case we don't want to lose any messages.  It
seems from posts that a loss of connection would mean that the msgs in the
queues (or still being added) are lost, because the queue connection would
not be re-established.  (Note: if the connection is lost for a long period
then we do want to create a new queue).

3.  We have our server telling the client applications, what queues to
connect to.  The Clients have no knowledge themselves of the queue they need
to connect to, and it can be that a producer will connect before a consumer
or vice versa. 

4.  We don't want client applications to be able to create queues themselves
(only publish or consume).  If we did allow them create/destroy priviledge
then we would have to give the clients the proper JAAS credentials to allow
this.  But the client apps. will be in the public domain.  If they have such
credentials then there is a risk that a hacker could get one Client's
credentials and gain access to the AMQ broker.  This leaves the AMQ
vulnerable to attack.  This is not a risk we want to take.  

Now if I am wrong about 4 being a security/attack risk, then we could have
the server pass the temporary queue name to the producer and consumer apps. 
But am I wrong?

Finally, you mentioned to Andrew that AMQ queues are dynamic, but I don't
see this as being the case if they can't be programatically deleted.  I
assume you weren't just talking about temporary queues when you said queues
are dynamic.

Please respond if you can to this and Andrews' prior question about his
method of deleting queues (see his last post), and thank you.



astepanenko wrote:
> 
> Dear Developers,
> 
> I my project I need to create and remove destinations (Queues) for
> connecting/disconnecting clients frequently. After reading a bit on JMS
> topics I got a feeling that in general dynamic creation of queues/topics
> is not encouraged. But I need to do that anyway.
> Sometimes I also need to remove all queues at a Broker instance except of
> my CONTROL_QUEUE. So, in DELETE_QUEUES onMessage() handler I do:
> 
> ObjectName[] queues = brokerService.getAdminView().getQueues();
> 
> then for each queue received I check if it's not a CONTROL_QUEUE and do:
> 
> brokerService.getAdminView().removeQueue(qName);
> 
> The problem is that after the above deletion I create new queues at the
> Broker but it appears that DELETE_QUEUES message processing still not
> finished at the time I call jmsSession.createQueue() and as a result I get
> my newly created queues deleted too.
> Both DELETE_QUEUES message is sent and new queues are created from the
> same remote client, so in the logs two operations appear one after another
> with smth like 4 seconds interval. But at the broker side, we noticed that
> each queue deletion takes too much time, smth like 1 second per each
> queue. 
> 
> Later in the sources of BrokerView.removeQueue(String name) I found:
> 
> broker.removeDestination(getConnectionContext(broker.getContextBroker()),
> new ActiveMQQueue(name), 1000);
> 
> The last parameter is timeout in milliseconds and it explained why each
> queue deletion takes up-to 1 second.
> 
> So, finally the call to removeQueue() ends up in
> AbstractRegion.removeDestination(...) which actually synchronizes on
> destinationsMutex and then removes the destination.
> 
> Taking the above into account, what would be the correct and efficient
> (not waiting for timeout) way to remove queues (and topics) from Broker?
> Should I iterate over the queue subscribers and try to force them to close
> and then remove the destination? I also do not get
> JMSException("Destination still has an active subscription:" ...) since
> the Broker waits for timeout.
> 
> I also noticed that there is no control over timeout value from the user
> perspective, since getAdminView().removeQueue() doesn't let you to specify
> one.
> 
> Any help is much appreciated.
> 
> Thank you in advance,
> Andrew
> 

-- 
View this message in context: http://www.nabble.com/Correct-way-to-removeDestinations%28%29-tf3732843s2354.html#a10619825
Sent from the ActiveMQ - Dev mailing list archive at Nabble.com.