Skip to content

Commit

Permalink
Use the ProtocolHandshake to determine remote end protocol version
Browse files Browse the repository at this point in the history
At the moment, all protocols are modelled using the Json*Codecs.
A follow up diff will clean this up.
  • Loading branch information
shs96c committed Aug 19, 2016
1 parent 1eb94ab commit d725150
Show file tree
Hide file tree
Showing 6 changed files with 606 additions and 13 deletions.
2 changes: 2 additions & 0 deletions java/client/src/org/openqa/selenium/remote/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ java_library(name = 'remote-lib',
'http/HttpResponse.java',
'http/JsonHttpCommandCodec.java',
'http/JsonHttpResponseCodec.java',
'http/W3CHttpCommandCodec.java',
'http/W3CHttpResponseCodec.java',
'internal/ApacheHttpClient.java',
'internal/HttpClientFactory.java',
'internal/JsonToWebElementConverter.java',
Expand Down
6 changes: 6 additions & 0 deletions java/client/src/org/openqa/selenium/remote/CommandCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.http.HttpMethod;

/**
* Converts {@link Command} objects to and from another representation.
Expand All @@ -44,4 +45,9 @@ public interface CommandCodec<T> {
* @throws UnsupportedCommandException If the command is not supported by this codec.
*/
Command decode(T encodedCommand);

/**
* Enhance this command codec with additional commands.
*/
void defineCommand(String name, HttpMethod method, String pathPattern);
}
34 changes: 32 additions & 2 deletions java/client/src/org/openqa/selenium/remote/Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,37 @@

package org.openqa.selenium.remote;

import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.http.JsonHttpCommandCodec;
import org.openqa.selenium.remote.http.JsonHttpResponseCodec;
import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
import org.openqa.selenium.remote.http.W3CHttpResponseCodec;

public enum Dialect {
OSS,
W3C;
OSS {
@Override
public CommandCodec<HttpRequest> getCommandCodec() {
return new JsonHttpCommandCodec();
}

@Override
public ResponseCodec<HttpResponse> getResponseCodec() {
return new JsonHttpResponseCodec();
}
},
W3C {
@Override
public CommandCodec<HttpRequest> getCommandCodec() {
return new W3CHttpCommandCodec();
}

@Override
public ResponseCodec<HttpResponse> getResponseCodec() {
return new W3CHttpResponseCodec();
}
};

public abstract CommandCodec<HttpRequest> getCommandCodec();
public abstract ResponseCodec<HttpResponse> getResponseCodec();
}
39 changes: 28 additions & 11 deletions java/client/src/org/openqa/selenium/remote/HttpCommandExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.SessionNotCreatedException;
import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.logging.LocalLogs;
Expand All @@ -35,8 +36,6 @@
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.http.JsonHttpCommandCodec;
import org.openqa.selenium.remote.http.JsonHttpResponseCodec;
import org.openqa.selenium.remote.internal.ApacheHttpClient;

import java.io.IOException;
Expand All @@ -50,8 +49,9 @@ public class HttpCommandExecutor implements CommandExecutor, NeedsLocalLogs {

private final URL remoteServer;
private final HttpClient client;
private final JsonHttpCommandCodec commandCodec;
private final JsonHttpResponseCodec responseCodec;
private final Map<String, CommandInfo> additionalCommands;
private CommandCodec<HttpRequest> commandCodec;
private ResponseCodec<HttpResponse> responseCodec;

private LocalLogs logs = LocalLogs.getNullLogger();

Expand Down Expand Up @@ -83,13 +83,8 @@ public HttpCommandExecutor(
throw new WebDriverException(e);
}

commandCodec = new JsonHttpCommandCodec();
responseCodec = new JsonHttpResponseCodec();
client = httpClientFactory.createClient(remoteServer);

for (Map.Entry<String, CommandInfo> entry : additionalCommands.entrySet()) {
defineCommand(entry.getKey(), entry.getValue());
}
this.additionalCommands = additionalCommands;
this.client = httpClientFactory.createClient(remoteServer);
}

private static synchronized HttpClient.Factory getDefaultClientFactory() {
Expand Down Expand Up @@ -137,6 +132,28 @@ public Response execute(Command command) throws IOException {
}
}

if (NEW_SESSION.equals(command.getName())) {
if (commandCodec != null) {
throw new SessionNotCreatedException("Session already exists");
}
ProtocolHandshake handshake = new ProtocolHandshake();
log(LogType.PROFILER, new HttpProfilerLogEntry(command.getName(), true));
ProtocolHandshake.Result result = handshake.createSession(client, command);
Dialect dialect = result.getDialect();
commandCodec = dialect.getCommandCodec();
for (Map.Entry<String, CommandInfo> entry : additionalCommands.entrySet()) {
defineCommand(entry.getKey(), entry.getValue());
}
responseCodec = dialect.getResponseCodec();
log(LogType.PROFILER, new HttpProfilerLogEntry(command.getName(), false));
return result.createResponse();
}

if (commandCodec == null || responseCodec == null) {
throw new WebDriverException(
"No command or response codec has been defined. Unable to proceed");
}

HttpRequest httpRequest = commandCodec.encode(command);
try {
log(LogType.PROFILER, new HttpProfilerLogEntry(command.getName(), true));
Expand Down
Loading

0 comments on commit d725150

Please sign in to comment.