blob: 3b9ff995ca4d1f48ee5f61ad855d843c981db033 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.test.jmx;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
import java.net.URI;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.eclipse.jetty.jmx.ConnectorServer;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Some JMX information tests.
*/
public class JmxIT
{
private static JMXConnector __jmxc;
private static MBeanServerConnection __mbsc;
private static Server __server;
private static int __port;
@BeforeClass
public static void connectToMBeanServer() throws Exception
{
startJetty();
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost:1099/jndi/rmi://localhost:1099/jmxrmi");
__jmxc = JMXConnectorFactory.connect(url,null);
__mbsc = __jmxc.getMBeanServerConnection();
}
@AfterClass
public static void disconnectFromMBeanServer() throws Exception
{
stopJetty();
__jmxc.close();
}
public static void startJetty() throws Exception
{
File target = MavenTestingUtils.getTargetDir();
File jettyBase = new File (target, "test-base");
File webapps = new File (jettyBase, "webapps");
File war = new File (webapps, "jmx-webapp.war");
//create server instance
__server = new Server(0);
//set up the webapp
WebAppContext context = new WebAppContext();
context.setWar(war.getCanonicalPath());
context.setContextPath("/jmx-webapp");
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(__server);
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
context.setAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
__server.setHandler(context);
//set up jmx remote
MBeanContainer mbContainer = new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
__server.addBean(mbContainer);
JMXServiceURL serviceUrl = new JMXServiceURL("rmi", "localhost", 1099, "/jndi/rmi://localhost:1099/jmxrmi");
ConnectorServer jmxConnServer = new ConnectorServer(serviceUrl, "org.eclipse.jetty.jmx:name=rmiconnectorserver");
__server.addBean(jmxConnServer);
//start server
__server.start();
//remember chosen port
__port = ((NetworkConnector)__server.getConnectors()[0]).getLocalPort();
}
public static void stopJetty () throws Exception
{
if (__server != null)
__server.stop();
}
private String getStringAttribute(ObjectName objName, String attrName) throws Exception
{
Object val = __mbsc.getAttribute(objName,attrName);
assertThat(attrName,val,notNullValue());
assertThat(attrName,val,instanceOf(String.class));
return (String)val;
}
private int getIntegerAttribute(ObjectName objName, String attrName) throws Exception
{
Object val = __mbsc.getAttribute(objName,attrName);
assertThat(attrName,val,notNullValue());
assertThat(attrName,val,instanceOf(Integer.class));
return (Integer)val;
}
@Test
public void testBasic() throws Exception
{
URI serverURI = new URI("http://localhost:"+String.valueOf(__port)+"/jmx-webapp/");
HttpURLConnection http = (HttpURLConnection) serverURI.resolve("ping").toURL().openConnection();
assertThat("http response", http.getResponseCode(), is(200));
try(InputStream inputStream = http.getInputStream())
{
String resp = IO.toString(inputStream);
assertThat(resp,startsWith("Servlet Pong at "));
}
}
@Test
public void testObtainRunningServerVersion() throws Exception
{
ObjectName serverName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
String version = getStringAttribute(serverName,"version");
assertThat("Version",version,startsWith("9.3."));
}
@Test
public void testObtainJmxWebAppState() throws Exception
{
ObjectName webappName = new ObjectName("org.eclipse.jetty.webapp:context=jmx-webapp,type=webappcontext,id=0");
String contextPath = getStringAttribute(webappName,"contextPath");
String displayName = getStringAttribute(webappName,"displayName");
assertThat("Context Path",contextPath,is("/jmx-webapp"));
assertThat("Display Name",displayName,is("Test JMX WebApp"));
}
/**
* Test for directly annotated POJOs in the JMX tree
*/
@Test
public void testAccessToCommonComponent() throws Exception
{
ObjectName commonName = new ObjectName("org.eclipse.jetty.test.jmx:type=commoncomponent,context=jmx-webapp,id=0");
String name = getStringAttribute(commonName,"name");
assertThat("Name",name,is("i am common"));
}
/**
* Test for POJO (not annotated) that is supplemented with a MBean that
* declares the annotations.
*/
@Test
public void testAccessToPingerMBean() throws Exception
{
ObjectName pingerName = new ObjectName("org.eclipse.jetty.test.jmx:type=pinger,context=jmx-webapp,id=0");
// Get initial count
int count = getIntegerAttribute(pingerName,"count");
// Operations
Object val = __mbsc.invoke(pingerName,"ping",null,null);
assertThat("ping() return",val.toString(),startsWith("Pong"));
// Attributes
assertThat("count",getIntegerAttribute(pingerName,"count"),is(count+1));
}
/**
* Test for POJO (annotated) that is merged with a MBean that
* declares more annotations.
*/
@Test
public void testAccessToEchoerMBean() throws Exception
{
ObjectName echoerName = new ObjectName("org.eclipse.jetty.test.jmx:type=echoer,context=jmx-webapp,id=0");
// Get initial count
int count = getIntegerAttribute(echoerName,"count");
// Operations
Object val = __mbsc.invoke(echoerName,"echo",new Object[]{"Its Me"},new String[]{String.class.getName()});
assertThat("echo() return",val.toString(),is("Its Me"));
// Attributes
assertThat("count",getIntegerAttribute(echoerName,"count"),is(count+1));
assertThat("foo",getStringAttribute(echoerName,"foo"),is("foo-ish"));
}
}