Date: 2005-01-23T15:15:01
   Editor: PhilSteitz
   Wiki: Apache Directory Project Wiki
   Page: NamingHome
   URL: http://wiki.apache.org/directory/NamingHome

   no comment

New Page:

= Current state =
The current code is focussed on supporting the java:comp/env namespace for web 
applications running inside a container. The Selector``Context and 
Context``Bindings classes enable multiple different naming contexts to be set 
up and bound to threads and classloaders.  In tomcat, where the code 
originated, JNDI resources can be configured "globally" or at the web app 
level.  Global naming resources are made available to individual web apps via 
resource links.

== Some details ==
 *The Context``Bindings class maintains hashtables linking external names with 
Naming``Context instances, as well as threads and classloaders. 
 *The javaURL``Context``Factory implements get``Initial``Context as follows: 
Check to see if the current thread or classloader is bound.  If so, return a 
new Selector``Context; otherwise return a shared, writable Naming``Context 
maintained in a static member.
 *The Selector``Context locates bound contexts and delegates JNDI operations to 
them. It uses its getBoundContext method to retrieve the appropriate context 
from Context``Bindings.  If the Selector``Context is created as an initial 
context and get``Bound``Context does not find a context bound to the calling 
thread/classloader, it creates a new Naming``Context and binds the caller to it.

= XML Configurator =
The Xml``Configurator was introduced to enable applications running outside of 
a J2EE container to load resource references and environment properties into a 
JNDI context.  The current setup loads just one "unbound" context, rooted by 
default at "java:comp/env."  Users can initialize contexts with different roots 
by supplying a value for the name attribute of the context element in the 
config file.  The javaURL``Context``Factory is used by the Xml``Configurator, 
so by default it creates a shared, global, writable context.
A basic use case is to allow code that makes use of tomcat-managed JNDI to run 
outside of tomcat.  Modifying the configurator dtd and initialization to 
support global resources and resource links will do this, but only for a single 
"global" context, which makes the whole concept less meaningful.

= Proposal to clean up the current setup and to support federation and links 
across contexts =
 *Extend the Xml``Configurator to support (multiple) named contexts and modify 
Naming``Context``Factory and javaURL``Context``Factory to look for context 
names in the environment and either create new named contexts with these names 
or return the named context from Context``Bindings.  For backward 
compatibility, map the empty name to a shared, writable context rooted at 
"java:comp/env."
 *Add a "base" element to the context element to play the role that the name 
element is now playing -- i.e., to specify the root name relative to which all 
of the child entries are named.  I see no need for nested context elements, 
since subcontexts are created implicitly based on the names of context child 
elements.
 *Per Roland's suggestion, add a "link" context child element which will insert 
a link to another named context, with links resolved using {{{(new 
InitialContext(env)).lookup(link)}}} as Naming``Context does now, but with the 
name of the other context included in env. Then  global naming resources" can 
be made available using a context named "global" or "root" or whatever the user 
likes.
 *Also per Roland's suggestion, either create a server.xml + web.xml -> naming 
config converter or support these config formats directly.

Then to support federation:

 *Allow urls as "base" names in Xml``Configurator context elements and add a 
"factory" attribute to allow the context factory to be specified/overridden.  
Then contexts backed by directory servers can be named and accessed via 
Context``Bindings as above and links can be inserted in in-memory contexts to 
enable federation between in-memory and ldap-backed naming contexts.  Note that 
this will work for contexts set up using the apis directly, as long as they 
include the names of external contexts in links. The implicit names used by 
tomcat so tomcat's global naming resources links will continue to work. 

== Examples ==

=== Single, global in-memory namespace, rooted at "java:comp/env."  No 
difference from current config or behavior ===
{{{<naming>
  <context>
    <environment name="config/host" value="www.apache.org" 
type="java.lang.String" />
    <resource name="jdbc/pool" type="javax.sql.DataSource">
      <parameter>
        <name>driverClassName</name>
        <value>org.hsqldb.jdbcDriver</value>
      </parameter>
      <parameter>
        <name>url</name>
        <value>jdbc:hsqldb:target/hsqldb</value>
      </parameter>
      <parameter>
        <name>username</name>
        <value>sa</value>
      </parameter>
      <parameter>
        <name>password</name>
        <value></value>
      </parameter>
    </resource>
  </context>
</naming>

Context ctx = new InitialContext();
Context env = (Context) ctx.lookup("java:comp/env);
String host = (String) env.lookup("config/host");
DataSource ds = (DataSource) env.lookup("jdbc/pool");}}}

=== Multiple in-memory contexts, with links ===
{{{<naming>
  <context name="global">
    <resource name="jdbc/pool" type="javax.sql.DataSource">
      <parameter>
        <name>driverClassName</name>
        <value>org.hsqldb.jdbcDriver</value>
      </parameter>
      <parameter>
        <name>url</name>
        <value>jdbc:hsqldb:target/hsqldb</value>
      </parameter>
      <parameter>
        <name>username</name>
        <value>sa</value>
      </parameter>
      <parameter>
        <name>password</name>
        <value></value>
      </parameter>
    </resource>
  </context>
  <context name="app1" base="java:comp/env">
    <environment name="port" value="5555" type="java.lang.Integer" />
    <link name="datasource" context="global" rname="jdbc/pool" />
  </context> 
</naming>

Hashtable env = new Hashtable();
env.put(NamingContext.NAME, "app1");
Context ctx = new InitialContext(env);
Context env = (Context) ctx.lookup("java:comp/env);
Integer port = (Integer) env.lookup("port");
DataSource ds = (DataSource) env.lookup("datasource"); //follows link}}}

=== Links to remote ldap-backed context inserted into default global in-memory 
context ===
{{{<naming>
  <context name="persistent" url="ldap://ldap.foo.com:389"; />
  <context>
     ...
    <link name="config/host" context="persistent" rname="config/host" />
    <link name="config" context="persistent" rname="config" />
  </context> 
</naming>

Context ctx = new InitialContext();
Context env = (Context) ctx.lookup("java:comp/env);
String host = (String) env.lookup("config/host");}}}
or even

{{{DirContext dirContext = (DirContext) ctx.lookup("config");}}}

More challenging would be to support

{{{Integer port = (Integer) env.lookup("config/port");}}} 

without creating the link explicitly.  This would require that the Name``Parser 
become aware of the links, as opposed to inserting them statically.






Reply via email to