Polish "Add actuator endpoint for exposing the Spring Integration graph"

Closes gh-12331
This commit is contained in:
Stephane Nicoll 2018-04-17 15:40:39 +02:00
parent 8c67ef1079
commit 03cf4fbb10
11 changed files with 64 additions and 63 deletions

View File

@ -1,7 +1,8 @@
[[integrationgraph]] [[integrationgraph]]
= Spring Integration graph (`integrationgraph`) = Spring Integration graph (`integrationgraph`)
The `integrationgraph` endpoint exposes a graph containing all Spring Integration components. The `integrationgraph` endpoint exposes a graph containing all Spring Integration
components.
@ -22,16 +23,18 @@ include::{snippets}integrationgraph/graph/http-response.adoc[]
[[integrationgraph-retrieving-response-structure]] [[integrationgraph-retrieving-response-structure]]
=== Response Structure === Response Structure
The response contains all Spring Integration components used within the application, as well as the links between them. The response contains all Spring Integration components used within the application, as
More information about the structure can be found in the https://docs.spring.io/spring-integration/reference/html/system-management-chapter.html#integration-graph[subchapter] for the integration graph in the reference documentation of Spring Integration. well as the links between them. More information about the structure can be found in the
https://docs.spring.io/spring-integration/reference/html/system-management-chapter.html#integration-graph[reference
documentation].
[[integrationgraph-rebuilding]] [[integrationgraph-rebuilding]]
== Rebuilding the Spring Integration graph == Rebuilding the Spring Integration graph
To rebuild the exposed graph, make a `POST` request to To rebuild the exposed graph, make a `POST` request to `/actuator/integrationgraph`, as
`/actuator/integrationgraph`, as shown in the following curl-based example: shown in the following curl-based example:
include::{snippets}integrationgraph/rebuild/curl-request.adoc[] include::{snippets}integrationgraph/rebuild/curl-request.adoc[]

View File

@ -18,26 +18,31 @@ package org.springframework.boot.actuate.autoconfigure.integration;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint; import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.integration.support.channel.HeaderChannelRegistry;
import org.springframework.integration.support.management.graph.IntegrationGraphServer; import org.springframework.integration.support.management.graph.IntegrationGraphServer;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for the {@link IntegrationGraphEndpoint}. * {@link EnableAutoConfiguration Auto-configuration} for the {@link IntegrationGraphEndpoint}.
* *
* @author Tim Ysewyn * @author Tim Ysewyn
* @author Stephane Nicoll
* @since 2.1.0 * @since 2.1.0
*/ */
@Configuration @Configuration
@ConditionalOnClass(IntegrationGraphServer.class) @ConditionalOnClass(IntegrationGraphServer.class)
@ConditionalOnBean(HeaderChannelRegistry.class)
@AutoConfigureAfter(IntegrationAutoConfiguration.class)
public class IntegrationGraphEndpointAutoConfiguration { public class IntegrationGraphEndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnBean(IntegrationGraphServer.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint @ConditionalOnEnabledEndpoint
public IntegrationGraphEndpoint integrationGraphEndpoint( public IntegrationGraphEndpoint integrationGraphEndpoint(
@ -45,5 +50,12 @@ public class IntegrationGraphEndpointAutoConfiguration {
return new IntegrationGraphEndpoint(integrationGraphServer); return new IntegrationGraphEndpoint(integrationGraphServer);
} }
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint(endpoint = IntegrationGraphEndpoint.class)
public IntegrationGraphServer integrationGraphServer() {
return new IntegrationGraphServer();
}
} }

View File

@ -45,7 +45,8 @@ public class IntegrationGraphEndpointDocumentationTests extends MockMvcEndpointD
@Test @Test
public void rebuild() throws Exception { public void rebuild() throws Exception {
this.mockMvc.perform(post("/actuator/integrationgraph")).andExpect(status().isNoContent()) this.mockMvc.perform(post("/actuator/integrationgraph")).andExpect(status()
.isNoContent())
.andDo(MockMvcRestDocumentation.document("integrationgraph/rebuild")); .andDo(MockMvcRestDocumentation.document("integrationgraph/rebuild"));
} }

View File

@ -20,9 +20,9 @@ import org.junit.Test;
import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint; import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.support.management.graph.IntegrationGraphServer; import org.springframework.integration.support.management.graph.IntegrationGraphServer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -31,38 +31,40 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link IntegrationGraphEndpointAutoConfiguration}. * Tests for {@link IntegrationGraphEndpointAutoConfiguration}.
* *
* @author Tim Ysewyn * @author Tim Ysewyn
* @author Stephane Nicoll
*/ */
public class IntegrationGraphEndpointAutoConfigurationTests { public class IntegrationGraphEndpointAutoConfigurationTests {
private final ApplicationContextRunner contextRunnerWithoutIntegrationGraph = new ApplicationContextRunner() private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(IntegrationGraphEndpointAutoConfiguration.class)); .withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
IntegrationAutoConfiguration.class,
private final ApplicationContextRunner contextRunnerWithIntegrationGraph = new ApplicationContextRunner() IntegrationGraphEndpointAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(IntegrationGraphEndpointAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class);
@Test @Test
public void runShouldNotHaveEndpointBean() { public void runShouldHaveEndpointBean() {
this.contextRunnerWithoutIntegrationGraph.run((context) -> assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class)); this.contextRunner.run((context) -> assertThat(context)
this.contextRunnerWithoutIntegrationGraph.withPropertyValues("management.endpoint.integrationgraph.enabled:true") .hasSingleBean(IntegrationGraphEndpoint.class));
.run((context) -> assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class));
this.contextRunnerWithIntegrationGraph.run((context) -> assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class));
} }
@Test @Test
public void runWhenEnabledPropertyIsTrueShouldHaveEndpointBean() { public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() {
this.contextRunnerWithIntegrationGraph.withPropertyValues("management.endpoint.integrationgraph.enabled:true") this.contextRunner
.run((context) -> assertThat(context).hasSingleBean(IntegrationGraphEndpoint.class)); .withPropertyValues("management.endpoint.integrationgraph.enabled:false")
.run((context) -> {
assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class);
assertThat(context).doesNotHaveBean(IntegrationGraphServer.class);
});
} }
@Configuration @Test
public static class TestConfiguration { public void runWhenSpringIntegrationIsNotEnabledShouldNotHaveEndpointBean() {
ApplicationContextRunner noSiRunner = new ApplicationContextRunner()
@Bean .withConfiguration(AutoConfigurations.of(
public IntegrationGraphServer integrationGraphServer() { IntegrationGraphEndpointAutoConfiguration.class));
return new IntegrationGraphServer(); noSiRunner.run((context) -> {
} assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class);
assertThat(context).doesNotHaveBean(IntegrationGraphServer.class);
});
} }
} }

View File

@ -28,31 +28,28 @@ import org.springframework.integration.support.management.graph.IntegrationGraph
* @author Tim Ysewyn * @author Tim Ysewyn
* @since 2.1.0 * @since 2.1.0
*/ */
@Endpoint(id = "integrationgraph", enableByDefault = false) @Endpoint(id = "integrationgraph")
public class IntegrationGraphEndpoint { public class IntegrationGraphEndpoint {
private final IntegrationGraphServer integrationGraphServer; private final IntegrationGraphServer graphServer;
/** /**
* Creates a new {@code IntegrationGraphEndpoint} that exposes a graph containing all the * Create a new {@code IntegrationGraphEndpoint} that exposes a graph containing all
* Spring Integration components in the given {@code integrationGraphServer}. * the Spring Integration components in the given {@link IntegrationGraphServer}.
* * @param graphServer the integration graph server
* @param integrationGraphServer the integration graph server
* @see IntegrationGraphServer
*/ */
public IntegrationGraphEndpoint(IntegrationGraphServer integrationGraphServer) { public IntegrationGraphEndpoint(IntegrationGraphServer graphServer) {
this.integrationGraphServer = integrationGraphServer; this.graphServer = graphServer;
} }
@ReadOperation @ReadOperation
public Graph graph() { public Graph graph() {
return this.integrationGraphServer.getGraph(); return this.graphServer.getGraph();
} }
@WriteOperation @WriteOperation
public void rebuild() { public void rebuild() {
this.integrationGraphServer.rebuild(); this.graphServer.rebuild();
} }
} }

View File

@ -15,6 +15,6 @@
*/ */
/** /**
* Actuator support relating to Spring Integration. * Actuator support for Spring Integration.
*/ */
package org.springframework.boot.actuate.integration; package org.springframework.boot.actuate.integration;

View File

@ -49,21 +49,18 @@ public class IntegrationGraphEndpointTests {
} }
@Test @Test
public void shouldReturnGraph() { public void readOperationShouldReturnGraph() {
Graph mockedGraph = mock(Graph.class); Graph mockedGraph = mock(Graph.class);
when(this.integrationGraphServer.getGraph()).thenReturn(mockedGraph); when(this.integrationGraphServer.getGraph()).thenReturn(mockedGraph);
Graph graph = this.integrationGraphEndpoint.graph(); Graph graph = this.integrationGraphEndpoint.graph();
verify(this.integrationGraphServer).getGraph(); verify(this.integrationGraphServer).getGraph();
assertThat(graph).isEqualTo(mockedGraph); assertThat(graph).isEqualTo(mockedGraph);
} }
@Test @Test
public void shouldRebuildGraph() { public void writeOperationShouldRebuildGraph() {
this.integrationGraphEndpoint.rebuild(); this.integrationGraphEndpoint.rebuild();
verify(this.integrationGraphServer).rebuild(); verify(this.integrationGraphServer).rebuild();
} }

View File

@ -41,7 +41,7 @@ public class IntegrationGraphEndpointWebIntegrationTests {
public void graph() { public void graph() {
client.get().uri("/actuator/integrationgraph").accept(MediaType.APPLICATION_JSON).exchange() client.get().uri("/actuator/integrationgraph").accept(MediaType.APPLICATION_JSON).exchange()
.expectStatus().isOk().expectBody() .expectStatus().isOk().expectBody()
.jsonPath("contentDescriptor.providerVersion").isEqualTo("5.0.3.RELEASE") .jsonPath("contentDescriptor.providerVersion").isNotEmpty()
.jsonPath("contentDescriptor.providerFormatVersion").isEqualTo(1.0f) .jsonPath("contentDescriptor.providerFormatVersion").isEqualTo(1.0f)
.jsonPath("contentDescriptor.provider").isEqualTo("spring-integration"); .jsonPath("contentDescriptor.provider").isEqualTo("spring-integration");
} }

View File

@ -43,7 +43,6 @@ import org.springframework.integration.jdbc.store.JdbcMessageStore;
import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport; import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport;
import org.springframework.integration.monitor.IntegrationMBeanExporter; import org.springframework.integration.monitor.IntegrationMBeanExporter;
import org.springframework.integration.support.management.IntegrationManagementConfigurer; import org.springframework.integration.support.management.IntegrationManagementConfigurer;
import org.springframework.integration.support.management.graph.IntegrationGraphServer;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -55,7 +54,6 @@ import org.springframework.util.StringUtils;
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Vedran Pavic * @author Vedran Pavic
* @author Madhura Bhave * @author Madhura Bhave
* @author Tim Ysewyn
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration @Configuration
@ -71,12 +69,6 @@ public class IntegrationAutoConfiguration {
@EnableIntegration @EnableIntegration
protected static class IntegrationConfiguration { protected static class IntegrationConfiguration {
@Bean
@ConditionalOnMissingBean
public IntegrationGraphServer integrationGraphServer() {
return new IntegrationGraphServer();
}
} }
/** /**

View File

@ -42,7 +42,6 @@ import org.springframework.integration.gateway.RequestReplyExchanger;
import org.springframework.integration.handler.MessageProcessor; import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.support.channel.HeaderChannelRegistry; import org.springframework.integration.support.channel.HeaderChannelRegistry;
import org.springframework.integration.support.management.IntegrationManagementConfigurer; import org.springframework.integration.support.management.IntegrationManagementConfigurer;
import org.springframework.integration.support.management.graph.IntegrationGraphServer;
import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jmx.export.MBeanExporter; import org.springframework.jmx.export.MBeanExporter;
@ -56,7 +55,6 @@ import static org.mockito.Mockito.mock;
* @author Artem Bilan * @author Artem Bilan
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Vedran Pavic * @author Vedran Pavic
* @author Tim Ysewyn
*/ */
public class IntegrationAutoConfigurationTests { public class IntegrationAutoConfigurationTests {
@ -70,7 +68,6 @@ public class IntegrationAutoConfigurationTests {
@Test @Test
public void integrationIsAvailable() { public void integrationIsAvailable() {
this.contextRunner.run((context) -> { this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(IntegrationGraphServer.class);
assertThat(context).hasSingleBean(TestGateway.class); assertThat(context).hasSingleBean(TestGateway.class);
assertThat(context) assertThat(context)
.hasSingleBean(IntegrationComponentScanAutoConfiguration.class); .hasSingleBean(IntegrationComponentScanAutoConfiguration.class);

View File

@ -106,8 +106,8 @@ exchanges).
|Yes |Yes
|`integrationgraph` |`integrationgraph`
|Exposes the Spring Integration graph. |Shows the Spring Integration graph.
|No |Yes
|`loggers` |`loggers`
|Shows and modifies the configuration of loggers in the application. |Shows and modifies the configuration of loggers in the application.