From cf5db008ded7451ff4cf0c66809a115c84aa86c9 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 7 Feb 2012 16:16:09 +0100 Subject: [PATCH] Refactored mapping of AsyncConnectionFactories with protocol names. --- .../ServerSPDY2AsyncConnectionFactory.java | 6 -- .../spdy/nio/AsyncConnectionFactory.java | 2 - .../eclipse/jetty/spdy/nio/SPDYClient.java | 66 +++++++++++++++---- .../jetty/spdy/nio/SPDYServerConnector.java | 60 ++++++++++------- .../jetty/spdy/nio/http/HTTPOverSPDYTest.java | 2 +- 5 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/eclipse/jetty/spdy/ServerSPDY2AsyncConnectionFactory.java b/src/main/java/org/eclipse/jetty/spdy/ServerSPDY2AsyncConnectionFactory.java index f3340f50fff..37b45818a34 100644 --- a/src/main/java/org/eclipse/jetty/spdy/ServerSPDY2AsyncConnectionFactory.java +++ b/src/main/java/org/eclipse/jetty/spdy/ServerSPDY2AsyncConnectionFactory.java @@ -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) { diff --git a/src/main/java/org/eclipse/jetty/spdy/nio/AsyncConnectionFactory.java b/src/main/java/org/eclipse/jetty/spdy/nio/AsyncConnectionFactory.java index fcc42d22b2e..68220b3badc 100644 --- a/src/main/java/org/eclipse/jetty/spdy/nio/AsyncConnectionFactory.java +++ b/src/main/java/org/eclipse/jetty/spdy/nio/AsyncConnectionFactory.java @@ -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); } diff --git a/src/main/java/org/eclipse/jetty/spdy/nio/SPDYClient.java b/src/main/java/org/eclipse/jetty/spdy/nio/SPDYClient.java index 5b8ad3542f5..a14e06d4e5c 100644 --- a/src/main/java/org/eclipse/jetty/spdy/nio/SPDYClient.java +++ b/src/main/java/org/eclipse/jetty/spdy/nio/SPDYClient.java @@ -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 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 serverProtocols) + protected String selectProtocol(List 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 entry : factories.entrySet()) + { + if (protocol.equals(entry.getKey())) + return entry.getValue(); + } + for (Map.Entry 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 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 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 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) { diff --git a/src/main/java/org/eclipse/jetty/spdy/nio/SPDYServerConnector.java b/src/main/java/org/eclipse/jetty/spdy/nio/SPDYServerConnector.java index 23c77eee088..1f69c73b4b4 100644 --- a/src/main/java/org/eclipse/jetty/spdy/nio/SPDYServerConnector.java +++ b/src/main/java/org/eclipse/jetty/spdy/nio/SPDYServerConnector.java @@ -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 factories = new CopyOnWriteArrayList<>(); + // Order is important on server side, so we use a LinkedHashMap + private final Map 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 copy = new LinkedHashMap<>(); + synchronized (factories) + { + copy.putAll(factories); + } + return copy.get(protocol); + } + + public Map getAsyncConnectionFactories() + { + synchronized (factories) + { + return new LinkedHashMap<>(factories); + } + } + + protected List provideProtocols() + { + synchronized (factories) + { + return new ArrayList<>(factories.keySet()); + } } @Override @@ -99,24 +129,6 @@ public class SPDYServerConnector extends SelectChannelConnector } } - protected List provideProtocols() - { - List 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(); diff --git a/src/test/java/org/eclipse/jetty/spdy/nio/http/HTTPOverSPDYTest.java b/src/test/java/org/eclipse/jetty/spdy/nio/http/HTTPOverSPDYTest.java index ed09cda5d79..a47d836b66f 100644 --- a/src/test/java/org/eclipse/jetty/spdy/nio/http/HTTPOverSPDYTest.java +++ b/src/test/java/org/eclipse/jetty/spdy/nio/http/HTTPOverSPDYTest.java @@ -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();