com.thoughtworks.selenium.grid.hub.remotecontrol.GlobalRemoteControlPool Maven / Gradle / Ivy
The newest version!
package com.thoughtworks.selenium.grid.hub.remotecontrol;
import com.thoughtworks.selenium.grid.hub.Environment;
import com.thoughtworks.selenium.grid.hub.NoSuchEnvironmentException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
/**
* Monolithic Remote Control Pool keeping track of all environment and all sessions.
*/
public class GlobalRemoteControlPool implements DynamicRemoteControlPool {
private static final Log LOGGER = LogFactory.getLog(GlobalRemoteControlPool.class);
private final Map remoteControlsBySessionIds;
private final Map provisionersByEnvironment;
public GlobalRemoteControlPool() {
remoteControlsBySessionIds = new HashMap();
provisionersByEnvironment = new HashMap();
}
public void register(RemoteControlProxy newRemoteControl) {
final RemoteControlProvisioner provisioner;
synchronized(provisionersByEnvironment) {
if (null == getProvisioner(newRemoteControl.environment())) {
createNewProvisionerForEnvironment(newRemoteControl.environment());
}
provisioner = getProvisioner(newRemoteControl.environment());
provisioner.add(newRemoteControl);
}
}
public boolean unregister(RemoteControlProxy remoteControl) {
final boolean status;
synchronized(provisionersByEnvironment) {
synchronized (remoteControlsBySessionIds) {
status = getProvisioner(remoteControl.environment()).remove(remoteControl);
for (RemoteControlSession session : remoteControlsBySessionIds.values()) {
if (session.remoteControl().equals(remoteControl)) {
removeFromSessionMap(session);
}
}
}
}
return status;
}
public RemoteControlProxy reserve(Environment environment) {
final RemoteControlProvisioner provisioner;
provisioner = getProvisioner(environment.name());
if (null == provisioner) {
throw new NoSuchEnvironmentException(environment.name());
}
return provisioner.reserve();
}
public void associateWithSession(RemoteControlProxy remoteControl, String sessionId) {
LOGGER.info("Associating session id='" + sessionId + "' =>" + remoteControl
+ " for environment " + remoteControl.environment());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Asssociating " + sessionId + " => " + remoteControl);
}
synchronized (remoteControlsBySessionIds) {
if (remoteControlsBySessionIds.containsKey(sessionId)) {
throw new IllegalStateException(
"Session '" + sessionId + "' is already asssociated with " + remoteControlsBySessionIds.get(sessionId));
}
synchronized (remoteControlsBySessionIds) {
final RemoteControlSession newSession;
newSession = new RemoteControlSession(sessionId, remoteControl);
remoteControlsBySessionIds.put(sessionId, newSession);
}
}
if (LOGGER.isDebugEnabled()) {
logSessionMap();
}
}
public RemoteControlProxy retrieve(String sessionId) {
return getRemoteControlForSession(sessionId);
}
public void release(RemoteControlProxy remoteControl) {
getProvisioner(remoteControl.environment()).release(remoteControl);
}
public void releaseForSession(String sessionId) {
LOGGER.info("Releasing pool for session id='" + sessionId + "'");
final RemoteControlProxy remoteControl;
remoteControl = getRemoteControlForSession(sessionId);
synchronized (remoteControlsBySessionIds) {
remoteControlsBySessionIds.remove(sessionId);
}
getProvisioner(remoteControl.environment()).release(remoteControl);
}
public List availableRemoteControls() {
final List availableRemoteControls;
availableRemoteControls = new LinkedList();
for (RemoteControlProvisioner provisioner : provisionersByEnvironment.values()) {
availableRemoteControls.addAll(provisioner.availableRemoteControls());
}
return availableRemoteControls;
}
public List reservedRemoteControls() {
final List reservedRemoteControls;
reservedRemoteControls = new LinkedList();
for (RemoteControlProvisioner provisioner : provisionersByEnvironment.values()) {
reservedRemoteControls.addAll(provisioner.reservedRemoteControls());
}
return reservedRemoteControls;
}
public List allRegisteredRemoteControls() {
final List allRemoteControls;
allRemoteControls = new LinkedList();
synchronized(provisionersByEnvironment) {
for (RemoteControlProvisioner provisioner : provisionersByEnvironment.values()) {
allRemoteControls.addAll(provisioner.allRemoteControls());
}
}
return allRemoteControls;
}
public boolean isRegistered(RemoteControlProxy remoteControl) {
for (RemoteControlProvisioner provisioner : provisionersByEnvironment.values()) {
if (provisioner.contains(remoteControl)) {
return true;
}
}
return false;
}
public RemoteControlProvisioner getProvisioner(String environment) {
return provisionersByEnvironment.get(environment);
}
protected RemoteControlProxy getRemoteControlForSession(String sessionId) {
final RemoteControlSession session;
session = getRemoteControlSession(sessionId);
return (null == session)? null : session.remoteControl();
}
protected RemoteControlSession getRemoteControlSession(String sessionId) {
return remoteControlsBySessionIds.get(sessionId);
}
protected void removeFromSessionMap(RemoteControlSession session) {
for (Map.Entry entry : remoteControlsBySessionIds.entrySet()) {
if (entry.getValue().equals(session)) {
remoteControlsBySessionIds.remove(entry.getKey());
}
}
}
protected void logSessionMap() {
for (Map.Entry entry : remoteControlsBySessionIds.entrySet()) {
LOGGER.debug(entry.getKey() + " => " + entry.getValue());
}
}
protected void createNewProvisionerForEnvironment(String environemntName) {
provisionersByEnvironment.put(environemntName, new RemoteControlProvisioner());
}
public void unregisterAllUnresponsiveRemoteControls() {
for (RemoteControlProxy rc : allRegisteredRemoteControls()) {
unregisterRemoteControlIfUnreliable(rc);
}
}
protected void unregisterRemoteControlIfUnreliable(RemoteControlProxy rc) {
if (rc.unreliable()) {
LOGGER.warn("Unregistering unreliable RC " + rc);
unregister(rc);
}
}
public void updateSessionLastActiveAt(String sessionId) {
getRemoteControlSession(sessionId).updateLastActiveAt();
}
public void recycleAllSessionsIdleForTooLong(double maxIdleTimeInSeconds) {
for (RemoteControlSession session : iteratorSafeRemoteControlSessions()) {
recycleSessionIfIdleForTooLong(session, maxIdleTimeInSeconds);
}
}
public Set iteratorSafeRemoteControlSessions() {
final Set iteratorSafeCopy;
iteratorSafeCopy = new HashSet();
synchronized (remoteControlsBySessionIds) {
for (Map.Entry entry : remoteControlsBySessionIds.entrySet()) {
iteratorSafeCopy.add(entry.getValue());
}
}
return iteratorSafeCopy;
}
public void recycleSessionIfIdleForTooLong(RemoteControlSession session, double maxIdleTimeInSeconds) {
final int maxIdleTImeInMilliseconds;
maxIdleTImeInMilliseconds = (int) (maxIdleTimeInSeconds * 1000);
if (session.innactiveForMoreThan(maxIdleTImeInMilliseconds)) {
LOGGER.warn("Releasing session IDLE for more than " + maxIdleTimeInSeconds + " seconds: " + session);
releaseForSession(session.sessionId());
}
}
}