[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