Skip to content

Commit fab7741

Browse files
committed
Shorten internal component names for graph (#3128)
* Shorten internal component names for graph The long `IntegrationContextUtils.ERROR_LOGGER_BEAN_NAME` name is used for `errorChannel` `LoggingHandler`'s endpoint. It is too long for endpoint node in the graph meanwhile the `errorChannel` is good everywhere * Change an `IntegrationGraphServer` logic to shorten internal component names before drawing a graph * Introduce `IntegrationUtils.obtainComponentName()` for shortening an internal name if any * Use `IntegrationConfigUtils.BASE_PACKAGE` in the `IntegrationMBeanExporter` instead of its own static property * Remove `IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE` in favor of introduced in SF `FactoryBean.OBJECT_TYPE_ATTRIBUTE` * Rework affected test classes to JUnit 5 * Remove usage of deprecated options in the `@EnableIntegrationManagement` * Document names shortening feature for graph * * Improve `obtainComponentName()` function
1 parent c08f4ec commit fab7741

File tree

9 files changed

+61
-74
lines changed

9 files changed

+61
-74
lines changed

spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigUtils.java

-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ public final class IntegrationConfigUtils {
3535

3636
public static final String HANDLER_ALIAS_SUFFIX = ".handler";
3737

38-
// TODO: Boot constant - move to Spring Framework?
39-
public static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
40-
4138
public static void registerSpelFunctionBean(BeanDefinitionRegistry registry, String functionId, String className,
4239
String methodSignature) {
4340

spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import java.util.Map.Entry;
2424
import java.util.Set;
2525

26-
import org.springframework.beans.BeanMetadataAttribute;
2726
import org.springframework.beans.factory.BeanDefinitionStoreException;
27+
import org.springframework.beans.factory.FactoryBean;
2828
import org.springframework.beans.factory.config.BeanDefinition;
2929
import org.springframework.beans.factory.config.BeanDefinitionHolder;
3030
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -176,9 +176,7 @@ else if (StringUtils.hasText(asyncExecutor)) {
176176
gatewayProxyBuilder.addConstructorArgValue(serviceInterface);
177177

178178
AbstractBeanDefinition beanDefinition = gatewayProxyBuilder.getBeanDefinition();
179-
beanDefinition.addMetadataAttribute(new BeanMetadataAttribute(IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE,
180-
serviceInterface));
181-
179+
beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, serviceInterface);
182180
return new BeanDefinitionHolder(beanDefinition, id);
183181
}
184182

@@ -188,7 +186,7 @@ else if (StringUtils.hasText(asyncExecutor)) {
188186
* @param importingClassMetadata The importing class metadata
189187
* @return The captured values.
190188
*/
191-
private static List<MultiValueMap<String, Object>> captureMetaAnnotationValues(
189+
private static List<MultiValueMap<String, Object>> captureMetaAnnotationValues(
192190
AnnotationMetadata importingClassMetadata) {
193191

194192
Set<String> directAnnotations = importingClassMetadata.getAnnotationTypes();

spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.springframework.integration.router.RecipientListRouterManagement;
4949
import org.springframework.integration.support.context.NamedComponent;
5050
import org.springframework.integration.support.management.MappingMessageRouterManagement;
51+
import org.springframework.integration.support.utils.IntegrationUtils;
5152
import org.springframework.lang.Nullable;
5253
import org.springframework.messaging.MessageChannel;
5354
import org.springframework.messaging.MessageHandler;
@@ -65,7 +66,7 @@
6566
*/
6667
public class IntegrationGraphServer implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
6768

68-
private static final float GRAPH_VERSION = 1.1f;
69+
private static final float GRAPH_VERSION = 1.2f;
6970

7071
private static MicrometerNodeEnhancer micrometerEnhancer;
7172

@@ -377,7 +378,7 @@ MessageGatewayNode gatewayNode(String name, MessagingGatewaySupport gateway) {
377378
}
378379

379380
@Nullable
380-
String channelToBeanName(MessageChannel messageChannel) {
381+
private String channelToBeanName(MessageChannel messageChannel) {
381382
return messageChannel instanceof NamedComponent
382383
? ((NamedComponent) messageChannel).getBeanName()
383384
: Objects.toString(messageChannel, null);
@@ -396,7 +397,7 @@ MessageSourceNode sourceNode(String name, SourcePollingChannelAdapter adapter) {
396397
String nameToUse = name;
397398
MessageSource<?> source = adapter.getMessageSource();
398399
if (source instanceof NamedComponent) {
399-
nameToUse = ((NamedComponent) source).getComponentName();
400+
nameToUse = IntegrationUtils.obtainComponentName((NamedComponent) source);
400401
}
401402
MessageSourceNode node = new MessageSourceNode(this.nodeId.incrementAndGet(), nameToUse, source,
402403
outputChannel, errorChannel);
@@ -412,7 +413,7 @@ MessageHandlerNode handlerNode(String nameArg, IntegrationConsumer consumer) {
412413
MessageHandlerNode node;
413414
String name = nameArg;
414415
if (handler instanceof NamedComponent) {
415-
name = ((NamedComponent) handler).getComponentName();
416+
name = IntegrationUtils.obtainComponentName((NamedComponent) handler);
416417
}
417418
if (handler instanceof CompositeMessageHandler) {
418419
node = compositeHandler(name, consumer, (CompositeMessageHandler) handler, outputChannelName, null,
@@ -448,7 +449,7 @@ MessageHandlerNode polledHandlerNode(String nameArg, PollingConsumer consumer) {
448449
MessageHandlerNode node;
449450
String name = nameArg;
450451
if (handler instanceof NamedComponent) {
451-
name = ((NamedComponent) handler).getComponentName();
452+
name = IntegrationUtils.obtainComponentName((NamedComponent) handler);
452453
}
453454
if (handler instanceof CompositeMessageHandler) {
454455
node = compositeHandler(name, consumer, (CompositeMessageHandler) handler, outputChannelName,
@@ -487,7 +488,7 @@ MessageHandlerNode compositeHandler(String name, IntegrationConsumer consumer,
487488
.map(NamedComponent.class::cast)
488489
.map(named ->
489490
new CompositeMessageHandlerNode.InnerHandler(
490-
named.getComponentName(),
491+
IntegrationUtils.obtainComponentName(named),
491492
named.getComponentType()))
492493
.collect(Collectors.toList());
493494

spring-integration-core/src/main/java/org/springframework/integration/support/utils/IntegrationUtils.java

+25-9
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424

2525
import org.springframework.beans.factory.BeanFactory;
2626
import org.springframework.core.convert.ConversionService;
27+
import org.springframework.integration.config.IntegrationConfigUtils;
2728
import org.springframework.integration.support.DefaultMessageBuilderFactory;
2829
import org.springframework.integration.support.MessageBuilderFactory;
30+
import org.springframework.integration.support.context.NamedComponent;
31+
import org.springframework.lang.Nullable;
2932
import org.springframework.messaging.Message;
3033
import org.springframework.messaging.MessageDeliveryException;
3134
import org.springframework.messaging.MessageHandlingException;
@@ -44,18 +47,19 @@
4447
*/
4548
public final class IntegrationUtils {
4649

47-
private static final Log logger = LogFactory.getLog(IntegrationUtils.class);
50+
private static final Log LOGGER = LogFactory.getLog(IntegrationUtils.class);
51+
52+
private static final String INTERNAL_COMPONENT_PREFIX = '_' + IntegrationConfigUtils.BASE_PACKAGE;
4853

4954
public static final String INTEGRATION_CONVERSION_SERVICE_BEAN_NAME = "integrationConversionService";
5055

5156
public static final String INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME = "messageBuilderFactory";
5257

53-
5458
/**
5559
* Should be set to TRUE on CI plans and framework developer systems.
5660
*/
5761
public static final boolean fatalWhenNoBeanFactory =
58-
Boolean.valueOf(System.getenv("SI_FATAL_WHEN_NO_BEANFACTORY"));
62+
Boolean.parseBoolean(System.getenv("SI_FATAL_WHEN_NO_BEANFACTORY"));
5963

6064
private IntegrationUtils() {
6165
super();
@@ -75,26 +79,24 @@ public static ConversionService getConversionService(BeanFactory beanFactory) {
7579
* @param beanFactory The bean factory.
7680
* @return The message builder factory.
7781
*/
78-
public static MessageBuilderFactory getMessageBuilderFactory(BeanFactory beanFactory) {
82+
public static MessageBuilderFactory getMessageBuilderFactory(@Nullable BeanFactory beanFactory) {
7983
MessageBuilderFactory messageBuilderFactory = null;
8084
if (beanFactory != null) {
8185
try {
8286
messageBuilderFactory = beanFactory.getBean(
8387
INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, MessageBuilderFactory.class);
8488
}
8589
catch (Exception e) {
86-
if (logger.isDebugEnabled()) {
87-
logger.debug("No MessageBuilderFactory with name '"
90+
if (LOGGER.isDebugEnabled()) {
91+
LOGGER.debug("No MessageBuilderFactory with name '"
8892
+ INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME
8993
+ "' found: " + e.getMessage()
9094
+ ", using default.");
9195
}
9296
}
9397
}
9498
else {
95-
if (logger.isDebugEnabled()) {
96-
logger.debug("No 'beanFactory' supplied; cannot find MessageBuilderFactory, using default.");
97-
}
99+
LOGGER.debug("No 'beanFactory' supplied; cannot find MessageBuilderFactory, using default.");
98100
if (fatalWhenNoBeanFactory) {
99101
throw new IllegalStateException("All Message creators need a BeanFactory");
100102
}
@@ -193,4 +195,18 @@ public static RuntimeException wrapInHandlingExceptionIfNecessary(Message<?> mes
193195
return runtimeException;
194196
}
195197

198+
/**
199+
* Obtain a component name from the provided {@link NamedComponent}.
200+
* @param component the {@link NamedComponent} source for component name.
201+
* @return the component name
202+
* @since 5.3
203+
*/
204+
public static String obtainComponentName(NamedComponent component) {
205+
String name = component.getComponentName();
206+
if (name.charAt(0) == '_' && name.startsWith(INTERNAL_COMPONENT_PREFIX)) {
207+
name = name.substring((INTERNAL_COMPONENT_PREFIX).length() + 1);
208+
}
209+
return name;
210+
}
211+
196212
}

spring-integration-core/src/test/java/org/springframework/integration/config/xml/GatewayParserTests.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535

3636
import org.springframework.beans.DirectFieldAccessor;
3737
import org.springframework.beans.factory.BeanNameAware;
38+
import org.springframework.beans.factory.FactoryBean;
3839
import org.springframework.beans.factory.annotation.Autowired;
3940
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
4041
import org.springframework.context.ApplicationContext;
4142
import org.springframework.context.support.GenericApplicationContext;
4243
import org.springframework.core.task.SimpleAsyncTaskExecutor;
4344
import org.springframework.expression.Expression;
4445
import org.springframework.integration.channel.QueueChannel;
45-
import org.springframework.integration.config.IntegrationConfigUtils;
4646
import org.springframework.integration.gateway.GatewayMethodMetadata;
4747
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
4848
import org.springframework.integration.gateway.RequestReplyExchanger;
@@ -177,16 +177,16 @@ public void testAsyncDisabledGateway() throws Exception {
177177
@Test
178178
public void testFactoryBeanObjectTypeWithServiceInterface() {
179179
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory();
180-
Object attribute = beanFactory.getMergedBeanDefinition("&oneWay").getAttribute(
181-
IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE);
180+
Object attribute =
181+
beanFactory.getMergedBeanDefinition("&oneWay").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
182182
assertThat(attribute).isEqualTo(TestService.class.getName());
183183
}
184184

185185
@Test
186186
public void testFactoryBeanObjectTypeWithNoServiceInterface() {
187187
ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory();
188-
Object attribute = beanFactory.getMergedBeanDefinition("&defaultConfig").getAttribute(
189-
IntegrationConfigUtils.FACTORY_BEAN_OBJECT_TYPE);
188+
Object attribute =
189+
beanFactory.getMergedBeanDefinition("&defaultConfig").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE);
190190
assertThat(attribute).isEqualTo(RequestReplyExchanger.class.getName());
191191
}
192192

spring-integration-http/src/test/java/org/springframework/integration/http/management/IntegrationGraphControllerTests.java

+7-13
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
2525

2626
import org.hamcrest.Matchers;
27-
import org.junit.Before;
28-
import org.junit.Test;
29-
import org.junit.runner.RunWith;
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.Test;
3029

3130
import org.springframework.beans.factory.annotation.Autowired;
3231
import org.springframework.context.ConfigurableApplicationContext;
@@ -43,8 +42,7 @@
4342
import org.springframework.mock.web.MockHttpServletResponse;
4443
import org.springframework.test.annotation.DirtiesContext;
4544
import org.springframework.test.context.TestPropertySource;
46-
import org.springframework.test.context.junit4.SpringRunner;
47-
import org.springframework.test.context.web.WebAppConfiguration;
45+
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;
4846
import org.springframework.test.web.servlet.MockMvc;
4947
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
5048
import org.springframework.web.context.WebApplicationContext;
@@ -62,8 +60,7 @@
6260
*
6361
* @since 4.3
6462
*/
65-
@RunWith(SpringRunner.class)
66-
@WebAppConfiguration
63+
@SpringJUnitWebConfig
6764
@TestPropertySource(properties = "spring.application.name:testApplication")
6865
@DirtiesContext
6966
public class IntegrationGraphControllerTests {
@@ -73,7 +70,7 @@ public class IntegrationGraphControllerTests {
7370

7471
private MockMvc mockMvc;
7572

76-
@Before
73+
@BeforeEach
7774
public void setup() {
7875
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
7976
}
@@ -88,8 +85,7 @@ public void testIntegrationGraphGet() throws Exception {
8885
.andExpect(handler().handlerType(IntegrationGraphController.class))
8986
.andExpect(handler().methodName("getGraph"))
9087
.andExpect(jsonPath("$.nodes..name")
91-
.value(Matchers.containsInAnyOrder("nullChannel", "errorChannel",
92-
"_org.springframework.integration.errorLogger")))
88+
.value(Matchers.containsInAnyOrder("nullChannel", "errorChannel", "errorLogger")))
9389
// .andDo(print())
9490
.andExpect(jsonPath("$.contentDescriptor.name").value("testApplication"))
9591
.andExpect(jsonPath("$.links").exists());
@@ -154,9 +150,7 @@ public void testIntegrationGraphControllerParser() throws Exception {
154150
@Configuration
155151
@EnableWebMvc
156152
@EnableIntegration
157-
@EnableIntegrationManagement(statsEnabled = "_org.springframework.integration.errorLogger.handler",
158-
countsEnabled = "!*",
159-
defaultLoggingEnabled = "false")
153+
@EnableIntegrationManagement(defaultLoggingEnabled = "false")
160154
@EnableIntegrationGraphController(path = "/testIntegration", allowedOrigins = "https://foo.bar.com")
161155
public static class ContextConfiguration {
162156

spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java

+9-10
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.springframework.context.ApplicationContextAware;
4444
import org.springframework.context.Lifecycle;
4545
import org.springframework.integration.channel.QueueChannel;
46+
import org.springframework.integration.config.IntegrationConfigUtils;
4647
import org.springframework.integration.config.IntegrationManagementConfigurer;
4748
import org.springframework.integration.context.IntegrationContextUtils;
4849
import org.springframework.integration.context.OrderlyShutdownCapable;
@@ -111,9 +112,7 @@
111112
public class IntegrationMBeanExporter extends MBeanExporter
112113
implements ApplicationContextAware, DestructionAwareBeanPostProcessor {
113114

114-
private static final String SI_PACKAGE = "org.springframework.integration";
115-
116-
public static final String DEFAULT_DOMAIN = SI_PACKAGE;
115+
public static final String DEFAULT_DOMAIN = IntegrationConfigUtils.BASE_PACKAGE;
117116

118117
private final IntegrationJmxAttributeSource attributeSource = new IntegrationJmxAttributeSource();
119118

@@ -827,7 +826,7 @@ private void registerEndpoint(AbstractEndpoint endpoint) {
827826
String beanKey;
828827
String name = endpoint.getComponentName();
829828
String source;
830-
if (name.startsWith('_' + SI_PACKAGE)) {
829+
if (name.startsWith('_' + IntegrationConfigUtils.BASE_PACKAGE)) {
831830
name = getInternalComponentName(name);
832831
source = "internal";
833832
}
@@ -881,7 +880,7 @@ private Object extractTarget(Object bean) {
881880

882881
private String getChannelBeanKey(String channel) {
883882
String extra = "";
884-
if (channel.startsWith(SI_PACKAGE)) {
883+
if (channel.startsWith(IntegrationConfigUtils.BASE_PACKAGE)) {
885884
extra = ",source=anonymous";
886885
}
887886
return String.format(this.domain + ":type=MessageChannel,name=%s%s" + getStaticNames(),
@@ -979,11 +978,11 @@ private org.springframework.integration.support.management.MessageHandlerMetrics
979978
String managedType = source;
980979
String managedName = name;
981980

982-
if (managedName != null && managedName.startsWith('_' + SI_PACKAGE)) {
981+
if (managedName != null && managedName.startsWith('_' + IntegrationConfigUtils.BASE_PACKAGE)) {
983982
managedName = getInternalComponentName(managedName);
984983
managedType = "internal";
985984
}
986-
if (managedName != null && name.startsWith(SI_PACKAGE)) {
985+
if (managedName != null && name.startsWith(IntegrationConfigUtils.BASE_PACKAGE)) {
987986
MessageChannel inputChannel = endpoint.getInputChannel();
988987
if (inputChannel != null) {
989988
managedName = buildAnonymousManagedName(this.anonymousHandlerCounters, inputChannel);
@@ -1058,7 +1057,7 @@ private String buildAnonymousManagedName(Map<Object, AtomicLong> anonymousCache,
10581057
}
10591058

10601059
private String getInternalComponentName(String name) {
1061-
return name.substring(('_' + SI_PACKAGE).length() + 1);
1060+
return name.substring(('_' + IntegrationConfigUtils.BASE_PACKAGE).length() + 1);
10621061
}
10631062

10641063
private org.springframework.integration.support.management.MessageSourceMetrics enhanceSourceMonitor(
@@ -1075,7 +1074,7 @@ private org.springframework.integration.support.management.MessageSourceMetrics
10751074
if (endpoint != null) {
10761075
endpointName = endpoint.getBeanName();
10771076
}
1078-
if (endpointName != null && endpointName.startsWith('_' + SI_PACKAGE)) {
1077+
if (endpointName != null && endpointName.startsWith('_' + IntegrationConfigUtils.BASE_PACKAGE)) {
10791078
endpointName = getInternalComponentName(endpointName);
10801079
source = "internal";
10811080
}
@@ -1115,7 +1114,7 @@ private org.springframework.integration.support.management.MessageSourceMetrics
11151114
String managedType = source;
11161115
String managedName = name;
11171116

1118-
if (managedName != null && managedName.startsWith(SI_PACKAGE)) {
1117+
if (managedName != null && managedName.startsWith(IntegrationConfigUtils.BASE_PACKAGE)) {
11191118
Object target = endpoint;
11201119
if (endpoint instanceof Advised) {
11211120
TargetSource targetSource = ((Advised) endpoint).getTargetSource();

0 commit comments

Comments
 (0)