Skip to content

Commit

Permalink
JMX initial support for Grid Hub
Browse files Browse the repository at this point in the history
  • Loading branch information
barancev committed Nov 15, 2017
1 parent 472af9f commit 6f6d66b
Show file tree
Hide file tree
Showing 14 changed files with 501 additions and 1 deletion.
1 change: 1 addition & 0 deletions java/server/src/org/openqa/grid/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ java_library(name = 'grid',
'//java/server/src/org/openqa/selenium/remote/server:server',
'//java/server/src/org/openqa/selenium/remote/server:webdriver-servlet',
'//java/server/src/org/openqa/selenium/remote/server/log:log',
'//java/server/src/org/openqa/selenium/remote/server/jmx:jmx',
'//third_party/java/beust:jcommander',
'//third_party/java/gson:gson',
'//third_party/java/guava:guava',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.jcip.annotations.ThreadSafe;

import org.openqa.grid.common.exception.GridException;
import org.openqa.selenium.remote.server.jmx.JMXHelper;

import java.util.Collections;
import java.util.Map;
Expand All @@ -30,6 +31,8 @@
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Logger;

import javax.management.ObjectName;

/**
* The set of active test sessions.
*/
Expand All @@ -55,11 +58,14 @@ public boolean add(TestSession testSession) {
if (!added) {
log.severe("Error adding session : " + testSession);
}

new JMXHelper().register(testSession);
return added;
}

public boolean remove(TestSession o, SessionTerminationReason reason) {
updateReason(o, reason);
new JMXHelper().unregister(o.getObjectName());
return activeTestSessions.remove(o);
}

Expand Down
13 changes: 12 additions & 1 deletion java/server/src/org/openqa/grid/internal/BaseRemoteProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.remote.internal.HttpClientFactory;
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;

import java.io.BufferedReader;
import java.io.IOException;
Expand Down Expand Up @@ -273,10 +274,12 @@ public RegistrationRequest getOriginalRegistrationRequest() {
return request;
}

@ManagedAttribute
public int getMaxNumberOfConcurrentTestSessions() {
return config.maxSession;
}

@ManagedAttribute
public URL getRemoteHost() {
return remoteHost;
}
Expand Down Expand Up @@ -304,6 +307,7 @@ public TestSession getNewSession(Map<String, Object> requestedCapability) {
return null;
}

@ManagedAttribute
public int getTotalUsed() {
int totalUsed = 0;

Expand All @@ -316,6 +320,11 @@ public int getTotalUsed() {
return totalUsed;
}

@ManagedAttribute
public int getTotal() {
return getTestSlots().size();
}

public boolean hasCapability(Map<String, Object> requestedCapability) {
for (TestSlot slot : getTestSlots()) {
if (slot.matches(requestedCapability)) {
Expand All @@ -326,6 +335,7 @@ public boolean hasCapability(Map<String, Object> requestedCapability) {
return false;
}

@ManagedAttribute
public boolean isBusy() {
return getTotalUsed() != 0;
}
Expand Down Expand Up @@ -489,11 +499,12 @@ private JsonObject extractObject(HttpResponse resp) throws IOException {
return new JsonParser().parse(s.toString()).getAsJsonObject();
}


@ManagedAttribute
public float getResourceUsageInPercent() {
return 100 * (float)getTotalUsed() / (float)getMaxNumberOfConcurrentTestSessions();
}

@ManagedAttribute
public long getLastSessionStart() {
long last = -1;
for (TestSlot slot : getTestSlots()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import org.openqa.grid.web.Hub;
import org.openqa.grid.web.servlet.handler.RequestHandler;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.server.jmx.JMXHelper;
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
import org.openqa.selenium.remote.server.jmx.ManagedService;
import org.openqa.selenium.remote.server.log.LoggingManager;

import java.util.List;
Expand All @@ -40,6 +43,7 @@
* incoming requests.
*/
@ThreadSafe
@ManagedService(objectName = "org.seleniumhq.qrid:type=Registry", description = "Selenium Grid Hub Registry")
public class DefaultGridRegistry extends BaseGridRegistry implements GridRegistry {
private static final Logger LOG = Logger.getLogger(DefaultGridRegistry.class.getName());

Expand Down Expand Up @@ -71,6 +75,8 @@ public DefaultGridRegistry(Hub hub) {
this.newSessionQueue = new NewSessionRequestQueue();
proxies = new ProxySet((hub != null) ? hub.getConfiguration().throwOnCapabilityNotPresent : true);
this.matcherThread.setUncaughtExceptionHandler(new UncaughtExceptionHandler());

new JMXHelper().register(this);
}

public void start() {
Expand Down Expand Up @@ -397,6 +403,7 @@ public TestSession getExistingSession(ExternalSessionKey externalKey) {
/**
* @see GridRegistry#getNewSessionRequestCount()
*/
@ManagedAttribute(name = "NewSessionRequestCount")
public int getNewSessionRequestCount() {
// may race
return newSessionQueue.getNewSessionRequestCount();
Expand Down
23 changes: 23 additions & 0 deletions java/server/src/org/openqa/grid/internal/TestSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
import org.openqa.grid.web.servlet.handler.SeleniumBasedResponse;
import org.openqa.grid.web.servlet.handler.WebDriverRequest;
import org.openqa.selenium.remote.ErrorCodes;
import org.openqa.selenium.remote.server.jmx.JMXHelper;
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
import org.openqa.selenium.remote.server.jmx.ManagedOperation;
import org.openqa.selenium.remote.server.jmx.ManagedService;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
Expand All @@ -67,6 +71,8 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

Expand All @@ -76,6 +82,7 @@
* timed out)
*/
@SuppressWarnings("JavaDoc")
@ManagedService
public class TestSession {

private static final Logger log = Logger.getLogger(TestSession.class.getName());
Expand Down Expand Up @@ -115,6 +122,7 @@ public TestSession(
* @return the capabilities the client requested. It will match the TestSlot capabilities, but is not
* equals.
*/
@ManagedAttribute
public Map<String, Object> getRequestedCapabilities() {
return requestedCapabilities;
}
Expand Down Expand Up @@ -145,13 +153,15 @@ public void setExternalKey(ExternalSessionKey externalKey) {
* @return time in millis
* @see TestSession#setIgnoreTimeout(boolean)
*/
@ManagedAttribute
public long getInactivityTime() {
if (ignoreTimeout) {
return 0;
}
return clock.millis() - lastActivity;
}

@ManagedAttribute
public boolean isOrphaned() {
final long elapsedSinceCreation = clock.millis() - sessionCreatedAt;

Expand Down Expand Up @@ -669,4 +679,17 @@ public void setIgnoreTimeout(boolean ignore) {
public boolean isForwardingRequest() {
return forwardingRequest;
}

public ObjectName getObjectName() {
try {
return new ObjectName(
String.format("org.seleniumhq.qrid:type=TestSession,nodeHost=%s,nodePort=%s,browser=%s,id=%s",
getSlot().getRemoteURL().getHost(), getSlot().getRemoteURL().getPort(),
getRequestedCapabilities().get("browserName"), getInternalKey()));
} catch (MalformedObjectNameException e) {
e.printStackTrace();
return null;
}
}

}
1 change: 1 addition & 0 deletions java/server/src/org/openqa/grid/selenium/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ java_library(name = 'classes',
'//java/server/src/org/openqa/selenium/remote/server/log:log',
'//java/server/src/org/openqa/selenium/remote/server:standalone-server-lib',
'//java/server/src/org/openqa/selenium/remote/server:server',
'//java/server/src/org/openqa/selenium/remote/server/jmx:jmx',
'//third_party/java/gson:gson',
'//third_party/java/guava:guava',
'//third_party/java/servlet:servlet-api',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,24 @@
import org.openqa.grid.internal.listeners.TestSessionListener;
import org.openqa.grid.internal.listeners.TimeoutListener;
import org.openqa.grid.internal.utils.HtmlRenderer;
import org.openqa.selenium.remote.server.jmx.JMXHelper;
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
import org.openqa.selenium.remote.server.jmx.ManagedService;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Default remote proxy for selenium, handling both selenium1 and webdriver requests.
*/
@ManagedService(description = "Selenium Grid Hub TestSlot")
public class DefaultRemoteProxy extends BaseRemoteProxy
implements
TimeoutListener,
Expand All @@ -64,6 +70,8 @@ public DefaultRemoteProxy(RegistrationRequest request, GridRegistry registry) {
pollingInterval = config.nodePolling != null ? config.nodePolling : DEFAULT_POLLING_INTERVAL;
unregisterDelay = config.unregisterIfStillDownAfter != null ? config.unregisterIfStillDownAfter : DEFAULT_UNREGISTER_DELAY;
downPollingLimit = config.downPollingLimit != null ? config.downPollingLimit : DEFAULT_DOWN_POLLING_LIMIT;

new JMXHelper().register(this);
}

public void beforeRelease(TestSession session) {
Expand Down Expand Up @@ -104,6 +112,7 @@ public HtmlRenderer getHtmlRender() {
private List<RemoteException> errors = new CopyOnWriteArrayList<>();
private Thread pollingThread = null;

@ManagedAttribute
public boolean isAlive() {
try {
getStatus();
Expand Down Expand Up @@ -191,6 +200,7 @@ public TestSession getNewSession(Map<String, Object> requestedCapability) {
return super.getNewSession(requestedCapability);
}

@ManagedAttribute
public boolean isDown() {
return down;
}
Expand Down Expand Up @@ -225,4 +235,16 @@ public void teardown() {
super.teardown();
stopPolling();
}

public ObjectName getObjectName() {
try {
return new ObjectName(
String.format("org.seleniumhq.qrid:type=RemoteProxy,nodeHost=%s,nodePort=%s",
getRemoteHost().getHost(), getRemoteHost().getPort()));
} catch (MalformedObjectNameException e) {
e.printStackTrace();
return null;
}
}

}
14 changes: 14 additions & 0 deletions java/server/src/org/openqa/grid/web/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
import org.openqa.grid.web.servlet.TestSessionStatusServlet;
import org.openqa.grid.web.servlet.beta.ConsoleServlet;
import org.openqa.grid.web.utils.ExtraServletUtil;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.net.NetworkUtils;
import org.openqa.selenium.remote.server.jmx.JMXHelper;
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
import org.openqa.selenium.remote.server.jmx.ManagedService;
import org.seleniumhq.jetty9.server.HttpConfiguration;
import org.seleniumhq.jetty9.server.HttpConnectionFactory;
import org.seleniumhq.jetty9.server.Server;
Expand All @@ -54,6 +58,7 @@
* Jetty server. Main entry point for everything about the grid. <p> Except for unit tests, this
* should be a singleton.
*/
@ManagedService(objectName = "org.seleniumhq.qrid:type=Hub", description = "Selenium Grid Hub")
public class Hub {

private static final Logger log = Logger.getLogger(Hub.class.getName());
Expand Down Expand Up @@ -110,6 +115,8 @@ public Hub(GridHubConfiguration gridHubConfiguration) {

// start the registry, now that 'config' is all setup
registry.start();

new JMXHelper().register(this);
}

private void addDefaultServlets(ServletContextHandler handler) {
Expand Down Expand Up @@ -196,6 +203,12 @@ public GridHubConfiguration getConfiguration() {
return config;
}

@ManagedAttribute(name = "Configuration")
public Map<?,?> getConfigurationForJMX() {
Json json = new Json();
return json.toType(json.toJson(config.toJson()), Map.class);
}

public void start() throws Exception {
initServer();
server.start();
Expand All @@ -206,6 +219,7 @@ public void stop() throws Exception {
server.stop();
}

@ManagedAttribute(name= "URL")
public URL getUrl() {
return getUrl("");
}
Expand Down
10 changes: 10 additions & 0 deletions java/server/src/org/openqa/selenium/remote/server/jmx/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# BUILD FILE SYNTAX: SKYLARK
java_library(name = 'jmx',
srcs = glob(['*.java']),
deps = [
],
visibility = [
'//java/server/src/...',
'//java/server/test/...',
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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.remote.server.jmx;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName;

public class JMXHelper {

public MBean register(Object bean) {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try {
MBean mBean = new MBean(bean);
mbs.registerMBean(mBean, mBean.getObjectName());
return mBean;
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}

public void unregister(ObjectName objectName) {
if (objectName != null) {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
try {
mbs.unregisterMBean(objectName);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
Loading

0 comments on commit 6f6d66b

Please sign in to comment.