From d7389a2ec07dad1eb6aab45de4729e2965b4fef2 Mon Sep 17 00:00:00 2001 From: Simon Stewart Date: Tue, 7 Jan 2020 18:40:02 +0000 Subject: [PATCH] [grid] Abstract SessionMap creation away to the options This makes it possible to use the RedisSessionMap if that's what we want to do. --- .../grid/commands/DefaultHubConfig.java | 10 ++-- .../commands/DefaultStandaloneConfig.java | 6 +- .../distributor/httpd/DistributorServer.java | 2 +- .../grid/router/httpd/RouterServer.java | 2 +- .../grid/sessionmap/config/BUILD.bazel | 1 - .../sessionmap/config/SessionMapOptions.java | 60 +++++++++++++------ .../grid/sessionmap/httpd/BUILD.bazel | 1 + .../httpd/DefaultSessionMapConfig.java | 8 ++- .../sessionmap/httpd/SessionMapServer.java | 4 +- .../grid/sessionmap/local/BUILD.bazel | 3 + .../sessionmap/local/LocalSessionMap.java | 10 ++++ .../grid/sessionmap/remote/BUILD.bazel | 4 ++ .../sessionmap/remote/RemoteSessionMap.java | 19 ++++++ 13 files changed, 100 insertions(+), 30 deletions(-) diff --git a/java/server/src/org/openqa/selenium/grid/commands/DefaultHubConfig.java b/java/server/src/org/openqa/selenium/grid/commands/DefaultHubConfig.java index 71c6dc7a4ab2a..90b84af3007bd 100644 --- a/java/server/src/org/openqa/selenium/grid/commands/DefaultHubConfig.java +++ b/java/server/src/org/openqa/selenium/grid/commands/DefaultHubConfig.java @@ -25,9 +25,11 @@ class DefaultHubConfig extends MapConfig { DefaultHubConfig() { super(ImmutableMap.of( - "events", ImmutableMap.of( - "publish", "tcp://*:4442", - "subscribe", "tcp://*:4443", - "bind", true))); + "events", ImmutableMap.of( + "publish", "tcp://*:4442", + "subscribe", "tcp://*:4443", + "bind", true), + "sessions", ImmutableMap.of( + "implementation", "org.openqa.selenium.grid.sessionmap.local.LocalSessionMap"))); } } diff --git a/java/server/src/org/openqa/selenium/grid/commands/DefaultStandaloneConfig.java b/java/server/src/org/openqa/selenium/grid/commands/DefaultStandaloneConfig.java index 55eb985507d90..d3b9dc33b67a9 100644 --- a/java/server/src/org/openqa/selenium/grid/commands/DefaultStandaloneConfig.java +++ b/java/server/src/org/openqa/selenium/grid/commands/DefaultStandaloneConfig.java @@ -25,8 +25,10 @@ class DefaultStandaloneConfig extends MapConfig { DefaultStandaloneConfig() { super(ImmutableMap.of( - "events", ImmutableMap.of( - "implementation", "org.openqa.selenium.events.local.GuavaEventBus"))); + "events", ImmutableMap.of( + "implementation", "org.openqa.selenium.events.local.GuavaEventBus"), + "sessions", ImmutableMap.of( + "implementation", "org.openqa.selenium.grid.sessionmap.local.LocalSessionMap"))); } } diff --git a/java/server/src/org/openqa/selenium/grid/distributor/httpd/DistributorServer.java b/java/server/src/org/openqa/selenium/grid/distributor/httpd/DistributorServer.java index 5ba162d46c955..61051f3ab427f 100644 --- a/java/server/src/org/openqa/selenium/grid/distributor/httpd/DistributorServer.java +++ b/java/server/src/org/openqa/selenium/grid/distributor/httpd/DistributorServer.java @@ -112,7 +112,7 @@ public Executable configure(String... args) { NetworkOptions networkOptions = new NetworkOptions(config); HttpClient.Factory clientFactory = networkOptions.getHttpClientFactory(); - SessionMap sessions = new SessionMapOptions(config).getSessionMap(tracer, clientFactory); + SessionMap sessions = new SessionMapOptions(config).getSessionMap(); Distributor distributor = new LocalDistributor( tracer, diff --git a/java/server/src/org/openqa/selenium/grid/router/httpd/RouterServer.java b/java/server/src/org/openqa/selenium/grid/router/httpd/RouterServer.java index 27d1d8ecb3327..3c24295403814 100644 --- a/java/server/src/org/openqa/selenium/grid/router/httpd/RouterServer.java +++ b/java/server/src/org/openqa/selenium/grid/router/httpd/RouterServer.java @@ -106,7 +106,7 @@ public Executable configure(String... args) { HttpClient.Factory clientFactory = networkOptions.getHttpClientFactory(); SessionMapOptions sessionsOptions = new SessionMapOptions(config); - SessionMap sessions = sessionsOptions.getSessionMap(tracer, clientFactory); + SessionMap sessions = sessionsOptions.getSessionMap(); BaseServerOptions serverOptions = new BaseServerOptions(config); diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel b/java/server/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel index 9df2ddb20e3fa..8e29578231e46 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/config/BUILD.bazel @@ -10,7 +10,6 @@ java_library( "//java/client/src/org/openqa/selenium/remote/http", "//java/server/src/org/openqa/selenium/grid/config", "//java/server/src/org/openqa/selenium/grid/sessionmap", - "//java/server/src/org/openqa/selenium/grid/sessionmap/remote", artifact("com.beust:jcommander"), artifact("io.opentracing:opentracing-api"), ], diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/config/SessionMapOptions.java b/java/server/src/org/openqa/selenium/grid/sessionmap/config/SessionMapOptions.java index b065a6821a0e7..77ce82b057101 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/config/SessionMapOptions.java +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/config/SessionMapOptions.java @@ -17,35 +17,32 @@ package org.openqa.selenium.grid.sessionmap.config; -import io.opentracing.Tracer; import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.config.ConfigException; import org.openqa.selenium.grid.sessionmap.SessionMap; -import org.openqa.selenium.grid.sessionmap.remote.RemoteSessionMap; -import org.openqa.selenium.remote.http.HttpClient; -import java.net.MalformedURLException; -import java.net.URL; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Optional; +import java.util.logging.Logger; public class SessionMapOptions { + private static final Logger LOG = Logger.getLogger(SessionMapOptions.class.getName()); + private static final String DEFAULT_SESSION_MAP = "org.openqa.selenium.grid.sessionmap.remote.RemoteSessionMap"; private final Config config; public SessionMapOptions(Config config) { this.config = config; } - public SessionMap getSessionMap(Tracer tracer, HttpClient.Factory clientFactory) { - HttpClient client = clientFactory.createClient(getSessionMapUrl()); - return new RemoteSessionMap(tracer, client); - } - - private URL getSessionMapUrl() { - Optional host = config.get("sessions", "host").map(str -> { + public URI getSessionMapUri() { + Optional host = config.get("sessions", "host").map(str -> { try { - return new URL(str); - } catch (MalformedURLException e) { + return new URI(str); + } catch (URISyntaxException e) { throw new ConfigException("Session map server URI is not a valid URI: " + str); } }); @@ -62,16 +59,45 @@ private URL getSessionMapUrl() { } try { - return new URL( + return new URI( "http", + null, hostname.get(), port.get(), - ""); - } catch (MalformedURLException e) { + "", + null, + null); + } catch (URISyntaxException e) { throw new ConfigException( "Session map server uri configured through host (%s) and port (%d) is not a valid URI", hostname.get(), port.get()); } } + + public SessionMap getSessionMap() { + String clazz = config.get("sessions", "implementation").orElse(DEFAULT_SESSION_MAP); + LOG.info("Creating event bus: " + clazz); + try { + Class busClazz = Class.forName(clazz); + Method create = busClazz.getMethod("create", Config.class); + + if (!Modifier.isStatic(create.getModifiers())) { + throw new IllegalArgumentException(String.format( + "Session map class %s's `create(Config)` method must be static", clazz)); + } + + if (!SessionMap.class.isAssignableFrom(create.getReturnType())) { + throw new IllegalArgumentException(String.format( + "Session map class %s's `create(Config)` method must return a SessionMap", clazz)); + } + + return (SessionMap) create.invoke(null, config); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(String.format( + "Session map class %s must have a static `create(Config)` method", clazz)); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException("Unable to find event bus class: " + clazz, e); + } + } } diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel index 83a5e4bbd8e97..549219931bb12 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/BUILD.bazel @@ -15,6 +15,7 @@ java_library( "//java/server/src/org/openqa/selenium/grid/log", "//java/server/src/org/openqa/selenium/grid/server", "//java/server/src/org/openqa/selenium/grid/sessionmap", + "//java/server/src/org/openqa/selenium/grid/sessionmap/config", "//java/server/src/org/openqa/selenium/grid/sessionmap/local", "//java/server/src/org/openqa/selenium/grid/web", "//java/server/src/org/openqa/selenium/netty/server", diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/DefaultSessionMapConfig.java b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/DefaultSessionMapConfig.java index f423f0345129a..b2bfb5b434eae 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/DefaultSessionMapConfig.java +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/DefaultSessionMapConfig.java @@ -25,8 +25,10 @@ class DefaultSessionMapConfig extends MapConfig { public DefaultSessionMapConfig() { super(ImmutableMap.of( - "events", ImmutableMap.of( - "publish", "tcp://*:4442", - "subscribe", "tcp://*:4443"))); + "events", ImmutableMap.of( + "publish", "tcp://*:4442", + "subscribe", "tcp://*:4443"), + "sessions", ImmutableMap.of( + "implementation", "org.openqa.selenium.grid.sessionmap.local.LocalSessionMap"))); } } diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/SessionMapServer.java b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/SessionMapServer.java index 9f613f4ed0ab9..3bd35b2c92fd4 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/SessionMapServer.java +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/httpd/SessionMapServer.java @@ -39,6 +39,7 @@ import org.openqa.selenium.grid.server.HelpFlags; import org.openqa.selenium.grid.server.Server; import org.openqa.selenium.grid.sessionmap.SessionMap; +import org.openqa.selenium.grid.sessionmap.config.SessionMapOptions; import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap; import org.openqa.selenium.netty.server.NettyServer; import org.openqa.selenium.remote.http.Contents; @@ -106,7 +107,8 @@ public Executable configure(String... args) { EventBusOptions events = new EventBusOptions(config); EventBus bus = events.getEventBus(); - SessionMap sessions = new LocalSessionMap(tracer, bus); + SessionMapOptions sessionMapOptions = new SessionMapOptions(config); + SessionMap sessions = sessionMapOptions.getSessionMap(); BaseServerOptions serverOptions = new BaseServerOptions(config); diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel b/java/server/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel index c5d8752288ff6..945b25de66319 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/local/BUILD.bazel @@ -9,7 +9,10 @@ java_library( deps = [ "//java/client/src/org/openqa/selenium/remote", "//java/server/src/org/openqa/selenium/events", + "//java/server/src/org/openqa/selenium/grid/config", "//java/server/src/org/openqa/selenium/grid/data", + "//java/server/src/org/openqa/selenium/grid/log", + "//java/server/src/org/openqa/selenium/grid/server", "//java/server/src/org/openqa/selenium/grid/sessionmap", ], ) diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java b/java/server/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java index 4944f34add5d1..0f98c0453026c 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/local/LocalSessionMap.java @@ -20,7 +20,10 @@ import io.opentracing.Tracer; import org.openqa.selenium.NoSuchSessionException; import org.openqa.selenium.events.EventBus; +import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.data.Session; +import org.openqa.selenium.grid.log.LoggingOptions; +import org.openqa.selenium.grid.server.EventBusOptions; import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.remote.SessionId; @@ -50,6 +53,13 @@ public LocalSessionMap(Tracer tracer, EventBus bus) { }); } + public static SessionMap create(Config config) { + Tracer tracer = new LoggingOptions(config).getTracer(); + EventBus bus = new EventBusOptions(config).getEventBus(); + + return new LocalSessionMap(tracer, bus); + } + @Override public boolean add(Session session) { Objects.requireNonNull(session, "Session has not been set"); diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel b/java/server/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel index 9ce1d58ee59d2..4a43caaf5449a 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/remote/BUILD.bazel @@ -8,8 +8,12 @@ java_library( deps = [ "//java/client/src/org/openqa/selenium/json", "//java/client/src/org/openqa/selenium/remote", + "//java/server/src/org/openqa/selenium/grid/config", "//java/server/src/org/openqa/selenium/grid/data", + "//java/server/src/org/openqa/selenium/grid/log", "//java/server/src/org/openqa/selenium/grid/sessionmap", + "//java/server/src/org/openqa/selenium/grid/sessionmap/config", + "//java/server/src/org/openqa/selenium/grid/server", "//java/server/src/org/openqa/selenium/grid/web", ], ) diff --git a/java/server/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java b/java/server/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java index 903eeb9e8b0e6..312221a342aed 100644 --- a/java/server/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java +++ b/java/server/src/org/openqa/selenium/grid/sessionmap/remote/RemoteSessionMap.java @@ -20,8 +20,12 @@ import io.opentracing.Span; import io.opentracing.Tracer; import org.openqa.selenium.NoSuchSessionException; +import org.openqa.selenium.grid.config.Config; import org.openqa.selenium.grid.data.Session; +import org.openqa.selenium.grid.log.LoggingOptions; +import org.openqa.selenium.grid.server.NetworkOptions; import org.openqa.selenium.grid.sessionmap.SessionMap; +import org.openqa.selenium.grid.sessionmap.config.SessionMapOptions; import org.openqa.selenium.grid.web.Values; import org.openqa.selenium.json.Json; import org.openqa.selenium.remote.SessionId; @@ -30,7 +34,10 @@ import org.openqa.selenium.remote.http.HttpResponse; import org.openqa.selenium.remote.tracing.HttpTracing; +import java.io.UncheckedIOException; import java.lang.reflect.Type; +import java.net.MalformedURLException; +import java.net.URI; import java.util.Objects; import static org.openqa.selenium.remote.http.Contents.utf8String; @@ -49,6 +56,18 @@ public RemoteSessionMap(Tracer tracer, HttpClient client) { this.client = Objects.requireNonNull(client); } + public static SessionMap create(Config config) { + Tracer tracer = new LoggingOptions(config).getTracer(); + URI uri = new SessionMapOptions(config).getSessionMapUri(); + HttpClient.Factory clientFactory = new NetworkOptions(config).getHttpClientFactory(); + + try { + return new RemoteSessionMap(tracer, clientFactory.createClient(uri.toURL())); + } catch (MalformedURLException e) { + throw new UncheckedIOException(e); + } + } + @Override public boolean add(Session session) { Objects.requireNonNull(session, "Session must be set");