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;
}
@Override
public String getProtocol()
{
return "spdy/2";
}
@Override
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 String getProtocol();
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.SocketChannel;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -57,6 +59,7 @@ import org.eclipse.jetty.util.thread.ThreadPool;
public class SPDYClient
{
private final Map<String, AsyncConnectionFactory> factories = new ConcurrentHashMap<>();
private final Factory factory;
private SocketAddress bindAddress;
private long maxIdleTime;
@ -113,15 +116,39 @@ public class SPDYClient
this.maxIdleTime = maxIdleTime;
}
protected AsyncConnectionFactory selectAsyncConnectionFactory(List<String> serverProtocols)
protected String selectProtocol(List<String> serverProtocols)
{
if (serverProtocols == null)
return new ClientSPDY2AsyncConnectionFactory();
return "spdy/2";
// TODO: for each server protocol, lookup a connection factory in SPDYClient.Factory;
// TODO: if that's null, lookup a connection factory in SPDYClient; if that's null, return null.
for (String serverProtocol : serverProtocols)
{
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)
@ -135,6 +162,7 @@ public class SPDYClient
public static class Factory extends AggregateLifeCycle
{
private final Map<String, AsyncConnectionFactory> factories = new ConcurrentHashMap<>();
private final ThreadPool threadPool;
private final SslContextFactory sslContextFactory;
private final SelectorManager selector;
@ -167,6 +195,8 @@ public class SPDYClient
selector = new ClientSelectorManager();
addBean(selector);
factories.put("spdy/2", new ClientSPDY2AsyncConnectionFactory());
}
public SPDYClient newSPDYClient()
@ -179,6 +209,19 @@ public class SPDYClient
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
{
@Override
@ -243,14 +286,15 @@ public class SPDYClient
@Override
public String selectProtocol(List<String> protocols)
{
AsyncConnectionFactory connectionFactory = client.selectAsyncConnectionFactory(protocols);
if (connectionFactory == null)
String protocol = client.selectProtocol(protocols);
if (protocol == null)
return null;
AsyncConnectionFactory connectionFactory = client.getAsyncConnectionFactory(protocol);
AsyncConnection connection = connectionFactory.newAsyncConnection(channel, sslEndPoint, attachment);
sslEndPoint.setConnection(connection);
return connectionFactory.getProtocol();
return protocol;
}
});
@ -356,12 +400,6 @@ public class SPDYClient
private static class ClientSPDY2AsyncConnectionFactory implements AsyncConnectionFactory
{
@Override
public String getProtocol()
{
return "spdy/2";
}
@Override
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.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Map;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
@ -34,7 +35,8 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
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;
public SPDYServerConnector(ServerSessionFrameListener listener)
@ -47,13 +49,41 @@ public class SPDYServerConnector extends SelectChannelConnector
this.sslContextFactory = sslContextFactory;
if (sslContextFactory != null)
addBean(sslContextFactory);
if (listener != null)
addAsyncConnectionFactory(new ServerSPDY2AsyncConnectionFactory(listener));
putAsyncConnectionFactory("spdy/2", 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
@ -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)
{
String peerHost = channel.socket().getInetAddress().getHostAddress();

View File

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