Refactored mapping of AsyncConnectionFactories with protocol names.

This commit is contained in:
Simone Bordet 2012-02-07 16:16:09 +01:00
parent d21ce5599a
commit cf5db008de
5 changed files with 89 additions and 47 deletions

View File

@ -44,12 +44,6 @@ public class ServerSPDY2AsyncConnectionFactory implements AsyncConnectionFactory
this.listener = listener; this.listener = listener;
} }
@Override
public String getProtocol()
{
return "spdy/2";
}
@Override @Override
public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment) public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment)
{ {

View File

@ -23,7 +23,5 @@ import org.eclipse.jetty.io.nio.AsyncConnection;
public interface AsyncConnectionFactory public interface AsyncConnectionFactory
{ {
public String getProtocol();
public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment); public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment);
} }

View File

@ -27,6 +27,8 @@ import java.net.SocketAddress;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -57,6 +59,7 @@ import org.eclipse.jetty.util.thread.ThreadPool;
public class SPDYClient public class SPDYClient
{ {
private final Map<String, AsyncConnectionFactory> factories = new ConcurrentHashMap<>();
private final Factory factory; private final Factory factory;
private SocketAddress bindAddress; private SocketAddress bindAddress;
private long maxIdleTime; private long maxIdleTime;
@ -113,15 +116,39 @@ public class SPDYClient
this.maxIdleTime = maxIdleTime; this.maxIdleTime = maxIdleTime;
} }
protected AsyncConnectionFactory selectAsyncConnectionFactory(List<String> serverProtocols) protected String selectProtocol(List<String> serverProtocols)
{ {
if (serverProtocols == null) if (serverProtocols == null)
return new ClientSPDY2AsyncConnectionFactory(); return "spdy/2";
// TODO: for each server protocol, lookup a connection factory in SPDYClient.Factory; for (String serverProtocol : serverProtocols)
// TODO: if that's null, lookup a connection factory in SPDYClient; if that's null, return null. {
for (String protocol : factories.keySet())
{
if (serverProtocol.equals(protocol))
return protocol;
}
String protocol = factory.selectProtocol(serverProtocols);
if (protocol != null)
return protocol;
}
return new ClientSPDY2AsyncConnectionFactory(); return null;
}
protected AsyncConnectionFactory getAsyncConnectionFactory(String protocol)
{
for (Map.Entry<String, AsyncConnectionFactory> entry : factories.entrySet())
{
if (protocol.equals(entry.getKey()))
return entry.getValue();
}
for (Map.Entry<String, AsyncConnectionFactory> entry : factory.factories.entrySet())
{
if (protocol.equals(entry.getKey()))
return entry.getValue();
}
return null;
} }
protected SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel) protected SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel)
@ -135,6 +162,7 @@ public class SPDYClient
public static class Factory extends AggregateLifeCycle public static class Factory extends AggregateLifeCycle
{ {
private final Map<String, AsyncConnectionFactory> factories = new ConcurrentHashMap<>();
private final ThreadPool threadPool; private final ThreadPool threadPool;
private final SslContextFactory sslContextFactory; private final SslContextFactory sslContextFactory;
private final SelectorManager selector; private final SelectorManager selector;
@ -167,6 +195,8 @@ public class SPDYClient
selector = new ClientSelectorManager(); selector = new ClientSelectorManager();
addBean(selector); addBean(selector);
factories.put("spdy/2", new ClientSPDY2AsyncConnectionFactory());
} }
public SPDYClient newSPDYClient() public SPDYClient newSPDYClient()
@ -179,6 +209,19 @@ public class SPDYClient
threadPool.join(); threadPool.join();
} }
protected String selectProtocol(List<String> serverProtocols)
{
for (String serverProtocol : serverProtocols)
{
for (String protocol : factories.keySet())
{
if (serverProtocol.equals(protocol))
return protocol;
}
}
return null;
}
private class ClientSelectorManager extends SelectorManager private class ClientSelectorManager extends SelectorManager
{ {
@Override @Override
@ -243,14 +286,15 @@ public class SPDYClient
@Override @Override
public String selectProtocol(List<String> protocols) public String selectProtocol(List<String> protocols)
{ {
AsyncConnectionFactory connectionFactory = client.selectAsyncConnectionFactory(protocols); String protocol = client.selectProtocol(protocols);
if (connectionFactory == null) if (protocol == null)
return null; return null;
AsyncConnectionFactory connectionFactory = client.getAsyncConnectionFactory(protocol);
AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachment); AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachment);
sslEndPoint.setConnection(connection); sslEndPoint.setConnection(connection);
return connectionFactory.getProtocol(); return protocol;
} }
}); });
@ -356,12 +400,6 @@ public class SPDYClient
private static class ClientSPDY2AsyncConnectionFactory implements AsyncConnectionFactory private static class ClientSPDY2AsyncConnectionFactory implements AsyncConnectionFactory
{ {
@Override
public String getProtocol()
{
return "spdy/2";
}
@Override @Override
public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment) public AsyncConnection newAsyncConnection(SocketChannel channel, AsyncEndPoint endPoint, Object attachment)
{ {

View File

@ -18,8 +18,9 @@ package org.eclipse.jetty.spdy.nio;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.Map;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
@ -34,7 +35,8 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SPDYServerConnector extends SelectChannelConnector public class SPDYServerConnector extends SelectChannelConnector
{ {
private final List<AsyncConnectionFactory> factories = new CopyOnWriteArrayList<>(); // Order is important on server side, so we use a LinkedHashMap
private final Map<String, AsyncConnectionFactory> factories = new LinkedHashMap<>();
private final SslContextFactory sslContextFactory; private final SslContextFactory sslContextFactory;
public SPDYServerConnector(ServerSessionFrameListener listener) public SPDYServerConnector(ServerSessionFrameListener listener)
@ -47,13 +49,41 @@ public class SPDYServerConnector extends SelectChannelConnector
this.sslContextFactory = sslContextFactory; this.sslContextFactory = sslContextFactory;
if (sslContextFactory != null) if (sslContextFactory != null)
addBean(sslContextFactory); addBean(sslContextFactory);
if (listener != null) putAsyncConnectionFactory("spdy/2", new ServerSPDY2AsyncConnectionFactory(listener));
addAsyncConnectionFactory(new ServerSPDY2AsyncConnectionFactory(listener));
} }
public void addAsyncConnectionFactory(AsyncConnectionFactory factory) public AsyncConnectionFactory putAsyncConnectionFactory(String protocol, AsyncConnectionFactory factory)
{ {
factories.add(factory); synchronized (factories)
{
return factories.put(protocol, factory);
}
}
public AsyncConnectionFactory getAsyncConnectionFactory(String protocol)
{
final Map<String, AsyncConnectionFactory> copy = new LinkedHashMap<>();
synchronized (factories)
{
copy.putAll(factories);
}
return copy.get(protocol);
}
public Map<String, AsyncConnectionFactory> getAsyncConnectionFactories()
{
synchronized (factories)
{
return new LinkedHashMap<>(factories);
}
}
protected List<String> provideProtocols()
{
synchronized (factories)
{
return new ArrayList<>(factories.keySet());
}
} }
@Override @Override
@ -99,24 +129,6 @@ public class SPDYServerConnector extends SelectChannelConnector
} }
} }
protected List<String> provideProtocols()
{
List<String> result = new ArrayList<>();
for (AsyncConnectionFactory factory : factories)
result.add(factory.getProtocol());
return result;
}
protected AsyncConnectionFactory getAsyncConnectionFactory(String protocol)
{
for (AsyncConnectionFactory factory : factories)
{
if (factory.getProtocol().equals(protocol))
return factory;
}
return null;
}
protected SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel) protected SSLEngine newSSLEngine(SslContextFactory sslContextFactory, SocketChannel channel)
{ {
String peerHost = channel.socket().getInetAddress().getHostAddress(); String peerHost = channel.socket().getInetAddress().getHostAddress();

View File

@ -51,7 +51,7 @@ public class HTTPOverSPDYTest
server = new Server(); server = new Server();
connector = new SPDYServerConnector(null); connector = new SPDYServerConnector(null);
server.addConnector(connector); server.addConnector(connector);
connector.addAsyncConnectionFactory(new ServerHTTP11OverSPDY2AsyncConnectionFactory(connector)); connector.putAsyncConnectionFactory("spdy/2", new ServerHTTP11OverSPDY2AsyncConnectionFactory(connector));
server.setHandler(handler); server.setHandler(handler);
server.start(); server.start();