You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Marcel Casado (JIRA)" <ji...@apache.org> on 2011/05/13 00:55:47 UTC

[jira] [Created] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and ActiveMQ.Advisory.MessageConsumed.Queue Topics receive advisory messages when

ActiveMQ.Advisory.MessageConsumed.TempQueue and ActiveMQ.Advisory.MessageConsumed.Queue Topics receive advisory messages when 
------------------------------------------------------------------------------------------------------------------------------

                 Key: AMQ-3320
                 URL: https://issues.apache.org/jira/browse/AMQ-3320
             Project: ActiveMQ
          Issue Type: Bug
    Affects Versions: 5.5.0, 5.4.2
            Reporter: Marcel Casado
            Priority: Minor


I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  

In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
 
Looking at the code for TempQueue and Queue this is the sequence :

TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 

This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.


Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html


--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Updated] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Marcel Casado updated AMQ-3320:
-------------------------------

    Attachment: AdvisoryTempDestinationTests.java

Added testTempMessageConsumedAdvisoryConnectionClose() method to test this issue. The test should fail since the test expects no new advisories when the connection is close 

> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Commented] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13064135#comment-13064135 ] 

Timothy Bish commented on AMQ-3320:
-----------------------------------

I'd suggest something like this instead of the disable / enable method shown above. 

{code}
### Eclipse Workspace Patch 1.0
#P activemq-core
Index: src/main/java/org/apache/activemq/broker/region/BaseDestination.java
===================================================================
--- src/main/java/org/apache/activemq/broker/region/BaseDestination.java	(revision 1145597)
+++ src/main/java/org/apache/activemq/broker/region/BaseDestination.java	(working copy)
@@ -452,7 +452,9 @@
      * @param messageReference
      */
     public void messageConsumed(ConnectionContext context, MessageReference messageReference) {
-        if (advisoryForConsumed) {
+        // If there are no consumers then the message was consumed by a purge which we don't
+        // want to propagate as a consumer ack of the message.
+        if (advisoryForConsumed && destinationStatistics.getConsumers().getCount() > 0) {
             broker.messageConsumed(context, messageReference);
         }
     }
{code}

> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13032744#comment-13032744 ] 

Marcel Casado commented on AMQ-3320:
------------------------------------

  A possible simple solution is to set setAdvisoryForConsumed(false); at the beginning of the purge() or maybe in  removeMessage(ConnectionContext c, QueueMessageReference r) method in Queue.java

   public void purge() throws Exception {
    	setAdvisoryForConsumed(false);
        ConnectionContext c = createConnectionContext();
        List<MessageReference> list = null;
        do {
            doPageIn(true);
            pagedInMessagesLock.readLock().lock();
            try {
                list = new ArrayList<MessageReference>(pagedInMessages.values());
            }finally {
                pagedInMessagesLock.readLock().unlock();
            }

            for (MessageReference ref : list) {
                try {
                    QueueMessageReference r = (QueueMessageReference) ref;
                    removeMessage(c, r);
                } catch (IOException e) {
                }
            }
            // don't spin/hang if stats are out and there is nothing left in the
            // store
        } while (!list.isEmpty() && this.destinationStatistics.getMessages().getCount() > 0);
        if (this.destinationStatistics.getMessages().getCount() > 0) {
            LOG.warn(getActiveMQDestination().getQualifiedName()
                    + " after purge complete, message count stats report: "
                    + this.destinationStatistics.getMessages().getCount());
        }
        gc();
        this.destinationStatistics.getMessages().setCount(0);
        getMessages().clear();
    }



> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Updated] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Marcel Casado updated AMQ-3320:
-------------------------------

    Summary: ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged  (was: ActiveMQ.Advisory.MessageConsumed.TempQueue and ActiveMQ.Advisory.MessageConsumed.Queue Topics receive advisory messages when )

> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Issue Comment Edited] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13032740#comment-13032740 ] 

Marcel Casado edited comment on AMQ-3320 at 5/13/11 8:22 PM:
-------------------------------------------------------------

Added testTempMessageConsumedAdvisoryConnectionClose() method to test this issue. The test should fail since the test expects no new advisories when the connection is closed 

      was (Author: marcelcasado):
    Added testTempMessageConsumedAdvisoryConnectionClose() method to test this issue. The test should fail since the test expects no new advisories when the connection is close 
  
> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Commented] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13064239#comment-13064239 ] 

Marcel Casado commented on AMQ-3320:
------------------------------------

Probably I'm missing something but I think that checking the number of consumers does not fix all the possible use cases that can go wrong. Like if I hit "purge" in jconsole for a "queue" with slow consumers and remaining messages in the queue. The removed messages are going to cause the creation of advisory messages.  

> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Issue Comment Edited] (AMQ-3320) ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged

Posted by "Marcel Casado (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/AMQ-3320?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13032744#comment-13032744 ] 

Marcel Casado edited comment on AMQ-3320 at 5/13/11 8:22 PM:
-------------------------------------------------------------

  A possible simple solution is to set setAdvisoryForConsumed(false); at the beginning of the purge() or maybe in  removeMessage(ConnectionContext c, QueueMessageReference r) method in Queue.java

   public void purge() throws Exception {
        boolean isAdvisoryForConsumed = isAdvisoryForConsumed();
    	setAdvisoryForConsumed(false);

        ConnectionContext c = createConnectionContext();
        List<MessageReference> list = null;
        do {
            doPageIn(true);
            pagedInMessagesLock.readLock().lock();
            try {
                list = new ArrayList<MessageReference>(pagedInMessages.values());
            }finally {
                pagedInMessagesLock.readLock().unlock();
            }

            for (MessageReference ref : list) {
                try {
                    QueueMessageReference r = (QueueMessageReference) ref;
                    removeMessage(c, r);
                } catch (IOException e) {
                }
            }
            // don't spin/hang if stats are out and there is nothing left in the
            // store
        } while (!list.isEmpty() && this.destinationStatistics.getMessages().getCount() > 0);
        if (this.destinationStatistics.getMessages().getCount() > 0) {
            LOG.warn(getActiveMQDestination().getQualifiedName()
                    + " after purge complete, message count stats report: "
                    + this.destinationStatistics.getMessages().getCount());
        }
        gc();
        this.destinationStatistics.getMessages().setCount(0);
        getMessages().clear();
        setAdvisoryForConsumed(isAdvisoryForConsumed);
    }



      was (Author: marcelcasado):
      A possible simple solution is to set setAdvisoryForConsumed(false); at the beginning of the purge() or maybe in  removeMessage(ConnectionContext c, QueueMessageReference r) method in Queue.java

   public void purge() throws Exception {
    	setAdvisoryForConsumed(false);
        ConnectionContext c = createConnectionContext();
        List<MessageReference> list = null;
        do {
            doPageIn(true);
            pagedInMessagesLock.readLock().lock();
            try {
                list = new ArrayList<MessageReference>(pagedInMessages.values());
            }finally {
                pagedInMessagesLock.readLock().unlock();
            }

            for (MessageReference ref : list) {
                try {
                    QueueMessageReference r = (QueueMessageReference) ref;
                    removeMessage(c, r);
                } catch (IOException e) {
                }
            }
            // don't spin/hang if stats are out and there is nothing left in the
            // store
        } while (!list.isEmpty() && this.destinationStatistics.getMessages().getCount() > 0);
        if (this.destinationStatistics.getMessages().getCount() > 0) {
            LOG.warn(getActiveMQDestination().getQualifiedName()
                    + " after purge complete, message count stats report: "
                    + this.destinationStatistics.getMessages().getCount());
        }
        gc();
        this.destinationStatistics.getMessages().setCount(0);
        getMessages().clear();
    }


  
> ActiveMQ.Advisory.MessageConsumed.TempQueue and AMQ.A.MC.Queue Topics receive advisory messages when TQ or Queue are purged
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-3320
>                 URL: https://issues.apache.org/jira/browse/AMQ-3320
>             Project: ActiveMQ
>          Issue Type: Bug
>    Affects Versions: 5.4.2, 5.5.0
>            Reporter: Marcel Casado
>            Priority: Minor
>         Attachments: AdvisoryTempDestinationTests.java
>
>
> I have enabled <policyEntry tempQueue="true" advisoryForConsumed="true" /> in the broker so I can subscribe to "ActiveMQ.Advisory.MessageConsumed.TempQueue.>" to get notified of messages consumed on a tempQueue/s. When client shuts down 
> if remaining messages are in the tempQueue an advisory message is generated and send to the ActiveMQ.Advisory.MessageConsumed.TempQueue topic for each message for that tempQueue. The same will happen if purge() is called on a TempQueue or Queue for example through JMX.  
> In my application I need to know if a message is consumed by a client but I can not differentiate between a client "ack" massage and one "ack" by the broker when the tempQueue is "disposed" looking to the message sent to the ActiveMQ.Advisory.MessageConsumed.TempQueue... . 
>  
> Looking at the code for TempQueue and Queue this is the sequence :
> TempQueue.dispose(context) --> purge() --> removeMessage() -> acknowledge() --> messageConsumed() 
> This is kind of a conceptual issue since myself consider that removing a message due a purge or a tempQueue cleanup should not trigger a messageConsumed advisory.
> Original ActiveMQ users post : http://activemq.2283324.n4.nabble.com/ActiveMQ-Advisory-MessageConsumed-TempQueue-problem-td3510067.html

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira