[jboss-cvs] JBossAS SVN: r83134 - in projects/naming/trunk/jnpserver/src: main/java/org/jnp/server and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Jan 21 01:33:37 EST 2009


Author: scott.stark at jboss.org
Date: 2009-01-21 01:33:36 -0500 (Wed, 21 Jan 2009)
New Revision: 83134

Added:
   projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/IPv6UnitTest.java
Modified:
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/Main.java
Log:
JBAS-6390, JBNAME-25, IPv6 support

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java	2009-01-21 05:40:16 UTC (rev 83133)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java	2009-01-21 06:33:36 UTC (rev 83134)
@@ -24,16 +24,15 @@
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.io.SerializablePermission;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.ReflectPermission;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
 import java.net.Socket;
 import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
 import java.rmi.ConnectException;
 import java.rmi.MarshalledObject;
 import java.rmi.NoSuchObjectException;
@@ -45,10 +44,11 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
 import javax.naming.Binding;
 import javax.naming.CannotProceedException;
 import javax.naming.CommunicationException;
@@ -176,7 +176,7 @@
 
    // Static --------------------------------------------------------
    /** HAJNDI keyed by partition name */
-   private static Hashtable haServers = new Hashtable();
+   private static Hashtable<String, Naming> haServers = new Hashtable<String, Naming>();
    private static RuntimePermission GET_HA_NAMING_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.getHANamingServerForPartition");
    private static RuntimePermission SET_HA_NAMING_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.setHANamingServerForPartition");
    public static void setHANamingServerForPartition(String partitionName, Naming haServer)
@@ -212,6 +212,8 @@
    private static Naming localServer;
    private static RuntimePermission GET_LOCAL_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.getLocal");
    private static RuntimePermission SET_LOCAL_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.setLocal");
+   private static int HOST_INDEX = 0;
+   private static int PORT_INDEX = 1;
 
    // Attributes ----------------------------------------------------
    Naming naming;
@@ -228,14 +230,30 @@
    // calls, which will improve performance.
    // Weak references are used so if no contexts use a particular server
    // it will be removed from the cache.
-   static HashMap cachedServers = new HashMap();
+   static ConcurrentHashMap<InetSocketAddress, WeakReference<Naming>> cachedServers
+      = new ConcurrentHashMap<InetSocketAddress, WeakReference<Naming>>();
 
+   /**
+    * @deprecated use {@link #addServer(InetSocketAddress, Naming)}
+    * @param name
+    * @param server
+    */
    static void addServer(String name, Naming server)
    {
+      Object[] hostAndPort = {name, 0};
+      parseHostPort(name, hostAndPort, 0);
+      String host = (String) hostAndPort[HOST_INDEX];
+      Integer port = (Integer) hostAndPort[PORT_INDEX];
+      InetSocketAddress addr = new InetSocketAddress(host, port);
+      addServer(addr, server);
+   }
+   static void addServer(InetSocketAddress addr, Naming server)
+   {
       // Add server to map
       synchronized (NamingContext.class)
       {
-         cachedServers.put(name, new WeakReference(server));
+         WeakReference<Naming> ref = new WeakReference<Naming>(server);
+         cachedServers.put(addr, ref);
       }
    }
 
@@ -243,8 +261,8 @@
       throws NamingException
    {
       // Check the server cache for a host:port entry
-      String hostKey = host + ":" + port;
-      WeakReference ref = (WeakReference) cachedServers.get(hostKey);
+      InetSocketAddress key = new InetSocketAddress(host, port);
+      WeakReference<Naming> ref = cachedServers.get(key);
       Naming server;
       if (ref != null)
       {
@@ -253,7 +271,7 @@
          {
             // JBAS-4622. Ensure the env for the request has the
             // hostKey so we can remove the cache entry if there is a failure
-            serverEnv.put("hostKey", hostKey);
+            serverEnv.put("hostKey", key);
             return server;
          }
       }
@@ -278,7 +296,7 @@
          }
          catch (IOException e)
          {
-            NamingException ex = new ServiceUnavailableException("Failed to connect to server " + hostKey);
+            NamingException ex = new ServiceUnavailableException("Failed to connect to server " + key);
             ex.setRootCause(e);
             throw ex;
          }
@@ -291,24 +309,24 @@
          s.close();
 
          // Add it to cache
-         addServer(hostKey, server);
-         serverEnv.put("hostKey", hostKey);
+         addServer(key, server);
+         serverEnv.put("hostKey", key);
 
          return server;
       }
       catch (IOException e)
       {
          if(log.isTraceEnabled())
-            log.trace("Failed to retrieve stub from server " + hostKey, e);
-         NamingException ex = new CommunicationException("Failed to retrieve stub from server " + hostKey);
+            log.trace("Failed to retrieve stub from server " + key, e);
+         NamingException ex = new CommunicationException("Failed to retrieve stub from server " + key);
          ex.setRootCause(e);
          throw ex;
       }
       catch (Exception e)
       {
          if(log.isTraceEnabled())
-            log.trace("Failed to connect server " + hostKey, e);
-         NamingException ex = new CommunicationException("Failed to connect to server " + hostKey);
+            log.trace("Failed to connect server " + key, e);
+         NamingException ex = new CommunicationException("Failed to connect to server " + key);
          ex.setRootCause(e);
          throw ex;
       }
@@ -376,28 +394,17 @@
                String server = parseNameForScheme(urlAsName, null);
                if (server != null)
                   url = server;
-               int colon = url.indexOf(':');
-               if (colon < 0)
-               {
-                  host = url.trim();
-               }
-               else
-               {
-                  host = url.substring(0, colon).trim();
-                  try
-                  {
-                     port = Integer.parseInt(url.substring(colon + 1).trim());
-                  }
-                  catch (Exception ex)
-                  {
-                     // Use default;
-                  }
-               }
+               
+               Object[] hostAndPort = {url, 1099};
+               parseHostPort(url, hostAndPort, 1099);
+               host = (String) hostAndPort[HOST_INDEX];
+               port = (Integer) hostAndPort[PORT_INDEX];
 
                // Remove server from map
                synchronized (NamingContext.class)
                {
-                  cachedServers.remove(host + ":" + port);
+                  InetSocketAddress key = new InetSocketAddress(host, port);
+                  cachedServers.remove(key);
                }
             }
             catch (NamingException ignored)
@@ -1614,11 +1621,12 @@
          String serverHost;
          int serverPort;
 
-         int colon = myServer.indexOf(':');
-         if (colon >= 0)
+         Object[] hostAndPort = {myServer, 0};
+         parseHostPort(myServer, hostAndPort, DEFAULT_DISCOVERY_GROUP_PORT);
+         serverHost = (String) hostAndPort[HOST_INDEX];
+         serverPort = (Integer) hostAndPort[PORT_INDEX];
+         if (serverHost != null)
          {
-            serverHost = myServer.substring(0, colon);
-            serverPort = Integer.valueOf(myServer.substring(colon + 1)).intValue();
             server = getServer(serverHost, serverPort, serverEnv);
          }
          return server;
@@ -1675,23 +1683,11 @@
                String server = parseNameForScheme(urlAsName, null);
                if (server != null)
                   url = server;
-               int colon = url.indexOf(':');
-               if (colon < 0)
-               {
-                  host = url;
-               }
-               else
-               {
-                  host = url.substring(0, colon).trim();
-                  try
-                  {
-                     port = Integer.parseInt(url.substring(colon + 1).trim());
-                  }
-                  catch (Exception ex)
-                  {
-                     // Use default;
-                  }
-               }
+               // 
+               Object[] hostAndPort = {url, 0};
+               parseHostPort(url, hostAndPort, 1099);
+               host = (String) hostAndPort[HOST_INDEX];
+               port = (Integer) hostAndPort[PORT_INDEX];
                try
                {
                   // Get server from cache
@@ -1766,6 +1762,48 @@
       }
    }
 
+   /**
+    * Parse a naming provider url for the host/port information
+    * @param url - the naming provider url string to parse
+    * @param output, [0] = the host name/address, [1] = the parsed port as an Integer
+    * @param defaultPort - the default port to return in output[1] if no port
+    * was seen in the url string.
+    * @return the index of the port separator if found, -1 otherwise.
+    */
+   static private int parseHostPort(String url, Object[] output, int defaultPort)
+   {
+      // First look for a @ separating the host and port
+      int colon = url.indexOf('@');
+      if(colon < 0)
+      {
+         // If there are multiple ':' assume its an IPv6 address
+         colon = url.lastIndexOf(':');
+         int firstColon = url.indexOf(':');
+         if(colon > firstColon)
+            colon = -1;
+      }
+
+      if(colon < 0)
+      {
+         output[HOST_INDEX] = url;
+         output[PORT_INDEX] = new Integer(defaultPort);
+      }
+      else
+      {
+         output[HOST_INDEX] = url.substring(0, colon);  
+         try
+         {
+            output[PORT_INDEX] = Integer.parseInt(url.substring(colon+1).trim());
+         }
+         catch (Exception ex)
+         {
+            // Use default port
+            output[PORT_INDEX] = new Integer(defaultPort);
+         }
+      }
+      return colon;
+   }
+
    private Name getAbsoluteName(Name n)
       throws NamingException
    {

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/Main.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/Main.java	2009-01-21 05:40:16 UTC (rev 83133)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/Main.java	2009-01-21 06:33:36 UTC (rev 83134)
@@ -35,6 +35,8 @@
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.rmi.server.UnicastRemoteObject;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
@@ -83,6 +85,7 @@
     * multi-homed hosts that want control over which interfaces accept
     * connections */
    protected InetAddress bindAddress;
+   protected List<InetAddress> bindAddresses;
    /** The interface to bind to for the Naming RMI server */ 
    protected InetAddress rmiBindAddress;
    /** Should the java.rmi.server.hostname property to rmiBindAddress */
@@ -235,6 +238,16 @@
          bindAddress = InetAddress.getByName(host);
    }
 
+   
+   public List<InetAddress> getBindAddresses()
+   {
+      return bindAddresses;
+   }
+   public void setBindAddresses(List<InetAddress> bindAddresses)
+   {
+      this.bindAddresses = bindAddresses;
+   }
+
    public String getRmiBindAddress()
    {
       String address = null;
@@ -436,38 +449,48 @@
          // Get the default ServerSocketFactory is one was not specified
          if( jnpServerSocketFactory == null )
             jnpServerSocketFactory = ServerSocketFactory.getDefault();
-         serverSocket = jnpServerSocketFactory.createServerSocket(port, backlog, bindAddress);
-         // If an anonymous port was specified get the actual port used
-         if( port == 0 )
-            port = serverSocket.getLocalPort();
-         String msg = "JNDI bootstrap JNP=" + bindAddress + ":" + port
-            + ", RMI=" + bindAddress + ":" + rmiPort
-            + ", backlog="+backlog;
+         List<InetAddress> addresses = bindAddresses;
+         if(addresses == null)
+            addresses = Collections.singletonList(bindAddress);
+         // Setup the exectuor with addresses + 1 threads
+         if( lookupExector == null  )
+         {
+            int count = addresses.size() + 1;
+            log.debug("Using default newFixedThreadPool("+count+")");
+            lookupExector = Executors.newFixedThreadPool(count, BootstrapThreadFactory.getInstance());
+         }
 
-          if (clientSocketFactory == null)
-            msg+= ", no client SocketFactory";
-          else
-            msg+= ", Client SocketFactory="+clientSocketFactory.toString();
+         for(InetAddress address : addresses)
+         {
+            serverSocket = jnpServerSocketFactory.createServerSocket(port, backlog, address);
+            // If an anonymous port was specified get the actual port used
+            if( port == 0 )
+               port = serverSocket.getLocalPort();
+            String msg = "JNDI bootstrap JNP=" + address + ":" + port
+               + ", RMI=" + address + ":" + rmiPort
+               + ", backlog="+backlog;
+   
+             if (clientSocketFactory == null)
+               msg+= ", no client SocketFactory";
+             else
+               msg+= ", Client SocketFactory="+clientSocketFactory.toString();
+   
+             if (serverSocketFactory == null)
+               msg+= ", no server SocketFactory";
+             else
+               msg+= ", Server SocketFactory="+serverSocketFactory.toString();
+   
+            log.debug(msg);
 
-          if (serverSocketFactory == null)
-            msg+= ", no server SocketFactory";
-          else
-            msg+= ", Server SocketFactory="+serverSocketFactory.toString();
-
-         log.debug(msg);
+            AcceptHandler handler = new AcceptHandler();
+            lookupExector.execute(handler);
+         }
       }
       catch (IOException e)
       {
          log.error("Could not start on port " + port, e);
       }
 
-      if( lookupExector == null  )
-      {
-         log.debug("Using default newFixedThreadPool(2)");
-         lookupExector = Executors.newFixedThreadPool(2, BootstrapThreadFactory.getInstance());
-      }
-      AcceptHandler handler = new AcceptHandler();
-      lookupExector.execute(handler);
    }
 
    /** 

Added: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/IPv6UnitTest.java
===================================================================
--- projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/IPv6UnitTest.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/IPv6UnitTest.java	2009-01-21 06:33:36 UTC (rev 83134)
@@ -0,0 +1,130 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.test;
+
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Properties;
+
+import javax.naming.Name;
+
+import junit.framework.Test;
+
+import org.jboss.test.BaseTestCase;
+import org.jnp.interfaces.Naming;
+import org.jnp.interfaces.NamingContext;
+import org.jnp.server.Main;
+import org.jnp.server.NamingBeanImpl;
+
+/**
+ * Tests of IPv6 addresses
+ * 
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 81238 $
+ */
+public class IPv6UnitTest extends BaseTestCase
+{
+   /** The actual namingMain service impl bean */
+   private static NamingBeanImpl namingBean;
+   /** */
+   private static Main namingMain = new Main("org.jnp.server");
+
+   static int serverPort;
+   public static Test suite()
+   {
+      return suite(IPv6UnitTest.class);
+   }
+   
+   public IPv6UnitTest(String name)
+   {
+      super(name);
+   }
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      if (namingBean != null)
+         return;
+
+      InetAddress localhost = InetAddress.getByName("localhost");
+      InetAddress localhostIPv6 = InetAddress.getByName("::ffff:127.0.0.1");
+
+      // Set the java.rmi.server.hostname to the bind address if not set
+      if(System.getProperty("java.rmi.server.hostname") == null)
+      {
+         log.debug("Set java.rmi.server.hostname to localhost");
+         System.setProperty("java.rmi.server.hostname", "localhost");
+      }
+      namingBean = new NamingBeanImpl();
+      namingBean.start();
+      namingMain.setPort(0);
+      namingMain.setBindAddress("localhost");
+      InetAddress[] addresses = {
+            localhost,
+            localhostIPv6,
+            };
+      namingMain.setBindAddresses(Arrays.asList(addresses));
+      namingMain.setNamingInfo(namingBean);
+      namingMain.start();
+      serverPort = namingMain.getPort();
+   }
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+   }
+
+   /**
+    * Access the naming instance over the ipv4 localhost address
+    * @throws Exception
+    */
+   public void testNamingContextIPv4Localhost()
+      throws Exception
+   {
+      Properties env = new Properties();
+      env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
+      env.setProperty("java.naming.provider.url", "localhost:"+serverPort);
+      env.setProperty("java.naming.factory.url", "org.jboss.naming:org.jnp.interfaces");
+      Name baseName = null;
+      Naming server = null;
+      NamingContext nc = new NamingContext(env, baseName, server);
+      nc.list("");
+   }
+   /**
+    * Access the naming instance over the ipv6 localhost address
+    * @throws Exception
+    */
+   public void testNamingContextIPv6Localhost()
+      throws Exception
+   {
+      Properties env = new Properties();
+      InetAddress localhost = InetAddress.getByName("localhost");
+      InetAddress localhostIPv6 = InetAddress.getByName("::ffff:"+localhost.getHostAddress());
+
+      env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
+      env.setProperty("java.naming.provider.url", localhostIPv6.getHostAddress()+"@"+serverPort);
+      env.setProperty("java.naming.factory.url", "org.jboss.naming:org.jnp.interfaces");
+      Name baseName = null;
+      Naming server = null;
+      NamingContext nc = new NamingContext(env, baseName, server);
+      nc.list("");
+   }
+}




More information about the jboss-cvs-commits mailing list