diff --git a/java/server/src/org/openqa/selenium/grid/commands/Hub.java b/java/server/src/org/openqa/selenium/grid/commands/Hub.java index 0985824d9abbf..15e0cb81a2a43 100644 --- a/java/server/src/org/openqa/selenium/grid/commands/Hub.java +++ b/java/server/src/org/openqa/selenium/grid/commands/Hub.java @@ -40,6 +40,7 @@ import org.openqa.selenium.grid.server.W3CCommandHandler; import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap; +import org.openqa.selenium.grid.web.Routes; @AutoService(CliCommand.class) public class Hub implements CliCommand { @@ -91,7 +92,7 @@ public Executable configure(String... args) { Router router = new Router(sessions, distributor); Server server = new BaseServer<>(new BaseServerOptions(config)); - server.addHandler(router, (inj, req) -> new W3CCommandHandler(router)); + server.addRoute(Routes.matching(router).using(router).decorateWith(W3CCommandHandler.class)); server.start(); }; } diff --git a/java/server/src/org/openqa/selenium/grid/commands/Standalone.java b/java/server/src/org/openqa/selenium/grid/commands/Standalone.java index c964f322d2bc5..26d3e4471a2c8 100644 --- a/java/server/src/org/openqa/selenium/grid/commands/Standalone.java +++ b/java/server/src/org/openqa/selenium/grid/commands/Standalone.java @@ -42,6 +42,7 @@ import org.openqa.selenium.grid.server.W3CCommandHandler; import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.net.NetworkUtils; import java.net.URI; @@ -119,7 +120,7 @@ public Executable configure(String... args) { distributor.add(node.build()); Server server = new BaseServer<>(new BaseServerOptions(config)); - server.addHandler(router, (inj, req) -> new W3CCommandHandler(router)); + server.addRoute(Routes.matching(router).using(router).decorateWith(W3CCommandHandler.class)); server.start(); }; } 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 230811b58b89a..08889e57507ad 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 @@ -36,6 +36,7 @@ import org.openqa.selenium.grid.server.HelpFlags; import org.openqa.selenium.grid.server.Server; import org.openqa.selenium.grid.server.W3CCommandHandler; +import org.openqa.selenium.grid.web.Routes; @AutoService(CliCommand.class) public class DistributorServer implements CliCommand { @@ -86,7 +87,10 @@ public Executable configure(String... args) { BaseServerOptions serverOptions = new BaseServerOptions(config); Server server = new BaseServer<>(serverOptions); - server.addHandler(distributor, (inj, req) -> new W3CCommandHandler(distributor)); + server.addRoute( + Routes.matching(distributor) + .using(distributor) + .decorateWith(W3CCommandHandler.class)); server.start(); }; } diff --git a/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java b/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java index 3a1c02b1cf2f1..6820824090268 100644 --- a/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java +++ b/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java @@ -43,6 +43,7 @@ import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.grid.sessionmap.SessionMapOptions; import org.openqa.selenium.grid.sessionmap.remote.RemoteSessionMap; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.remote.http.HttpClient; import java.net.URL; @@ -116,7 +117,7 @@ public Executable configure(String... args) { HttpClient.Factory.createDefault().createClient(distributorUrl)); Server server = new BaseServer<>(serverOptions); - server.addHandler(node, (inj, req) -> new W3CCommandHandler(node)); + server.addRoute(Routes.matching(node).using(node).decorateWith(W3CCommandHandler.class)); server.start(); Regularly regularly = new Regularly( 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 875b7d6c6476e..c857c5b153b7a 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 @@ -42,6 +42,7 @@ import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.grid.sessionmap.SessionMapOptions; import org.openqa.selenium.grid.sessionmap.remote.RemoteSessionMap; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.remote.http.HttpClient; import java.net.URL; @@ -108,7 +109,7 @@ public Executable configure(String... args) { Router router = new Router(sessions, distributor); Server server = new BaseServer<>(serverOptions); - server.addHandler(router, (inj, req) -> new W3CCommandHandler(router)); + server.addRoute(Routes.matching(router).using(router).decorateWith(W3CCommandHandler.class)); server.start(); }; } diff --git a/java/server/src/org/openqa/selenium/grid/server/BaseServer.java b/java/server/src/org/openqa/selenium/grid/server/BaseServer.java index c7a829479c9e6..af5dcfe514b53 100644 --- a/java/server/src/org/openqa/selenium/grid/server/BaseServer.java +++ b/java/server/src/org/openqa/selenium/grid/server/BaseServer.java @@ -20,14 +20,13 @@ import static java.net.HttpURLConnection.HTTP_OK; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.concurrent.TimeUnit.SECONDS; -import static org.openqa.selenium.grid.server.Server.get; import com.google.common.collect.ImmutableMap; import com.google.common.net.MediaType; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.grid.web.CommandHandler; -import org.openqa.selenium.grid.web.CompoundHandler; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.injector.Injector; import org.openqa.selenium.json.Json; import org.openqa.selenium.net.NetworkUtils; @@ -48,7 +47,9 @@ import java.net.BindException; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.BiFunction; @@ -65,6 +66,7 @@ public class BaseServer implements Server { private final org.seleniumhq.jetty9.server.Server server; private final Map, BiFunction> handlers; + private final List routes = new ArrayList<>(); private final ServletContextHandler servletContextHandler; private final Injector injector; private final URL url; @@ -97,7 +99,8 @@ public BaseServer(BaseServerOptions options) { .register(json) .build(); - addHandler(get("/status"), (injector, req) -> + addRoute( + Routes.get("/status").using( (in, out) -> { String value = json.toJson(ImmutableMap.of( "value", ImmutableMap.of( @@ -109,7 +112,7 @@ public BaseServer(BaseServerOptions options) { out.setStatus(HTTP_OK); out.setContent(value.getBytes(UTF_8)); - }); + }).build()); this.servletContextHandler = new ServletContextHandler(ServletContextHandler.SECURITY); ConstraintSecurityHandler @@ -170,13 +173,12 @@ public void addServlet(Servlet servlet, String pathSpec) { } @Override - public void addHandler( - Predicate selector, - BiFunction handler) { + public void addRoute(Routes route) { if (server.isRunning()) { throw new IllegalStateException("You may not add a handler to a running server"); } - handlers.put(Objects.requireNonNull(selector), Objects.requireNonNull(handler)); + + this.routes.add(route); } public boolean isStarted() { @@ -186,9 +188,16 @@ public boolean isStarted() { @Override public T start() { try { - CommandHandler delegate = new CompoundHandler(injector, handlers); - W3CCommandHandler handler = new W3CCommandHandler(delegate); - addServlet(new CommandHandlerServlet(handler), "/*"); + // If there are no routes, we've done something terribly wrong. + if (routes.isEmpty()) { + throw new IllegalStateException("There must be at least one route specified"); + } + Routes first = routes.remove(0); + Routes routes = Routes.combine(first, this.routes.toArray(new Routes[0])) + .decorateWith(W3CCommandHandler.class) + .build(); + + addServlet(new CommandHandlerServlet(routes), "/*"); server.start(); diff --git a/java/server/src/org/openqa/selenium/grid/server/CommandHandlerServlet.java b/java/server/src/org/openqa/selenium/grid/server/CommandHandlerServlet.java index 8bd7d0f0d9690..d77496c497693 100644 --- a/java/server/src/org/openqa/selenium/grid/server/CommandHandlerServlet.java +++ b/java/server/src/org/openqa/selenium/grid/server/CommandHandlerServlet.java @@ -17,12 +17,19 @@ package org.openqa.selenium.grid.server; +import static org.openqa.selenium.grid.web.Routes.combine; + +import org.openqa.selenium.UnsupportedCommandException; import org.openqa.selenium.grid.web.CommandHandler; +import org.openqa.selenium.grid.web.Routes; +import org.openqa.selenium.injector.Injector; +import org.openqa.selenium.json.Json; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; import java.io.IOException; import java.util.Objects; +import java.util.Optional; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -30,10 +37,19 @@ class CommandHandlerServlet extends HttpServlet { - private final CommandHandler handler; + private final Routes routes; + private final Injector injector; - public CommandHandlerServlet(CommandHandler handler) { - this.handler = Objects.requireNonNull(handler); + public CommandHandlerServlet(Routes routes) { + Objects.requireNonNull(routes); + this.routes = combine(routes) + .fallbackTo( + new W3CCommandHandler( + (req, res) -> { + throw new UnsupportedCommandException(String.format( + "Unknown command: (%s) %s", req.getMethod(), req.getUri())); + })).build(); + this.injector = Injector.builder().register(new Json()).build(); } @Override @@ -42,6 +58,11 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws HttpRequest request = new ServletRequestWrappingHttpRequest(req); HttpResponse response = new ServletResponseWrappingHttpResponse(resp); - handler.execute(request, response); + Optional possibleMatch = routes.match(injector, request); + if (possibleMatch.isPresent()) { + possibleMatch.get().execute(request, response); + } else { + throw new IllegalStateException("It should not be possible to get here"); + } } } diff --git a/java/server/src/org/openqa/selenium/grid/server/Server.java b/java/server/src/org/openqa/selenium/grid/server/Server.java index 715c1eb59139f..2c4fac377c19b 100644 --- a/java/server/src/org/openqa/selenium/grid/server/Server.java +++ b/java/server/src/org/openqa/selenium/grid/server/Server.java @@ -17,22 +17,13 @@ package org.openqa.selenium.grid.server; -import static org.openqa.selenium.remote.http.HttpMethod.DELETE; -import static org.openqa.selenium.remote.http.HttpMethod.GET; -import static org.openqa.selenium.remote.http.HttpMethod.POST; - import org.openqa.selenium.grid.component.HasLifecycle; import org.openqa.selenium.grid.web.CommandHandler; -import org.openqa.selenium.grid.web.UrlTemplate; -import org.openqa.selenium.injector.Injector; -import org.openqa.selenium.remote.SessionId; -import org.openqa.selenium.remote.http.HttpMethod; -import org.openqa.selenium.remote.http.HttpRequest; +import org.openqa.selenium.grid.web.Route; +import org.openqa.selenium.grid.web.Routes; import java.net.URL; import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Predicate; import javax.servlet.Servlet; @@ -56,47 +47,12 @@ public interface Server extends HasLifecycle { @Deprecated void addServlet(Servlet servlet, String pathSpec); - void addHandler( - Predicate selector, - BiFunction handler); - - URL getUrl(); - - default void addHandler( - HttpMethod method, - String urlTemplate, - BiFunction handler) { - Objects.requireNonNull(method, "Method must be set"); - - UrlTemplate template = new UrlTemplate(urlTemplate); + void addRoute(Routes route); - addHandler( - req -> method == req.getMethod() && template.match(req.getUri()) != null, - (inj, req) -> { - UrlTemplate.Match match = template.match(req.getUri()); - if (match != null && match.getParameters().get("sessionId") != null) { - inj = Injector.builder() - .parent(inj) - .register(new SessionId(match.getParameters().get("sessionId"))) - .build(); - } - return handler.apply(inj, req); - } - ); + default void addRoute(Route route) { + Objects.requireNonNull(route, "Route must not be null"); + addRoute(route.build()); } - static Predicate delete(String template) { - UrlTemplate urlTemplate = new UrlTemplate(template); - return req -> DELETE == req.getMethod() && urlTemplate.match(req.getUri()) != null; - } - - static Predicate get(String template) { - UrlTemplate urlTemplate = new UrlTemplate(template); - return req -> GET == req.getMethod() && urlTemplate.match(req.getUri()) != null; - } - - static Predicate post(String template) { - UrlTemplate urlTemplate = new UrlTemplate(template); - return req -> POST == req.getMethod() && urlTemplate.match(req.getUri()) != null; - } + URL getUrl(); } 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 22ce872ea1dc3..c213b83fbc4ff 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 @@ -17,6 +17,8 @@ package org.openqa.selenium.grid.sessionmap.httpd; +import static org.openqa.selenium.grid.web.Routes.matching; + import com.google.auto.service.AutoService; import com.beust.jcommander.JCommander; @@ -36,6 +38,7 @@ import org.openqa.selenium.grid.server.W3CCommandHandler; import org.openqa.selenium.grid.sessionmap.SessionMap; import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap; +import org.openqa.selenium.grid.web.Routes; @AutoService(CliCommand.class) public class SessionMapServer implements CliCommand { @@ -86,7 +89,7 @@ public Executable configure(String... args) { BaseServerOptions serverOptions = new BaseServerOptions(config); Server server = new BaseServer<>(serverOptions); - server.addHandler(sessions, (inj, req) -> new W3CCommandHandler(sessions)); + server.addRoute(matching(sessions).using(sessions).decorateWith(W3CCommandHandler.class)); server.start(); }; } diff --git a/java/server/src/org/openqa/selenium/grid/web/CompoundHandler.java b/java/server/src/org/openqa/selenium/grid/web/CompoundHandler.java deleted file mode 100644 index 67044e5e446e7..0000000000000 --- a/java/server/src/org/openqa/selenium/grid/web/CompoundHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package org.openqa.selenium.grid.web; - -import com.google.common.collect.ImmutableMap; - -import org.openqa.selenium.UnsupportedCommandException; -import org.openqa.selenium.injector.Injector; -import org.openqa.selenium.remote.http.HttpRequest; -import org.openqa.selenium.remote.http.HttpResponse; - -import java.io.IOException; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Map; -import java.util.Objects; -import java.util.function.BiFunction; -import java.util.function.Predicate; - -/** - * Presents a collection of {@link CommandHandler}s as a single unit. Should there be more than one - * handler that responds to a given {@link HttpRequest}, then the last one returned from the - * underlying {@link Map}'s key set will be returned (that is, if the map preserves insertion order - * the last inserted handler will be returned). This means that handlers added later take precedence - * over handlers added first, allowing them to be overridden. - */ -public class CompoundHandler implements Predicate, CommandHandler { - - private final Injector injector; - private final Map, BiFunction> - handlers; - - public CompoundHandler( - Injector injector, - Map, BiFunction> handlers) { - - this.injector = Objects.requireNonNull(injector, "Injector must be set"); - - Objects.requireNonNull(handlers, "Handlers to use must be set"); - - // First reverse the key set. In maps without a defined order in the key set, this doesn't mean - // much. - Deque> deque = new ArrayDeque<>(); - handlers.keySet().forEach(deque::addFirst); - - // Now bbuild up the map we want to actually use. - ImmutableMap.Builder, BiFunction> - built = ImmutableMap.builder(); - deque.forEach(key -> built.put(key, handlers.get(key))); - this.handlers = built.build(); - } - - @Override - public boolean test(HttpRequest request) { - return handlers.keySet().parallelStream().anyMatch(pred -> pred.test(request)); - } - - @Override - public void execute(HttpRequest req, HttpResponse resp) throws IOException { - BiFunction generator = - handlers.entrySet().stream() - .filter(entry -> entry.getKey().test(req)) - .map(Map.Entry::getValue) - .findFirst() - .orElseThrow(() -> new UnsupportedCommandException(String.format( - "Unknown command: (%s) %s", req.getMethod(), req.getUri()))); - - CommandHandler handler = generator.apply(injector, req); - handler.execute(req, resp); - } -} diff --git a/java/server/src/org/openqa/selenium/grid/web/Route.java b/java/server/src/org/openqa/selenium/grid/web/Route.java index 6333e081d62b6..406cc4113b3d5 100644 --- a/java/server/src/org/openqa/selenium/grid/web/Route.java +++ b/java/server/src/org/openqa/selenium/grid/web/Route.java @@ -27,11 +27,12 @@ import java.util.List; import java.util.Objects; import java.util.function.BiFunction; +import java.util.function.Function; public abstract class Route { private final List> decorators = new ArrayList<>(); - private Class fallback; + private Function fallback; protected Route() { // no-op @@ -74,7 +75,19 @@ public T decorateWith(Class decorator) { } public T fallbackTo(Class fallback) { - this.fallback = Objects.requireNonNull(fallback); + Objects.requireNonNull(fallback); + + this.fallback = inj -> inj.newInstance(fallback); + + //noinspection unchecked + return (T) this; + } + + public T fallbackTo(CommandHandler fallback) { + Objects.requireNonNull(fallback); + + this.fallback = inj -> fallback; + //noinspection unchecked return (T) this; } @@ -101,6 +114,6 @@ public Routes build() { } protected CommandHandler getFallback(Injector injector) { - return fallback == null ? null : injector.newInstance(fallback); + return fallback == null ? null : fallback.apply(injector); } } diff --git a/java/server/src/org/openqa/selenium/remote/server/SeleniumServer.java b/java/server/src/org/openqa/selenium/remote/server/SeleniumServer.java index 2db01a0eaf160..3fce363a8ee12 100644 --- a/java/server/src/org/openqa/selenium/remote/server/SeleniumServer.java +++ b/java/server/src/org/openqa/selenium/remote/server/SeleniumServer.java @@ -18,6 +18,7 @@ package org.openqa.selenium.remote.server; import static java.util.concurrent.TimeUnit.SECONDS; +import static org.openqa.selenium.grid.web.Routes.matching; import com.beust.jcommander.JCommander; @@ -35,6 +36,7 @@ import org.openqa.selenium.grid.server.BaseServer; import org.openqa.selenium.grid.server.BaseServerOptions; import org.openqa.selenium.grid.web.CommandHandler; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.injector.Injector; import org.openqa.selenium.json.Json; import org.openqa.selenium.remote.http.HttpRequest; @@ -122,14 +124,11 @@ public boolean boot() { addServlet(driverServlet, "/wd/hub/*"); addServlet(driverServlet, "/webdriver/*"); - addHandler(req -> true, new BiFunction() { - @Override - public CommandHandler apply(Injector inj, HttpRequest ignored) { - Json json = inj.newInstance(Json.class); - - return new DisplayHelpHandler(json, GridRole.get(configuration.role), "/wd/hub"); - } - }); + addRoute( + matching(req -> true).using(new DisplayHelpHandler( + new Json(), + GridRole.get(configuration.role), + "/wd/hub"))); addRcSupport(); addExtraServlets(); diff --git a/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java b/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java index 93fbd91d75dff..da5271dea84e8 100644 --- a/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java +++ b/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java @@ -36,6 +36,7 @@ import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap; import org.openqa.selenium.grid.sessionmap.remote.RemoteSessionMap; import org.openqa.selenium.grid.web.CommandHandler; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.net.PortProber; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.SessionId; @@ -66,7 +67,7 @@ public void inMemory() throws URISyntaxException { Router router = new Router(sessions, distributor); Server server = createServer(); - server.addHandler(router, (inj, req) -> router); + server.addRoute(Routes.matching(router).using(router)); server.start(); exerciseDriver(server); @@ -85,14 +86,14 @@ public void withServers() throws URISyntaxException { LocalSessionMap localSessions = new LocalSessionMap(); Server sessionServer = createServer(); - sessionServer.addHandler(localSessions, (inj, req) -> localSessions); + sessionServer.addRoute(Routes.matching(localSessions).using(localSessions)); sessionServer.start(); SessionMap sessions = new RemoteSessionMap(getClient(sessionServer)); LocalDistributor localDistributor = new LocalDistributor(); Server distributorServer = createServer(); - distributorServer.addHandler(localDistributor, (inj, req) -> localDistributor); + distributorServer.addRoute(Routes.matching(localDistributor).using(localDistributor)); distributorServer.start(); Distributor distributor = new RemoteDistributor(getClient(distributorServer)); @@ -104,14 +105,14 @@ public void withServers() throws URISyntaxException { .build(); Server nodeServer = new BaseServer<>(new BaseServerOptions( new MapConfig(ImmutableMap.of("server", ImmutableMap.of("port", port))))); - nodeServer.addHandler(localNode, (inj, req) -> localNode); + nodeServer.addRoute(Routes.matching(localNode).using(localNode)); nodeServer.start(); distributor.add(localNode); Router router = new Router(sessions, distributor); Server routerServer = createServer(); - routerServer.addHandler(router, (inj, req) -> router); + routerServer.addRoute(Routes.matching(router).using(router)); routerServer.start(); exerciseDriver(routerServer); diff --git a/java/server/test/org/openqa/selenium/grid/server/BaseServerTest.java b/java/server/test/org/openqa/selenium/grid/server/BaseServerTest.java index 55c14275ba632..fbb46755be6a0 100644 --- a/java/server/test/org/openqa/selenium/grid/server/BaseServerTest.java +++ b/java/server/test/org/openqa/selenium/grid/server/BaseServerTest.java @@ -20,7 +20,7 @@ import static java.net.HttpURLConnection.HTTP_OK; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; -import static org.openqa.selenium.grid.server.Server.get; +import static org.openqa.selenium.grid.web.Routes.get; import static org.openqa.selenium.remote.http.HttpMethod.GET; import com.google.common.collect.ImmutableMap; @@ -58,9 +58,7 @@ public void baseServerStartsAndDoesNothing() throws IOException { @Test public void shouldAllowAHandlerToBeRegistered() throws IOException { Server server = new BaseServer<>(emptyOptions); - server.addHandler( - get("/cheese"), - (inj, ignored) -> (req, res) -> res.setContent("cheddar".getBytes(UTF_8))); + server.addRoute(get("/cheese").using((req, res) -> res.setContent("cheddar".getBytes(UTF_8)))); server.start(); URL url = server.getUrl(); @@ -73,12 +71,8 @@ public void shouldAllowAHandlerToBeRegistered() throws IOException { @Test public void ifTwoHandlersRespondToTheSameRequestTheLastOneAddedWillBeUsed() throws IOException { Server server = new BaseServer<>(emptyOptions); - server.addHandler( - get("/status"), - (inj, ignored) -> (req, res) -> res.setContent("one".getBytes(UTF_8))); - server.addHandler( - get("/status"), - (inj, ignored) -> (req, res) -> res.setContent("two".getBytes(UTF_8))); + server.addRoute(get("/status").using((req, res) -> res.setContent("one".getBytes(UTF_8)))); + server.addRoute(get("/status").using((req, res) -> res.setContent("two".getBytes(UTF_8)))); server.start(); URL url = server.getUrl(); @@ -95,7 +89,7 @@ public void addHandlersOnceServerIsStartedIsAnError() { server.start(); Assertions.assertThatExceptionOfType(IllegalStateException.class).isThrownBy( - () -> server.addHandler(get("/foo"), (inj, ignored) -> (req, res) -> {})); + () -> server.addRoute(get("/foo").using((req, res) -> {}))); } } diff --git a/java/server/test/org/openqa/selenium/grid/server/CommandHandlerServletTest.java b/java/server/test/org/openqa/selenium/grid/server/CommandHandlerServletTest.java index e56f45417a56d..dd04c1635abe7 100644 --- a/java/server/test/org/openqa/selenium/grid/server/CommandHandlerServletTest.java +++ b/java/server/test/org/openqa/selenium/grid/server/CommandHandlerServletTest.java @@ -24,12 +24,10 @@ import static org.assertj.core.api.Assertions.fail; import static org.openqa.selenium.remote.http.HttpMethod.GET; -import com.google.common.collect.ImmutableMap; - import org.junit.Test; import org.openqa.selenium.UnableToSetCookieException; import org.openqa.selenium.UnsupportedCommandException; -import org.openqa.selenium.grid.web.CompoundHandler; +import org.openqa.selenium.grid.web.Routes; import org.openqa.selenium.injector.Injector; import org.openqa.selenium.json.Json; import org.openqa.selenium.remote.ErrorHandler; @@ -73,10 +71,8 @@ public class CommandHandlerServletTest { public void shouldReturnValueFromHandlerIfUrlMatches() throws IOException { String cheerfulGreeting = "Hello, world!"; - Injector injector = Injector.builder().register(new Json()).build(); - CommandHandlerServlet servlet = new CommandHandlerServlet( - (req, res) -> res.setContent(cheerfulGreeting.getBytes(UTF_8))); + Routes.matching(req -> true).using((req, res) -> res.setContent(cheerfulGreeting.getBytes(UTF_8))).build()); HttpServletRequest request = requestConverter.apply(new HttpRequest(GET, "/hello-world")); FakeHttpServletResponse response = new FakeHttpServletResponse(); @@ -89,10 +85,8 @@ public void shouldReturnValueFromHandlerIfUrlMatches() throws IOException { @Test public void shouldCorrectlyReturnAnUnknownCommandExceptionForUnmappableUrls() throws IOException { - Injector injector = Injector.builder().register(new Json()).build(); - CommandHandlerServlet servlet = new CommandHandlerServlet( - new W3CCommandHandler(new CompoundHandler(injector, ImmutableMap.of()))); + Routes.matching(req -> false).using((req, res) -> {}).decorateWith(W3CCommandHandler.class).build()); HttpServletRequest request = requestConverter.apply(new HttpRequest(GET, "/missing")); FakeHttpServletResponse response = new FakeHttpServletResponse(); @@ -108,14 +102,9 @@ public void exceptionsThrownByHandlersAreConvertedToAProperPayload() throws IOEx Injector injector = Injector.builder().register(new Json()).build(); CommandHandlerServlet servlet = new CommandHandlerServlet( - new W3CCommandHandler( - new CompoundHandler( - injector, - ImmutableMap.of( - req -> true, - (inj, ignored) -> (req, res) -> { - throw new UnableToSetCookieException("Yowza"); - })))); + Routes.matching(req -> true).using((req, res) -> { + throw new UnableToSetCookieException("Yowza"); + }).decorateWith(W3CCommandHandler.class).build()); HttpServletRequest request = requestConverter.apply(new HttpRequest(GET, "/exceptional")); FakeHttpServletResponse response = new FakeHttpServletResponse(); diff --git a/java/server/test/org/openqa/selenium/grid/web/CompoundHandlerTest.java b/java/server/test/org/openqa/selenium/grid/web/CompoundHandlerTest.java deleted file mode 100644 index cfea5ceb50b0e..0000000000000 --- a/java/server/test/org/openqa/selenium/grid/web/CompoundHandlerTest.java +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the Software Freedom Conservancy (SFC) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The SFC licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package org.openqa.selenium.grid.web; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; -import static org.openqa.selenium.grid.server.Server.get; -import static org.openqa.selenium.remote.http.HttpMethod.GET; - -import com.google.common.collect.ImmutableMap; - -import org.junit.Test; -import org.openqa.selenium.injector.Injector; -import org.openqa.selenium.remote.http.HttpRequest; -import org.openqa.selenium.remote.http.HttpResponse; - -import java.io.IOException; - -public class CompoundHandlerTest { - - @Test - public void ifTwoHandlersRespondToTheSameRequestTheLastOneAddedWillBeUsed() throws IOException { - CommandHandler handler = new CompoundHandler( - Injector.builder().build(), - // Insertion order is preserved with an ImmutableMap - ImmutableMap.of( - get("/status"), (inj, ignored) -> (req, res) -> res.setContent("one".getBytes(UTF_8)), - get("/status"), (inj, ignored) -> (req, res) -> res.setContent("two".getBytes(UTF_8)))); - - HttpRequest request = new HttpRequest(GET, "/status"); - HttpResponse response = new HttpResponse(); - - handler.execute(request, response); - - assertThat(response.getContentString()).isEqualTo("two"); - } -} \ No newline at end of file