GH-3994: Register native hints for Graph model (#3996)

Fixes https://github.com/spring-projects/spring-integration/issues/3994

Essentially, migrate those hints from Spring Boot Actuator:
an `IntegrationGraphServer` can be used without Spring Boot

* Introduce `IntegrationGraphRuntimeHints` - implementation of `RuntimeHintsRegistrar`
to register reflection hints for `Graph` and top-level `IntegrationNode` types.
* Use `@ImportRuntimeHints` on the `IntegrationGraphServer` to make those hints
conditional.
This commit is contained in:
Artem Bilan
2023-01-23 14:22:42 -05:00
committed by GitHub
parent ebba37497f
commit f01e2b8553
4 changed files with 64 additions and 3 deletions

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2023 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
*
* https://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.
*/
package org.springframework.integration.graph;
import org.springframework.aot.hint.BindingReflectionHintsRegistrar;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
/**
* The {@link RuntimeHintsRegistrar} implementation for {@link Graph}
* (and related types) reflection hints registration.
*
* @author Artem Bilan
*
* @since 6.0.3
*/
class IntegrationGraphRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
new BindingReflectionHintsRegistrar()
.registerReflectionHints(hints.reflection(),
Graph.class,
ErrorCapableCompositeMessageHandlerNode.class,
ErrorCapableDiscardingMessageHandlerNode.class,
ErrorCapableMessageHandlerNode.class,
ErrorCapableRoutingNode.class,
MessageGatewayNode.class,
MessageProducerNode.class,
MessageSourceNode.class,
PollableChannelNode.class);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -34,6 +34,7 @@ import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.endpoint.IntegrationConsumer;
@@ -64,6 +65,7 @@ import org.springframework.messaging.PollableChannel;
* @since 4.3
*
*/
@ImportRuntimeHints(IntegrationGraphRuntimeHints.class)
public class IntegrationGraphServer implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
private static final float GRAPH_VERSION = 1.2f;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -33,11 +33,13 @@ import net.minidev.json.JSONArray;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.annotation.Filter;
import org.springframework.integration.annotation.InboundChannelAdapter;
@@ -91,6 +93,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@DirtiesContext
public class IntegrationGraphServerTests {
@Autowired
private ListableBeanFactory beanFactory;
@Autowired
private IntegrationGraphServer server;
@@ -238,6 +243,8 @@ public class IntegrationGraphServerTests {
assertThat(serviceActivator)
.containsEntry("integrationPatternType", "service_activator")
.containsEntry("integrationPatternCategory", "messaging_endpoint");
assertThat(this.beanFactory.findAnnotationOnBean("server", ImportRuntimeHints.class)).isNotNull();
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -77,6 +78,8 @@ public class IntegrationGraphControllerTests {
@Test
public void testIntegrationGraphGet() throws Exception {
assertThat(this.wac.findAnnotationOnBean("integrationGraphServer", ImportRuntimeHints.class)).isNotNull();
this.mockMvc.perform(get("/testIntegration")
.header(HttpHeaders.ORIGIN, "https://foo.bar.com")
.accept(MediaType.APPLICATION_JSON))
@@ -96,6 +99,7 @@ public class IntegrationGraphControllerTests {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
"IntegrationGraphControllerParserTests-context.xml", getClass());
assertThat(context.findAnnotationOnBean("integrationGraphServer", ImportRuntimeHints.class)).isNotNull();
HandlerMapping handlerMapping =
context.getBean(RequestMappingHandlerMapping.class.getName(), HandlerMapping.class);