[jboss-cvs] JBossAS SVN: r83186 - branches/Branch_4_2/naming/src/main/org/jnp/interfaces.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Jan 21 20:24:11 EST 2009


Author: scott.stark at jboss.org
Date: 2009-01-21 20:24:11 -0500 (Wed, 21 Jan 2009)
New Revision: 83186

Modified:
   branches/Branch_4_2/naming/src/main/org/jnp/interfaces/NamingContext.java
Log:
JBAS-6390, JBPAPP-1522 add support for IPv6 address strings in the provider url

Modified: branches/Branch_4_2/naming/src/main/org/jnp/interfaces/NamingContext.java
===================================================================
--- branches/Branch_4_2/naming/src/main/org/jnp/interfaces/NamingContext.java	2009-01-22 01:22:42 UTC (rev 83185)
+++ branches/Branch_4_2/naming/src/main/org/jnp/interfaces/NamingContext.java	2009-01-22 01:24:11 UTC (rev 83186)
@@ -36,6 +36,9 @@
 import java.rmi.MarshalledObject;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -44,11 +47,14 @@
 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;
 import javax.naming.ConfigurationException;
 import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
 import javax.naming.InitialContext;
 import javax.naming.InvalidNameException;
 import javax.naming.LinkRef;
@@ -142,6 +148,14 @@
     * will be made.
     */ 
    public static final String JNP_MAX_RETRIES = "jnp.maxRetries";
+   /**
+    * The Naming instance to use for the root Context creation
+    */ 
+   public static final String JNP_NAMING_INSTANCE = "jnp.namingInstance";
+   /**
+    * The name to associate with Naming instance to use for the root Context
+    */ 
+   public static final String JNP_NAMING_INSTANCE_NAME = "jnp.namingInstanceName";
 
    /**
     * The default discovery multicast information
@@ -160,9 +174,8 @@
    private static Logger log = Logger.getLogger(NamingContext.class);
 
    // Static --------------------------------------------------------
-   
-   public static Hashtable haServers = new Hashtable();
-
+   /** HAJNDI keyed by partition name */
+   private static Hashtable<String, Naming> haServers = new Hashtable<String, Naming>();
    public static void setHANamingServerForPartition(String partitionName, Naming haServer)
    {
       haServers.put(partitionName, haServer);
@@ -178,7 +191,15 @@
       return (Naming) haServers.get(partitionName);
    }
 
+   /**
+    * The jvm local server used for non-transport access to the naming
+    * server
+    * @see #checkRef(Hashtable)
+    * @see {@linkplain LocalOnlyContextFactory}
+    */
    public static Naming localServer;
+   private static int HOST_INDEX = 0;
+   private static int PORT_INDEX = 1;
 
    // Attributes ----------------------------------------------------
    Naming naming;
@@ -195,14 +216,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);
       }
    }
 
@@ -210,8 +247,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)
       {
@@ -220,7 +257,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;
          }
       }
@@ -245,7 +282,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;
          }
@@ -258,20 +295,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)
       {
-         NamingException ex = new CommunicationException("Failed to retrieve stub from server " + hostKey);
+         if(log.isTraceEnabled())
+            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)
       {
-         NamingException ex = new CommunicationException("Failed to connect to server " + hostKey);
+         if(log.isTraceEnabled())
+            log.trace("Failed to connect server " + key, e);
+         NamingException ex = new CommunicationException("Failed to connect to server " + key);
          ex.setRootCause(e);
          throw ex;
       }
@@ -339,28 +380,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)
@@ -440,6 +470,10 @@
       return serverInfo;
    }
 
+   public static Naming getLocal()
+   {
+      return localServer;
+   }
    public static void setLocal(Naming server)
    {
       localServer = server;
@@ -504,8 +538,7 @@
          {
             if( obj != null )
                className = obj.getClass().getName();
-            // Normal object - serialize using a MarshalledValuePair
-            obj = new MarshalledValuePair(obj);
+            obj = createMarshalledValuePair(obj);
          }
          else
          {
@@ -517,7 +550,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -525,7 +558,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -576,9 +609,9 @@
          {
             if( obj != null )
                className = obj.getClass().getName();
-            
+
             // Normal object - serialize using a MarshalledValuePair
-            obj = new MarshalledValuePair(obj);
+            obj = createMarshalledValuePair(obj);
          }
          else
          {
@@ -592,7 +625,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -600,7 +633,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -668,7 +701,7 @@
                }
                catch (RemoteException re)
                {
-                  // Check for JBAS-4615.
+                  // Check for JBAS-4574.
                   if (handleStaleNamingStub(re, refEnv))
                   {
                      // try again with new naming stub                  
@@ -676,7 +709,7 @@
                   }
                   else
                   {
-                     // Not JBAS-4615. Throw exception and let outer logic handle it.
+                     // Not JBAS-4574. Throw exception and let outer logic handle it.
                      throw re;
                   }
                }
@@ -813,7 +846,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -821,7 +854,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }             
          }
@@ -879,7 +912,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -887,7 +920,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -935,7 +968,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -943,7 +976,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -1058,7 +1091,7 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
+            // Check for JBAS-4574.
             if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
@@ -1066,7 +1099,7 @@
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -1123,13 +1156,18 @@
    public void destroySubcontext(String name)
       throws NamingException
    {
-      throw new OperationNotSupportedException();
+      destroySubcontext(getNameParser(name).parse(name));
    }
 
    public void destroySubcontext(Name name)
       throws NamingException
    {
-      throw new OperationNotSupportedException();
+      if (!list(name).hasMore())
+      {
+         unbind(name);
+      }
+      else
+         throw new ContextNotEmptyException();
    }
 
    public Object lookupLink(String name)
@@ -1147,6 +1185,12 @@
    public Object lookupLink(Name name)
       throws NamingException
    {
+      Hashtable refEnv = getEnv(name);
+      checkRef(refEnv);
+      Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
+      if (parsedName != null)
+         name = parsedName;
+
       if (name.isEmpty())
          return lookup(name);
 
@@ -1160,16 +1204,15 @@
          }
          catch (RemoteException re)
          {
-            // Check for JBAS-4615.
-            // TODO if we resolve JBAS-4616, need to use refEnv
-            if (handleStaleNamingStub(re, env))
+            // Check for JBAS-4574.
+            if (handleStaleNamingStub(re, refEnv))
             {
                // try again with new naming stub                  
                link = naming.lookup(n);
             }
             else
             {
-               // Not JBAS-4615. Throw exception and let outer logic handle it.
+               // Not JBAS-4574. Throw exception and let outer logic handle it.
                throw re;
             }            
          }
@@ -1180,7 +1223,7 @@
       catch (IOException e)
       {
          naming = null;
-         removeServer(env);
+         removeServer(refEnv);
          NamingException ex = new CommunicationException();
          ex.setRootCause(e);
          throw ex;
@@ -1222,6 +1265,47 @@
    // Private -------------------------------------------------------
 
    /**
+    * Isolate the creation of the MarshalledValuePair in a privileged block
+    * when running under a security manager so the following permissions can
+    * be isolated from the caller:
+    * RuntimePermission("createClassLoader")
+      ReflectPermission("suppressAccessChecks")
+      SerializablePermission("enableSubstitution")
+      @return the MarshalledValuePair wrapping obj
+    */
+   private Object createMarshalledValuePair(final Object obj)
+      throws IOException
+   {
+      MarshalledValuePair mvp = null;
+      SecurityManager sm = System.getSecurityManager();
+      if(sm != null)
+      {
+         try
+         {
+            mvp = AccessController.doPrivileged(new PrivilegedExceptionAction<MarshalledValuePair>()
+            {
+               public MarshalledValuePair run() throws Exception
+               {
+                  return new MarshalledValuePair(obj);
+               }
+            }
+            );
+         }
+         catch(PrivilegedActionException e)
+         {
+            IOException ioe = new IOException();
+            ioe.initCause(e.getException());
+            throw ioe;
+         }
+      }
+      else
+      {
+         mvp = new MarshalledValuePair(obj);
+      }
+      return mvp;
+   }
+
+   /**
     * Determine the form of the name to pass to the NamingManager operations.
     * This is supposed to be a context relative name according to the javaodcs
     * for NamingManager, but historically the absolute name of the target
@@ -1339,16 +1423,16 @@
          String group = DEFAULT_DISCOVERY_GROUP_ADDRESS;
          int port = DEFAULT_DISCOVERY_GROUP_PORT;
          int timeout = DEFAULT_DISCOVERY_TIMEOUT;
-
          int ttl = 16;
 
+         String discoveryGroup = (String) serverEnv.get(JNP_DISCOVERY_GROUP);
+         if (discoveryGroup != null)
+            group = discoveryGroup;
+
          String discoveryTTL = (String) serverEnv.get(JNP_DISCOVERY_TTL);
          if(discoveryTTL != null)
             ttl = Integer.parseInt(discoveryTTL);
 
-         String discoveryGroup = (String) serverEnv.get(JNP_DISCOVERY_GROUP);
-         if (discoveryGroup != null)
-            group = discoveryGroup;
          String discoveryTimeout = (String) serverEnv.get(JNP_DISCOVERY_TIMEOUT);
          if (discoveryTimeout == null)
          {
@@ -1449,11 +1533,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;
@@ -1510,23 +1595,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
@@ -1601,6 +1674,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
    {
@@ -1628,7 +1743,7 @@
    }
    
    /**
-    * JBAS-4615. Check if the given exception is because the server has 
+    * JBAS-4574. Check if the given exception is because the server has 
     * been restarted while the cached naming stub hasn't been dgc-ed yet. 
     * If yes, we will flush out the naming stub from our cache and
     * acquire a new stub. BW.
@@ -1640,7 +1755,7 @@
     *         naming stub and we were able to succesfully flush the
     *         cache and acquire a new stub; <code>false</code> otherwise.
     */
-   private boolean handleStaleNamingStub(RemoteException e, Hashtable refEnv)
+   private boolean handleStaleNamingStub(Exception e, Hashtable refEnv)
    {
       if (e instanceof NoSuchObjectException
             || e.getCause() instanceof NoSuchObjectException)
@@ -1649,8 +1764,8 @@
          {
             if( log.isTraceEnabled() )
             {
-               log.trace("Call failed with recoverable RMI failure, " +
-                         "flushing server cache and reaquiring Naming ref", e);
+               log.trace("Call failed with NoSuchObjectException, " +
+                         "flushing server cache and retrying", e);
             }
             naming = null;
             removeServer(refEnv);




More information about the jboss-cvs-commits mailing list