Rename SpringApplicationLifecycle => Admin

Rename SpringApplicationLifecycle JMX beans to SpringApplicationAdmin
and relocate to a dedicated package.

Fixes gh-3124
This commit is contained in:
Phillip Webb 2015-06-09 16:06:28 -07:00
parent f8f4bd6c95
commit 105039cdb2
12 changed files with 92 additions and 70 deletions

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.context;
package org.springframework.boot.autoconfigure.admin;
import javax.management.MalformedObjectNameException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.admin.SpringApplicationAdminMXBean;
import org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.context.SpringApplicationLifecycleMXBean;
import org.springframework.boot.context.SpringApplicationLifecycleRegistrar;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@ -35,23 +35,23 @@ import org.springframework.jmx.export.MBeanExporter;
*
* @author Stephane Nicoll
* @since 1.3.0
* @see SpringApplicationLifecycleMXBean
* @see SpringApplicationAdminMXBean
*/
@Configuration
@AutoConfigureAfter(JmxAutoConfiguration.class)
@ConditionalOnProperty(value = "spring.context.lifecycle.enabled", havingValue = "true", matchIfMissing = false)
class SpringApplicationLifecycleAutoConfiguration {
public class SpringApplicationAdminJmxAutoConfiguration {
/**
* The property to use to customize the {@code ObjectName} of the application
* lifecycle mbean.
*/
static final String JMX_NAME_PROPERTY = "spring.context.lifecycle.jmx-name";
private static final String JMX_NAME_PROPERTY = "spring.application.admin.jmx-name";
/**
* The default {@code ObjectName} of the application lifecycle mbean.
*/
static final String DEFAULT_JMX_NAME = "org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle";
private static final String DEFAULT_JMX_NAME = "org.springframework.boot:type=SpringApplicationAdmin,name=springApplicationAdmin";
@Autowired(required = false)
private MBeanExporter mbeanExporter;
@ -60,14 +60,14 @@ class SpringApplicationLifecycleAutoConfiguration {
private Environment environment;
@Bean
public SpringApplicationLifecycleRegistrar springApplicationLifecycleRegistrar()
public SpringApplicationAdminMXBeanRegistrar springApplicationLifecycleRegistrar()
throws MalformedObjectNameException {
String jmxName = this.environment
.getProperty(JMX_NAME_PROPERTY, DEFAULT_JMX_NAME);
if (this.mbeanExporter != null) { // Make sure to not register that MBean twice
this.mbeanExporter.addExcludedBean(jmxName);
}
return new SpringApplicationLifecycleRegistrar(jmxName);
return new SpringApplicationAdminMXBeanRegistrar(jmxName);
}
}

View File

@ -4,6 +4,7 @@ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingIni
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\
@ -11,7 +12,6 @@ org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.SpringApplicationLifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.context;
package org.springframework.boot.autoconfigure.admin;
import java.lang.management.ManagementFactory;
@ -37,13 +37,17 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
/**
* Tests for {@link SpringApplicationLifecycleAutoConfiguration}.
* Tests for {@link SpringApplicationAdminJmxAutoConfiguration}.
*
* @author Stephane Nicoll
*/
public class SpringApplicationLifecycleAutoConfigurationTests {
public static final String ENABLE_LIFECYCLE_PROP = "spring.context.lifecycle.enabled=true";
private static final String ENABLE_LIFECYCLE_PROP = "spring.context.lifecycle.enabled=true";
private static final String JMX_NAME_PROPERTY = "spring.application.admin.jmx-name";
private static final String DEFAULT_JMX_NAME = "org.springframework.boot:type=SpringApplicationAdmin,name=springApplicationAdmin";
@Rule
public final ExpectedException thrown = ExpectedException.none();
@ -83,8 +87,7 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
@Test
public void registerWithCustomJmxName() throws InstanceNotFoundException {
String customJmxName = "org.acme:name=FooBar";
System.setProperty(SpringApplicationLifecycleAutoConfiguration.JMX_NAME_PROPERTY,
customJmxName);
System.setProperty(JMX_NAME_PROPERTY, customJmxName);
try {
load(ENABLE_LIFECYCLE_PROP);
try {
@ -97,12 +100,12 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
this.mBeanServer.getObjectInstance(createDefaultObjectName());
}
finally {
System.clearProperty(SpringApplicationLifecycleAutoConfiguration.JMX_NAME_PROPERTY);
System.clearProperty(JMX_NAME_PROPERTY);
}
}
private ObjectName createDefaultObjectName() {
return createObjectName(SpringApplicationLifecycleAutoConfiguration.DEFAULT_JMX_NAME);
return createObjectName(DEFAULT_JMX_NAME);
}
private ObjectName createObjectName(String jmxName) {
@ -118,7 +121,7 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.register(JmxAutoConfiguration.class,
SpringApplicationLifecycleAutoConfiguration.class);
SpringApplicationAdminJmxAutoConfiguration.class);
applicationContext.refresh();
this.context = applicationContext;
}

View File

@ -31,8 +31,8 @@ public class SampleApplication {
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle");
SpringApplicationLifecycle mbean = new SpringApplicationLifecycle();
"org.springframework.boot:type=SpringApplicationAdmin,name=springApplicationAdmin");
SpringApplicationAdmin mbean = new SpringApplicationAdmin();
mbs.registerMBean(mbean, name);
// Flag the app as ready
@ -51,7 +51,7 @@ public class SampleApplication {
}
}
public interface SpringApplicationLifecycleMXBean {
public interface SpringApplicationAdminMXBean {
boolean isReady();
@ -59,7 +59,7 @@ public class SampleApplication {
}
static class SpringApplicationLifecycle implements SpringApplicationLifecycleMXBean {
static class SpringApplicationAdmin implements SpringApplicationAdminMXBean {
private boolean ready;

View File

@ -30,8 +30,8 @@ public class SampleApplication {
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle");
SpringApplicationLifecycle mbean = new SpringApplicationLifecycle();
"org.springframework.boot:type=SpringApplicationAdmin,name=springApplicationAdmin");
SpringApplicationAdmin mbean = new SpringApplicationAdmin();
mbs.registerMBean(mbean, name);
// Flag the app as ready
@ -50,7 +50,7 @@ public class SampleApplication {
}
}
public interface SpringApplicationLifecycleMXBean {
public interface SpringApplicationAdminMXBean {
boolean isReady();
@ -58,7 +58,7 @@ public class SampleApplication {
}
static class SpringApplicationLifecycle implements SpringApplicationLifecycleMXBean {
static class SpringApplicationAdmin implements SpringApplicationAdminMXBean {
private boolean ready;

View File

@ -32,39 +32,25 @@ import javax.management.remote.JMXServiceURL;
import org.apache.maven.plugin.MojoExecutionException;
/**
* A JMX client for the {@code SpringApplicationLifecycle} mbean. Permits to obtain
* information about the lifecycle of a given Spring application.
* A JMX client for the {@code SpringApplicationAdmin} MBean. Permits to obtain
* information about a given Spring application.
*
* @author Stephane Nicoll
*/
class SpringApplicationLifecycleClient {
class SpringApplicationAdminClient {
// Note: see SpringApplicationLifecycleAutoConfiguration
static final String DEFAULT_OBJECT_NAME = "org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle";
// Note: see SpringApplicationAdminJmxAutoConfiguration
static final String DEFAULT_OBJECT_NAME = "org.springframework.boot:type=SpringApplicationAdmin,name=springApplicationAdmin";
private final MBeanServerConnection connection;
private final ObjectName objectName;
public SpringApplicationLifecycleClient(MBeanServerConnection connection,
String jmxName) {
public SpringApplicationAdminClient(MBeanServerConnection connection, String jmxName) {
this.connection = connection;
this.objectName = toObjectName(jmxName);
}
/**
* Create a connector for an {@link javax.management.MBeanServer} exposed on the
* current machine and the current port. Security should be disabled.
* @param port the port on which the mbean server is exposed
* @return a connection
* @throws IOException if the connection to that server failed
*/
public static JMXConnector createLocalJmxConnector(int port) throws IOException {
String url = "service:jmx:rmi:///jndi/rmi://127.0.0.1:" + port + "/jmxrmi";
JMXServiceURL serviceUrl = new JMXServiceURL(url);
return JMXConnectorFactory.connect(serviceUrl, null);
}
/**
* Check if the spring application managed by this instance is ready. Returns
* {@code false} if the mbean is not yet deployed so this method should be repeatedly
@ -123,4 +109,17 @@ class SpringApplicationLifecycleClient {
}
}
/**
* Create a connector for an {@link javax.management.MBeanServer} exposed on the
* current machine and the current port. Security should be disabled.
* @param port the port on which the mbean server is exposed
* @return a connection
* @throws IOException if the connection to that server failed
*/
public static JMXConnector connect(int port) throws IOException {
String url = "service:jmx:rmi:///jndi/rmi://127.0.0.1:" + port + "/jmxrmi";
JMXServiceURL serviceUrl = new JMXServiceURL(url);
return JMXConnectorFactory.connect(serviceUrl, null);
}
}

View File

@ -59,7 +59,7 @@ public class StartMojo extends AbstractRunMojo {
* spring application.
*/
@Parameter
private String jmxName = SpringApplicationLifecycleClient.DEFAULT_OBJECT_NAME;
private String jmxName = SpringApplicationAdminClient.DEFAULT_OBJECT_NAME;
/**
* The port to use to expose the platform MBeanServer if the application needs to be
@ -151,11 +151,11 @@ public class StartMojo extends AbstractRunMojo {
private void waitForSpringApplication(long wait, int maxAttempts)
throws MojoExecutionException {
SpringApplicationLifecycleClient helper = new SpringApplicationLifecycleClient(
SpringApplicationAdminClient client = new SpringApplicationAdminClient(
ManagementFactory.getPlatformMBeanServer(), this.jmxName);
getLog().debug("Waiting for spring application to start...");
for (int i = 0; i < maxAttempts; i++) {
if (helper.isReady()) {
if (client.isReady()) {
return;
}
String message = "Spring application is not ready yet, waiting " + wait
@ -227,7 +227,7 @@ public class StartMojo extends AbstractRunMojo {
private void doWaitForSpringApplication(MBeanServerConnection connection)
throws IOException, MojoExecutionException, MojoFailureException {
final SpringApplicationLifecycleClient client = new SpringApplicationLifecycleClient(
final SpringApplicationAdminClient client = new SpringApplicationAdminClient(
connection, this.jmxName);
try {
execute(this.wait, this.maxAttempts, new Callable<Boolean>() {
@ -294,8 +294,7 @@ public class StartMojo extends AbstractRunMojo {
@Override
public JMXConnector call() throws Exception {
try {
return SpringApplicationLifecycleClient
.createLocalJmxConnector(this.port);
return SpringApplicationAdminClient.connect(this.port);
}
catch (IOException ex) {
if (hasCauseWithType(ex, ConnectException.class)) {

View File

@ -53,7 +53,7 @@ public class StopMojo extends AbstractMojo {
* application.
*/
@Parameter
private String jmxName = SpringApplicationLifecycleClient.DEFAULT_OBJECT_NAME;
private String jmxName = SpringApplicationAdminClient.DEFAULT_OBJECT_NAME;
/**
* The port to use to lookup the platform MBeanServer if the application has been
@ -81,8 +81,7 @@ public class StopMojo extends AbstractMojo {
private void stopForkedProcess() throws IOException, MojoFailureException,
MojoExecutionException {
JMXConnector connector = SpringApplicationLifecycleClient
.createLocalJmxConnector(this.jmxPort);
JMXConnector connector = SpringApplicationAdminClient.connect(this.jmxPort);
try {
MBeanServerConnection connection = connector.getMBeanServerConnection();
doStop(connection);
@ -99,7 +98,7 @@ public class StopMojo extends AbstractMojo {
private void doStop(MBeanServerConnection connection) throws IOException,
MojoExecutionException {
try {
new SpringApplicationLifecycleClient(connection, this.jmxName).stop();
new SpringApplicationAdminClient(connection, this.jmxName).stop();
}
catch (InstanceNotFoundException ex) {
throw new MojoExecutionException(

View File

@ -14,16 +14,16 @@
* limitations under the License.
*/
package org.springframework.boot.context;
package org.springframework.boot.admin;
/**
* A simple MBean contract to control the lifecycle of a {@code SpringApplication} via
* JMX. Intended for internal use only.
* A MBean contract to control and monitor a running {@code SpringApplication} via JMX.
* Intended for internal use only.
*
* @author Stephane Nicoll
* @since 1.3.0
*/
public interface SpringApplicationLifecycleMXBean {
public interface SpringApplicationAdminMXBean {
/**
* Specify if the application has fully started and is now ready.

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.context;
package org.springframework.boot.admin;
import java.lang.management.ManagementFactory;
@ -35,13 +35,13 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.Assert;
/**
* Register a {@link SpringApplicationLifecycleMXBean} implementation to the platform
* Register a {@link SpringApplicationAdminMXBean} implementation to the platform
* {@link MBeanServer}.
*
* @author Stephane Nicoll
* @since 1.3.0
*/
public class SpringApplicationLifecycleRegistrar implements ApplicationContextAware,
public class SpringApplicationAdminMXBeanRegistrar implements ApplicationContextAware,
InitializingBean, DisposableBean, ApplicationListener<ApplicationReadyEvent> {
private static final Log logger = LogFactory.getLog(SpringApplicationLifecycle.class);
@ -52,7 +52,7 @@ public class SpringApplicationLifecycleRegistrar implements ApplicationContextAw
private boolean ready = false;
public SpringApplicationLifecycleRegistrar(String name)
public SpringApplicationAdminMXBeanRegistrar(String name)
throws MalformedObjectNameException {
this.objectName = new ObjectName(name);
}
@ -85,17 +85,17 @@ public class SpringApplicationLifecycleRegistrar implements ApplicationContextAw
ManagementFactory.getPlatformMBeanServer().unregisterMBean(this.objectName);
}
private class SpringApplicationLifecycle implements SpringApplicationLifecycleMXBean {
private class SpringApplicationLifecycle implements SpringApplicationAdminMXBean {
@Override
public boolean isReady() {
return SpringApplicationLifecycleRegistrar.this.ready;
return SpringApplicationAdminMXBeanRegistrar.this.ready;
}
@Override
public void shutdown() {
logger.info("Application shutdown requested.");
SpringApplicationLifecycleRegistrar.this.applicationContext.close();
SpringApplicationAdminMXBeanRegistrar.this.applicationContext.close();
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed 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.
*/
/**
* Administration support for Spring Boot applications.
*/
package org.springframework.boot.admin;

View File

@ -29,6 +29,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@ -39,7 +40,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link SpringApplicationLifecycleRegistrar}.
* Tests for {@link SpringApplicationAdminMXBeanRegistrar}.
*
* @author Stephane Nicoll
*/
@ -133,9 +134,9 @@ public class SpringApplicationLifecycleRegistrarTests {
static class Config {
@Bean
public SpringApplicationLifecycleRegistrar springApplicationLifecycle()
public SpringApplicationAdminMXBeanRegistrar springApplicationLifecycle()
throws MalformedObjectNameException {
return new SpringApplicationLifecycleRegistrar(OBJECT_NAME);
return new SpringApplicationAdminMXBeanRegistrar(OBJECT_NAME);
}
}