Topics and queues can be used remotely. A remote client must use JNDI to get the default JMS connection factory. Here's the code to obtain the connection factory:
String CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
...
final Properties env = new Properties();
env.put(INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(PROVIDER_URL, "http-remoting://127.0.0.1:8080");
Context namingContext = new InitialContext(env);
ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup(CONNECTION_FACTORY);
The remote connection factory is declared in the standalone-full.xml property file in the standalone/configuration folder of WildFly:
<connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
The connectors field lets the connection factory be called with JNDI through the http-remoting protocol. This protocol was created since the JBoss 5 application server, and it lets you execute remote callings directly through the HTTP protocol.
Once we have the connection factory, we can take the destination that can be a queue or a topic. This is how you take a remote queue through JNDI:
String REMOTE_QUEUE_LOOKUP = "java:/jms/queue/Questionary";
...
Destination destination = (Destination) namingContext.lookup(REMOTE_QUEUE_LOOKUP);
Once we have the destination, we can send a remote message. Here's a sample:
String USER_NAME = "my-user";
String USER_PASSWORD = "my-pass";
...
String question = "how many components in your family?";
String response = "they are four";
// Create the JMS context
JMSContext context = connectionFactory.createContext(USER_NAME, USER_PASSWORD);
Questionary questionary = new Questionary();
questionary.setQuestion(question);
questionary.setResponse(response);
JMSProducer producer = context.createProducer();
producer.send(destination, questionary);
In this example, we started the JMSContext through the connection factory, passing a user and a password. WildFly provides a default authentication for the remote client through the application-users.properties and application-roles.properties, seen in the earlier chapters, so ensure that you create an application user and a role beforehand.
The default realm used is the ApplicationRealm, which can be showed in our standalone-full.xml file:
<security-realm name="ApplicationRealm">
<server-identities>
<ssl>
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
</ssl>
</server-identities>
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
The ApplicationRealm sets the default property files where we find the users and the roles sited in the jboss.server.config.dir, a variable representing the configuration/standalone folder of WildFly.
The application.keystore is used to encrypt the password inside the file. Here's a sample of application users.properties with the MD5 encrypted password my-pass:
my-user=e0aa5b3d064f986c004d4db12e84334c
By default, JMS accepts the guest role. This is how the application roles.properties file should be to authorize the my-user user: my-user=guest.
This client has sent an object message represented, in this case, by the Questionary class. To use object messages, you can simply write a serializable class and send it through the JMSProducer component. Let's examine a sample of Questionary:
public class Questionary implements Serializable {
private static final long serialVersionUID = 7097408487111792846L;
private String question;
private String response;
private boolean approved;
...
}
To execute the client as a standalone application, simply add this code to your pom.xml maven descriptor file:
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-client-all</artifactId>
<version>10.1.0.Final</version>
</dependency>
This is the default library that WildFly provides for the local and remote clients, and it contains all the client utilities to interact with the enterprise components.