org.openqa.selenium.grid.distributor.Distributor Maven / Gradle / Ivy
// 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.distributor;
import static org.openqa.selenium.grid.web.Routes.delete;
import static org.openqa.selenium.grid.web.Routes.get;
import static org.openqa.selenium.grid.web.Routes.post;
import static org.openqa.selenium.remote.http.Contents.bytes;
import org.openqa.selenium.SessionNotCreatedException;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.DistributorStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.web.CommandHandler;
import org.openqa.selenium.grid.web.HandlerNotFoundException;
import org.openqa.selenium.grid.web.Routes;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.DistributedTracer;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Predicate;
/**
* Responsible for being the central place where the {@link Node}s on which {@link Session}s run
* are determined.
*
* This class responds to the following URLs:
*
*
* Verb
* URL Template
* Meaning
*
*
* POST
* /session
* This is exactly the same as the New Session command from the WebDriver spec.
*
*
* POST
* /se/grid/distributor/node
* Adds a new {@link Node} to this distributor. Please read the javadocs for {@link Node} for
* how the Node should be serialized.
*
*
* DELETE
* /se/grid/distributor/node/{nodeId}
* Remove the {@link Node} identified by {@code nodeId} from this distributor. It is expected
* that any sessions running on the Node are allowed to complete: this simply means that no new
* sessions will be scheduled on this Node.
*
*
*/
public abstract class Distributor implements Predicate, CommandHandler {
private final Routes routes;
protected Distributor(DistributedTracer tracer, HttpClient.Factory httpClientFactory) {
Objects.requireNonNull(tracer);
Objects.requireNonNull(httpClientFactory);
Json json = new Json();
routes = Routes.combine(
post("/session").using((req, res) -> {
CreateSessionResponse sessionResponse = newSession(req);
res.setContent(bytes(sessionResponse.getDownstreamEncodedResponse()));
}),
post("/se/grid/distributor/session")
.using(() -> new CreateSession(json, this)),
post("/se/grid/distributor/node")
.using(() -> new AddNode(tracer, this, json, httpClientFactory)),
delete("/se/grid/distributor/node/{nodeId}")
.using((Map params) -> new RemoveNode(this, UUID.fromString(params.get("nodeId")))),
get("/se/grid/distributor/status")
.using(() -> new GetDistributorStatus(json, this)))
.build();
}
public abstract CreateSessionResponse newSession(HttpRequest request)
throws SessionNotCreatedException;
public abstract Distributor add(Node node);
public abstract void remove(UUID nodeId);
public abstract DistributorStatus getStatus();
@Override
public boolean test(HttpRequest req) {
return routes.match(req).isPresent();
}
@Override
public void execute(HttpRequest req, HttpResponse resp) throws IOException {
Optional handler = routes.match(req);
if (!handler.isPresent()) {
throw new HandlerNotFoundException(req);
}
handler.get().execute(req, resp);
}
}