Polish "Add actuator endpoint for exposing the Spring Integration graph"
Closes gh-12331
This commit is contained in:
parent
8c67ef1079
commit
03cf4fbb10
|
@ -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[]
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
@Configuration
|
assertThat(context).doesNotHaveBean(IntegrationGraphServer.class);
|
||||||
public static class TestConfiguration {
|
});
|
||||||
|
|
||||||
@Bean
|
|
||||||
public IntegrationGraphServer integrationGraphServer() {
|
|
||||||
return new IntegrationGraphServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void runWhenSpringIntegrationIsNotEnabledShouldNotHaveEndpointBean() {
|
||||||
|
ApplicationContextRunner noSiRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
IntegrationGraphEndpointAutoConfiguration.class));
|
||||||
|
noSiRunner.run((context) -> {
|
||||||
|
assertThat(context).doesNotHaveBean(IntegrationGraphEndpoint.class);
|
||||||
|
assertThat(context).doesNotHaveBean(IntegrationGraphServer.class);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue