Reputation: 91
I'm using Spring Boot to perform a JNDI lookup
so I can subscribe to Artemis' management notifications and figure out when a client is no longer subscribed to a particular topic. I'm fairly new to JNDI and my understanding is that the code snippet I've provided causes a connection to an existing Artemis broker to be established and consequently captures notifications being sent by the broker.
I get an error when control hits the connection = cf.createConnection();
line in the code snippet provided.
Error:
Caused by: javax.jms.JMSSecurityException: AMQ229031: Unable to validate user from /ip:port. Username: null; SSL certificate subject DN: unavailable
...
Caused by: org.apache.activemq.artemis.api.core.ActiveMQSecurityException: AMQ229031: Unable to validate user from /ip:port. Username: null; SSL certificate subject DN: unavailable
How do I include the username, password, keystore and truststore in the InitialContext
so that this error doesn't show up?
Code I'm using:
@ComponentScan({"com.management.notifications"})
@SpringBootApplication
public class ManagementNotificationTestApplication {
@Value("${JMS_BROKER_TRUSTSTORE}")
private String pathToTrustStore;
public static void main(String[] args) {
SpringApplication.run(ManagementNotificationTestApplication.class);
}
@EventListener(ApplicationReadyEvent.class)
public void doSomething() throws NamingException, JMSException {
Connection connection = null;
InitialContext initialContext = null;
try {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
properties.setProperty(Context.PROVIDER_URL, "tcp://ipAddress:portNumber?&" + "sslEnabled=true&" +
"trustStorePath=" + pathToTrustStore + "&trustStorePassword=" + "abc");
// Step 1. Create an initial context to perform the JNDI lookup.
initialContext = new InitialContext(properties);
// Step 3. Perform a lookup on the Connection Factory
ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
// Step 4.Create a JMS connection, a session and a producer for the queue
connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Step 5. Perform a lookup on the notifications topic
Topic notificationsTopic = (Topic) initialContext.lookup("topic/notificationsTopic");
// Step 6. Create a JMS message consumer for the notification queue and set its message listener
// It will display all the properties of the JMS Message
MessageConsumer notificationConsumer = session.createConsumer(notificationsTopic);
notificationConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(final Message notif) {
System.out.println("------------------------");
System.out.println("Received notification:");
try {
Enumeration propertyNames = notif.getPropertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String) propertyNames.nextElement();
System.out.format(" %s: %s%n", propertyName, notif.getObjectProperty(propertyName));
}
} catch (JMSException e) {
}
System.out.println("------------------------");
}
});
// Step 7. Start the Connection to allow the consumers to receive messages
connection.start();
// Step 10. Try to create a connection with unknown user
try {
cf.createConnection("not.a.valid.user", "not.a.valid.password");
} catch (JMSException e) {
}
// sleep a little bit to be sure to receive the notification for the security
// authentication violation before leaving the example
/*Thread.sleep(2000);*/
} finally {
// Step 11. Be sure to close the resources!
if (initialContext != null) {
initialContext.close();
}
if (connection != null) {
connection.close();
}
}
}
}
Upvotes: 1
Views: 1181
Reputation: 34998
There's nothing wrong with your JNDI code. You just need to pass the username and password via createConnection(String, String)
. This is standard practice in JMS.
It's worth noting that the fact that you're getting an authentication error means that your SSL configuration is working. If your SSL config wasn't correct then you'd get an SSL error before you even made a successful connection to the broker and tried to authenticate.
Upvotes: 1