...37import org.openqa.selenium.grid.sessionmap.local.LocalSessionMap;38import org.openqa.selenium.grid.web.ClassPathResource;39import org.openqa.selenium.grid.web.CombinedHandler;40import org.openqa.selenium.grid.web.NoHandler;41import org.openqa.selenium.grid.web.ResourceHandler;42import org.openqa.selenium.grid.web.RoutableHttpClientFactory;43import org.openqa.selenium.internal.Require;44import org.openqa.selenium.json.Json;45import org.openqa.selenium.remote.http.Contents;46import org.openqa.selenium.remote.http.HttpClient;47import org.openqa.selenium.remote.http.HttpHandler;48import org.openqa.selenium.remote.http.HttpResponse;49import org.openqa.selenium.remote.http.Routable;50import org.openqa.selenium.remote.http.Route;51import org.openqa.selenium.remote.tracing.Tracer;52import java.net.MalformedURLException;53import java.net.URL;54import java.util.Collections;55import java.util.Set;56import java.util.logging.Logger;57import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;58import static java.net.HttpURLConnection.HTTP_MOVED_PERM;59import static java.net.HttpURLConnection.HTTP_OK;60import static org.openqa.selenium.grid.config.StandardGridRoles.EVENT_BUS_ROLE;61import static org.openqa.selenium.grid.config.StandardGridRoles.HTTPD_ROLE;62import static org.openqa.selenium.grid.config.StandardGridRoles.ROUTER_ROLE;63import static org.openqa.selenium.remote.http.Route.combine;64import static org.openqa.selenium.remote.http.Route.get;65@AutoService(CliCommand.class)66public class Hub extends TemplateGridServerCommand {67 private static final Logger LOG = Logger.getLogger(Hub.class.getName());68 @Override69 public String getName() {70 return "hub";71 }72 @Override73 public String getDescription() {74 return "A grid hub, composed of sessions, distributor, and router.";75 }76 @Override77 public Set<Role> getConfigurableRoles() {78 return ImmutableSet.of(EVENT_BUS_ROLE, HTTPD_ROLE, ROUTER_ROLE);79 }80 @Override81 public Set<Object> getFlagObjects() {82 return Collections.emptySet();83 }84 @Override85 protected String getSystemPropertiesConfigPrefix() {86 return "selenium";87 }88 @Override89 protected Config getDefaultConfig() {90 return new DefaultHubConfig();91 }92 @Override93 protected Handlers createHandlers(Config config) {94 LoggingOptions loggingOptions = new LoggingOptions(config);95 Tracer tracer = loggingOptions.getTracer();96 EventBusOptions events = new EventBusOptions(config);97 EventBus bus = events.getEventBus();98 CombinedHandler handler = new CombinedHandler();99 SessionMap sessions = new LocalSessionMap(tracer, bus);100 handler.addHandler(sessions);101 BaseServerOptions serverOptions = new BaseServerOptions(config);102 URL externalUrl;103 try {104 externalUrl = serverOptions.getExternalUri().toURL();105 } catch (MalformedURLException e) {106 throw new IllegalArgumentException(e);107 }108 NetworkOptions networkOptions = new NetworkOptions(config);109 HttpClient.Factory clientFactory = new RoutableHttpClientFactory(110 externalUrl,111 handler,112 networkOptions.getHttpClientFactory(tracer));113 Distributor distributor = new LocalDistributor(114 tracer,115 bus,116 clientFactory,117 sessions,118 serverOptions.getRegistrationSecret());119 handler.addHandler(distributor);120 Router router = new Router(tracer, clientFactory, sessions, distributor);121 GraphqlHandler graphqlHandler = new GraphqlHandler(distributor, serverOptions.getExternalUri());122 HttpHandler readinessCheck = req -> {123 boolean ready = router.isReady() && bus.isReady();124 return new HttpResponse()125 .setStatus(ready ? HTTP_OK : HTTP_INTERNAL_ERROR)126 .setContent(Contents.utf8String("Router is " + ready));127 };128 Routable ui;129 URL uiRoot = getClass().getResource("/javascript/grid-ui/build");130 if (uiRoot != null) {131 ResourceHandler132 uiHandler = new ResourceHandler(new ClassPathResource(uiRoot, "javascript/grid-ui/build"));133 ui = Route.combine(134 get("/grid/console").to(() -> req -> new HttpResponse().setStatus(HTTP_MOVED_PERM).addHeader("Location", "/ui/index.html")),135 Route.prefix("/ui/").to(Route.matching(req -> true).to(() -> uiHandler)));136 } else {137 Json json = new Json();138 ui = Route.matching(req -> false).to(() -> new NoHandler(json));139 }140 HttpHandler httpHandler = combine(141 ui,142 router.with(networkOptions.getSpecComplianceChecks()),143 Route.prefix("/wd/hub").to(combine(router.with(networkOptions.getSpecComplianceChecks()))),144 Route.post("/graphql").to(() -> graphqlHandler),145 Route.get("/readyz").to(() -> readinessCheck));146 return new Handlers(httpHandler, new ProxyCdpIntoGrid(clientFactory, sessions));...