Sergio Scaramuzzi
Sergio Scaramuzzi

Reputation: 15

Can't use management API with JMS to change address settings

I am quite new to the world of JMS and ActiveMQ Artemis, and I'm struggling to make use of the management API to send a JMS message to my stand alone broker.

I am using ActiveMQ Artemis 2.38.0.

I want to update the address settings without using broker.xml, but I keep getting null as a reply, and the settings clearly don't change when I go to test them.

I followed along with a similar post and was able to come up with this bit of code:

try (JMSContext context = activeMQConnectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
            //You MUST explicitly create this queue for management operations.
            Queue managementQueue = context.createQueue("activemq.management");

            Message message = context.createMessage();
            JMSManagementHelper.putOperationInvocation(
                message,
                ResourceNames.BROKER,    // Targetted Resource
                "addAddressSettings",    // Operation to invoke
                "ri.trips1",             // Address match
                null,                    // Dead letter address (DLA)
                null,                    // Expiry address
                -1L,                     // Expiry delay
                true,                    // Last value queue
                7,                       // Max delivery attempts
                -1L,                     // Max size bytes
                0,                       // Page size bytes
                -1,                      // Page max cache size
                1000L,                   // Redelivery delay
                1.0,                     // Redelivery multiplier
                -1L,                     // Max redelivery delay
                -1L,                     // Slow consumer threshold
                false,                   // Slow consumer policy
                null,                    // Slow consumer notification interval
                -1L,                     // Min large message size
                -1L,                     // Consumer window size
                null,                    // Auto-create queues
                true,                    // Auto-create addresses
                false,                   // Auto-delete queues
                false,                   // Auto-delete addresses
                true                     // Auto-delete created queues
            );
            context.createProducer().send(managementQueue, message);

            Message response = context.createConsumer(managementQueue).receive(5000);
            if (response != null && JMSManagementHelper.hasOperationSucceeded(response)) {
                System.out.println("Address settings applied successfully.");
            } else {
                System.err.println("Failed to apply address settings");
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }

The code block here is always resolving to failed because the response is always null. However, it is creating the address activemq.management just fine.

Upvotes: 1

Views: 42

Answers (1)

Justin Bertram
Justin Bertram

Reputation: 35122

The problem here is the way you're sending the request and receiving the reply. There's nothing to correlate the request with the response so you're not actually receiving a response. You could use a QueueRequestor as is demonstrated in the management example from ActiveMQ Artemis or you could stick with the JMSContext and correlate the response yourself, e.g.:

try (JMSContext context = activeMQConnectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
   // You MUST explicitly create this queue for management operations.
   Queue managementQueue = context.createQueue("activemq.management");

   Message message = context.createMessage();
   JMSManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, ...);
   Queue responseQueue = context.createTemporaryQueue();
   message.setJMSReplyTo(responseQueue);
   context.createProducer().send(managementQueue, message);
   Message response = context.createConsumer(responseQueue).receive(5000);
   if (response != null && JMSManagementHelper.hasOperationSucceeded(response)) {
      System.out.println("Address settings applied successfully.");
   } else {
      System.err.println("Failed to apply address settings");
   }
} catch (JMSException e) {
   e.printStackTrace();
}

Also, it's worth noting that the addAddressSettings method you're using is deprecated. I encourage you to use this one instead which takes flexible JSON input, e.g.

try (JMSContext context = activeMQConnectionFactory.createContext(JMSContext.AUTO_ACKNOWLEDGE)) {
   //You MUST explicitly create this queue for management operations.
   Queue managementQueue = context.createQueue("activemq.management");
   Message message = context.createMessage();
   String json = """
      {
         "maxDeliveryAttempts": "7",
         "maxSizeBytes": "-1",
         "pageSizeBytes": "0",
         "redeliveryDelay": "1000"         
      }
      """;
   JMSManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, "addAddressSettings", "ri.trips1", json);
   Queue responseQueue = context.createTemporaryQueue();
   message.setJMSReplyTo(responseQueue);
   context.createProducer().send(managementQueue, message);

   Message response = context.createConsumer(responseQueue).receive(5000);
   if (response != null && JMSManagementHelper.hasOperationSucceeded(response)) {
      System.out.println("Address settings applied successfully.");
   } else {
      System.err.println("Failed to apply address settings");
   }
} catch (JMSException e) {
   e.printStackTrace();
}

Upvotes: 1

Related Questions