org.openqa.grid.common.RegistrationRequest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of selenium-server Show documentation
Show all versions of selenium-server Show documentation
Selenium automates browsers. That's it! What you do with that power is entirely up to you.
// 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.grid.common;
import com.google.common.reflect.TypeToken;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.openqa.grid.common.exception.GridConfigurationException;
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration;
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration.CollectionOfDesiredCapabilitiesDeSerializer;
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration.CollectionOfDesiredCapabilitiesSerializer;
import org.openqa.selenium.Platform;
import org.openqa.selenium.net.NetworkUtils;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.util.List;
/**
* Helper to register to the grid. Using JSON to exchange the object between the node and the hub.
*/
public class RegistrationRequest {
// some special param for capability
public static final String MAX_INSTANCES = "maxInstances";
// see enum SeleniumProtocol
public static final String SELENIUM_PROTOCOL = "seleniumProtocol";
public static final String PATH = "path";
@SerializedName( "class" )
@Expose( deserialize = false)
private final String clazz = RegistrationRequest.class.getCanonicalName();
@Expose
private String name;
@Expose
private String description;
@Expose
private GridNodeConfiguration configuration;
/**
* Create a new registration request using the default values of a
* {@link GridNodeConfiguration}
*/
public RegistrationRequest() {
this(new GridNodeConfiguration());
}
/**
* Create a new registration request using the supplied {@link GridNodeConfiguration}
* @param configuration the {@link GridNodeConfiguration} to use
*/
public RegistrationRequest(GridNodeConfiguration configuration) {
this(configuration, null, null);
}
/**
* Create a new registration request using the supplied {@link GridNodeConfiguration}, and name
* @param configuration the {@link GridNodeConfiguration} to use
* @param name the name for the remote
*/
public RegistrationRequest(GridNodeConfiguration configuration, String name) {
this(configuration, name, null);
}
/**
* Create a new registration request using the supplied {@link GridNodeConfiguration}, name, and
* description
* @param configuration the {@link GridNodeConfiguration} to use
* @param name the name for the remote
* @param description the description for the remote host
*/
public RegistrationRequest(GridNodeConfiguration configuration, String name, String description) {
this.configuration = configuration;
this.name = name;
this.description = description;
// make sure we have something that looks like a valid host
fixUpHost();
// make sure the capabilities are updated with required fields
fixUpCapabilities();
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public GridNodeConfiguration getConfiguration() {
return configuration;
}
public JsonObject toJson() {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(new TypeToken>(){}.getType(),
new CollectionOfDesiredCapabilitiesSerializer());
return builder.excludeFieldsWithoutExposeAnnotation().create()
.toJsonTree(this, RegistrationRequest.class).getAsJsonObject();
}
/**
* Create an object from a registration request formatted as a JsonObject
*
* @param json JsonObject
* @return
*/
public static RegistrationRequest fromJson(JsonObject json) throws JsonSyntaxException {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(new TypeToken>(){}.getType(),
new CollectionOfDesiredCapabilitiesDeSerializer());
RegistrationRequest request = builder.excludeFieldsWithoutExposeAnnotation().create()
.fromJson(json, RegistrationRequest.class);
return request;
}
/**
* Create an object from a registration request formatted as a json string.
*
* @param json JSON String
* @return
*/
public static RegistrationRequest fromJson(String json) throws JsonSyntaxException {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(new TypeToken>(){}.getType(),
new CollectionOfDesiredCapabilitiesDeSerializer());
RegistrationRequest request = builder.excludeFieldsWithoutExposeAnnotation().create()
.fromJson(json, RegistrationRequest.class);
return request;
}
/**
* Build a RegistrationRequest from the provided {@link GridNodeConfiguration}. This is different
* than {@code new RegistrationRequest(GridNodeConfiguration)} because it will merge the provided
* configuration onto the {@link GridNodeConfiguration#DEFAULT_NODE_CONFIG_FILE} and then "fixup"
* the resulting RegistrationRequest before returning the result
* @param configuration the {@link GridNodeConfiguration} to use
* @return
*/
public static RegistrationRequest build(GridNodeConfiguration configuration) {
return RegistrationRequest.build(configuration, null, null);
}
/**
* Build a RegistrationRequest from the provided {@link GridNodeConfiguration}, use the provided name.
* This is different than {@code new RegistrationRequest(GridNodeConfiguration, String)} because it
* will merge the provided configuration onto the {@link GridNodeConfiguration#DEFAULT_NODE_CONFIG_FILE}
* and then "fixup" the resulting RegistrationRequest before returning the result
* @param configuration the {@link GridNodeConfiguration} to use
* @param name the name for the remote
* @return
*/
public static RegistrationRequest build(GridNodeConfiguration configuration, String name) {
return RegistrationRequest.build(configuration, name, null);
}
/**
* Build a RegistrationRequest from the provided {@link GridNodeConfiguration}, use the provided name
* and description. This is different than
* {@code new RegistrationRequest(GridNodeConfiguration, String, String)} because it will merge the
* provided configuration onto the {@link GridNodeConfiguration#DEFAULT_NODE_CONFIG_FILE}
* and then "fixup" the resulting RegistrationRequest before returning the result
* @param configuration the {@link GridNodeConfiguration} to use
* @param name the name for the remote
* @param description the description for the remote host
* @return
*/
public static RegistrationRequest build(GridNodeConfiguration configuration, String name, String description) {
RegistrationRequest pendingRequest =
new RegistrationRequest(GridNodeConfiguration
.loadFromJSON(GridNodeConfiguration.DEFAULT_NODE_CONFIG_FILE));
if (configuration.nodeConfigFile != null) {
pendingRequest.configuration = GridNodeConfiguration.loadFromJSON(configuration.nodeConfigFile);
}
pendingRequest.configuration.merge(configuration);
//update important merge protected values for the pendingRequest we are building.
if (configuration.host != null) {
pendingRequest.configuration.host = configuration.host;
}
if (configuration.port != null) {
pendingRequest.configuration.port = configuration.port;
}
pendingRequest.name = name;
pendingRequest.description = description;
// make sure we have a valid host
pendingRequest.fixUpHost();
// make sure the capabilities are updated with required fields
pendingRequest.fixUpCapabilities();
return pendingRequest;
}
private void fixUpCapabilities() {
Platform current = Platform.getCurrent();
for (DesiredCapabilities cap : configuration.capabilities) {
if (cap.getPlatform() == null) {
cap.setPlatform(current);
}
if (cap.getCapability(SELENIUM_PROTOCOL) == null) {
cap.setCapability(SELENIUM_PROTOCOL, SeleniumProtocol.WebDriver.toString());
}
}
}
private void fixUpHost() {
if (configuration.host == null || "ip".equalsIgnoreCase(configuration.host)) {
NetworkUtils util = new NetworkUtils();
configuration.host = util.getIp4NonLoopbackAddressOfThisMachine().getHostAddress();
} else if ("host".equalsIgnoreCase(configuration.host)) {
NetworkUtils util = new NetworkUtils();
configuration.host = util.getIp4NonLoopbackAddressOfThisMachine().getHostName();
}
}
/**
* Validate the current setting and throw a config exception is an invalid setup is detected.
*
* @throws GridConfigurationException grid configuration
*/
public void validate() throws GridConfigurationException {
// validations occur here in the getters called on the configuration.
try {
configuration.getHubHost();
configuration.getHubPort();
} catch (RuntimeException e) {
throw new GridConfigurationException(e.getMessage());
}
}
}