WildFly Naming Subsystem Configuration

From NovaOrdis Knowledge Base
Revision as of 18:22, 20 September 2017 by Ovidiu (talk | contribs) (→‎Importing an External JNDI Context)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Internal

Overview

The "naming" subsystem contains configuration related to various JNDI namespaces.

<subsystem xmlns="urn:jboss:domain:naming:1.4">
    <remote-naming/>
</subsystem>

Configuration

<remote-naming>

If present, this element activates the remote naming server, that allows access to items bound in the java:jboss/exported JNDI context. More details about the JBoss exported JNDI namespace and the remote naming server can be found here:

WildFly JNDI Concepts - Exporting for Access by Remote JNDI Clients

Importing an External JNDI Context

This section describes the configuration required to import an external JNDI context into the local JND namespace. The external JNDI context must be exported by a remote server. More details about external JNDI contexts are available here:

External JNDI Contexts

Provided that the remote JNDI objects have been bound into an externally exported context ("java:/jboss/export") by the remote server, they can be made available locally by declaring an "external-context" in the "naming" subsystem configuration of the local server:

<subsystem xmlns="urn:jboss:domain:naming:1.4">
  ...
  <bindings>
    <external-context name="java:global/remote-hornetq" 
                      module="org.jboss.remote-naming" 
                      class="javax.naming.InitialContext">
      <environment>
        <property name="java.naming.factory.initial" 
                  value="org.jboss.naming.remote.client.InitialContextFactory"/>
        <property name="java.naming.provider.url"
                  value="remote://${remote.node.one.address}:${remote.node.one.remoting.port},remote://${remote.node.two.address}:${remote.node.two.remoting.port}"/>
        <property name="java.naming.security.principal" 
                  value="${remoting.user.name}"/>
        <property name="java.naming.security.credentials" 
                  value="${remoting.password}"/>
      </environment>
    </external-context>
  </bindings>
</subsystem>

<external-context> name

The external-context's "name" is the local JNDI name to bind to. The external namespace will be accessible locally as an JNDI Context with that name. For details on how to programmatically access the external context, see the "Accessing the External JNDI Context" section below.

The name must be in the "java:global", "java:jboss" or "java:/" contexts. Anything else will trigger a configuration error.

System Properties

The system properties referred in the example can be declared in a <system-properties> block, as follows, and they have the following semantics:

<system-properties>
    <property name="remote.node.one.address" value="127.0.0.1"/>
    <property name="remote.node.one.remoting.port" value="4547"/>
    <property name="remote.node.two.address" value="127.0.0.1"/>
    <property name="remote.node.two.remoting.port" value="4647"/>
    <property name="remoting.user.name" value="some-remoting-user"/>
    <property name="remoting.password" value="some-remoting-password"/>
</system-properties>
  • "remote.node.one.address" the address of the first remote EAP node that exposes the external JNDI context.
  • "remote.node.one.remoting.port" the remoting port of the first remote EAP node. The default value is 4447 and if the node runs with an offset of 100, the value should be 4547.
  • "remote.node.two.address" the address of the second remote EAP node.
  • "remote.node.two.remoting.port" the remoting port of the second remote EAP node. The default value is 4447 and if the node runs with an offset of 200, the value should be 4647.
  • "remoting.user.name"/"remoting.password" the remoting credentials. Remoting can be configured to allow unauthenticated access as described here: "Disabling Remoting Authentication"

Accessing the External JNDI Context

The remote objects bound in the external JNDI context can be accessed locally as follows:

...
public static final String LOCAL_NAME_OF_THE_EXTERNAL_CONTEXT = "java:global/remote-hornetq";
public static final String DESTINATION_JNDI_NAME = "jms/queue/remote-playground";
...

InitialContext ic = new InitialContext();
Queue queue = (Queue)ic.lookup(LOCAL_NAME_OF_THE_EXTERNAL_CONTEXT + "/" + DESTINATION_JNDI_NAME);

Obviously, LOCAL_NAME_OF_THE_EXTERNAL_CONTEXT must contain the same value that was declared for the external-context name attribute.

If the component we're looking up from supports resource injection, an alternative is:

@Resource(lookup = "java:global/remote-hornetq")
private InitialContext externalContext;

...

Queue queue = (Queue)externalContext.lookup("jms/queue/remote-playground");

A working example that demonstrates both API styles is available here:

https://github.com/NovaOrdis/playground/tree/master/jboss/messaging/sending-and-receiving-from-remote-destinations

Alternatively, instead of exposing objects in the external context, they can be mapped to the local JNDI space using <lookup> constructs, as shown below.

<lookup>

A <lookup> configuration can be used to look up an object in JNDI and re-bind it under a different name.

<bindings>
    <lookup name="name-to-bind-to" lookup="name-to-look-up" />
</bindings>

where:

name is the JNDI name to bind to.

lookup is the JNDI location to look up.

Mapping External Context Objects Locally

<lookup> is particularly useful when we want to bind remotely exposed objects into the local namespace, as shown below:

<subsystem xmlns="urn:jboss:domain:naming:...">
    <bindings>
        <external-context name="java:global/remote-server-context" module="org.jboss.remote-naming" class="javax.naming.InitialContext">
             ...
        </external-context>
        <lookup name="java:/local-name-to-bind-to" lookup="java:global/remote-server-context/name/on/the/remote/server" />
    </bindings>
    ...
</subsystem>

<simple>

Binds a simple environment entry in JNDI at boot.

<bindings>
    <simple name="java:global/simple-global-int-example" value="10" type="java.lang.Integer"/>
</bindings>