Java Dynamic Management Kit 5.1 Tutorial

10.4.1 Registering the Connector Server with the JNDI/LDAP Lookup Service

The following code extracts are taken from the Server class in the Jini Lookup Service examples directory.


Example 10–9 Creating Connector Servers for Registration in the JNDI/LDAP Lookup Service

public class Server { 
   public final static int JMX_DEFAULT_LEASE = 60; 
   private static boolean debug = false; 
   private final MBeanServer mbs; 
   public Server() { 
      mbs = MBeanServerFactory.createMBeanServer(); 
   } 
 
  public static DirContext getRootContext() throws NamingException { 
      final Hashtable env = new Hashtable(); 
 
      final String factory = 
        System.getProperty(Context.INITIAL_CONTEXT_FACTORY, 
                           "com.sun.jndi.ldap.LdapCtxFactory"); 
      final String ldapServerUrl = 
        System.getProperty(Context.PROVIDER_URL); 
      final String ldapUser = 
        System.getProperty(Context.SECURITY_PRINCIPAL, 
                           "cn=Directory Manager"); 
      final String ldapPasswd = 
        System.getProperty(Context.SECURITY_CREDENTIALS); 
      debug(Context.PROVIDER_URL + "=" + ldapServerUrl); 
      debug(Context.SECURITY_PRINCIPAL + "=" + ldapUser); 
      if (debug) { 
                  System.out.print(Context.SECURITY_CREDENTIALS + "="); 
                  final int len = (ldapPasswd==null)?0:ldapPasswd.length(); 
                  for (int i=0;i
                  for (int i=0;i<len;i++) System.out.print("*"); 
                  System.out.println(); 
      } 
      env.put(Context.INITIAL_CONTEXT_FACTORY,factory); 
      env.put(Context.SECURITY_PRINCIPAL, ldapUser); 
      if (ldapServerUrl != null) 
           env.put(Context.PROVIDER_URL, ldapServerUrl); 
      if (ldapPasswd != null) 
           env.put(Context.SECURITY_CREDENTIALS, ldapPasswd); 
      InitialContext root = new InitialLdapContext(env,null); 
      return (DirContext)(root.lookup("")); 
  } 
   
[...] 

Example 10–9 shows the initial creation of an MBean server mbs, and the obtainment of a pointer to the root context of the LDAP directory tree in which the connector server address is to be registered. All the relevant LDAP access variables, such as the provider URL, the LDAP user name and the security credentials, are given here and passed into the environment map env. The environment map env is then passed as a parameter into a call to InitialLdapContext, from which the initial LDAP context is obtained.

Code that is not shown retrieves the agent name under which the connector will be registered in the LDAP server.


Example 10–10 Registering the Connector Server Address in the LDAP Registry

[...] 
 
public static void register(DirContext root, 
                           JMXServiceURL jmxUrl, 
                           String name) 
   throws NamingException, IOException { 
 
   final String mydn = System.getProperty("dn","cn="+name); 
 
   debug("dn: " + mydn ); 
 
   Object o = null; 
   try { 
       o = root.lookup(mydn); 
   } catch (NameNotFoundException n) { 
       Attributes attrs = new BasicAttributes(); 
       Attribute objclass = new BasicAttribute("objectClass"); 
       objclass.add("top"); 
       objclass.add("javaContainer"); 
       objclass.add("jmxConnector"); 
       attrs.put(objclass); 
       attrs.put("jmxAgentName", name); 
       o = root.createSubcontext(mydn,attrs); 
   } 
   if (o == null) throw new NameNotFoundException(); 
   final Attributes attrs = root.getAttributes(mydn); 
   final Attribute oc = attrs.get("objectClass"); 
   if (!oc.contains("jmxConnector")) { 
       final String msg = "The supplied node [" + mydn +  
         "] does not contain the jmxConnector objectclass"; 
       throw new NamingException(msg); 
   } 
    
   final Attributes newattrs = new BasicAttributes(); 
   newattrs.put("jmxAgentName",name); 
   newattrs.put("jmxServiceURL",jmxUrl.toString()); 
   newattrs.put("jmxAgentHost",InetAddress.getLocalHost().getHostName()); 
   newattrs.put("jmxProtocolType",jmxUrl.getProtocol()); 
   newattrs.put("jmxExpirationDate", 
                getExpirationDate(JMX_DEFAULT_LEASE)); 
   root.modifyAttributes(mydn,DirContext.REPLACE_ATTRIBUTE,newattrs); 
} 
 
[...] 

Example 10–10 shows the registration of the JMX connector server service URL in the LDAP directory. The domain name in which the URL is registered can be passed on the command line through the dn System property, namely, -Ddn=mydn. If the dn system property is not specified, then you can use cn=name, in which name is the agent name. This is not mandatory, however.

The location in which the URL is registered is not important, because the client code never uses that DN directly, but instead performs an LDAP search to find the nodes that have an auxiliary JMX connector ObjectClass. What is important however, is that each URL is registered in its own LDAP node. How to name these nodes is left to the LDAP administrator. In this example, it is assumed that you have configured your LDAP server by creating a root context under which the node cn=name can be created, and that this root context has been passed to the LDAP initial context through the Context.PROVIDER_URL property (see Example 10–9).

The code shown above checks whether the node in which you will register the server URL already exists. If it does not, you try to create it (this will fail if the parent node does not exist). Since the ObjectClass is a simple auxiliary class, you can use the javaContainer ObjectClass as structural class if you need to create a new context. Once again, this is optional.

Any structural class to which the jmxConnector auxiliary class can be added is acceptable. It then checks whether the node in which you will register the server already has the jmxConnector auxiliary class. Otherwise, an exception is thrown.

At this point you are sure that the node in which you will register the URL exists, and has the appropriate jmxConnector auxiliary class. So you need only to replace the values of the attributes defined by the LDAP schema for JMX, (see jmx-schema.txt):


Example 10–11 Registering the Connector Servers in the LDAP Server

[...] 
 
   public JMXConnectorServer rmi(String url) 
     throws IOException, JMException, 
        NamingException, ClassNotFoundException { 
 
     JMXServiceURL jurl = new JMXServiceURL(url); 
     final HashMap env = new HashMap(); 
     // Prepare the environment Map 
     
[...] 
 
     JMXConnectorServer rmis = 
        JMXConnectorServerFactory.newJMXConnectorServer(jurl, env, mbs); 
 
     final String agentName = System.getProperty("agent.name", 
                                                 "DefaultAgent"); 
     start(rmis,env,agentName); 
     return rmis; 
   } 
     
[...] 

In Example 10–11, a new RMI connector server named rmis is created with the JMX service URL jurl and the appropriate LDAP properties passed to its environment map env. The connector server rmis is launched by calling JMXConnectorServer.start() and is registered in the LDAP server.

Subsequent code not shown here creates and registers a corresponding JMXMP connector server named jmxmp.


Example 10–12 Creating the JMX Connector Server

[...] 
 
    public void start(JMXConnectorServer server, Map env, String agentName) 
       throws IOException, NamingException { 
       server.start(); 
       final DirContext root=getRootContext(); 
       final JMXServiceURL address = server.getAddress(); 
       register(root,address,agentName); 
    } 
     
[...] 

Example 10–12 shows the creation of a JMX connector server server, the obtainment of a pointer to the LDAP server root directory root and the creation of a URL for server named address. The root directory, the URL and an agent name are passed as parameters to register() and are registered in the LDAP server.