我有一个Springboot应用程序,其中配置了一些驼峰路线。
public class CamelConfig {
private static final Logger LOG = LoggerFactory.getLogger(CamelConfig.class);
@Value("${activemq.broker.url:tcp://localhost:61616}")
String brokerUrl;
@Value("${activemq.broker.maxconnections:1}")
int maxConnections;
@Bean
ConnectionFactory jmsConnectionFactory() {
PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
pooledConnectionFactory.setMaxConnections(maxConnections);
return pooledConnectionFactory;
}
@Bean
public RoutesBuilder route() {
LOG.info("Initializing camel routes......................");
return new SpringRouteBuilder() {
@Override
public void configure() throws Exception {
from("activemq:testQueue")
.to("bean:queueEventHandler?method=handleQueueEvent");
}
};
}
}
我想测试从activemq:testQueue
到queueEventHandler::handleQueueEvent
的路由。我试过这里提到的不同东西http://camel.apache.org/camel-test.html,但似乎无法让它工作。
我正在尝试这样做:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {CamelConfig.class, CamelTestContextBootstrapper.class})
public class CamelRouteConfigTest {
@Produce(uri = "activemq:testQueue")
protected ProducerTemplate template;
@Test
public void testSendMatchingMessage() throws Exception {
template.sendBodyAndHeader("testJson", "foo", "bar");
// Verify handleQueueEvent(...) method is called on bean queueEventHandler by mocking
}
但是我的ProducerTemplate总是null
。我尝试了自动连接CamelContext,但遇到一个异常,它无法解析CamelContext。但这可以通过添加上下文来解决。类
到@SpringBootTest
类。但是我的ProducerTemplate
仍然是null
。
请建议。我使用的是Camel 2.18和Spring Boot 1.4。
我最后是这样做的:
@RunWith(SpringRunner.class)
public class CamelRouteConfigTest extends CamelTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(CamelRouteConfigTest.class);
private static BrokerService brokerSvc = new BrokerService();
@Mock
private QueueEventHandler queueEventHandler;
@BeforeClass
// Sets up an embedded broker
public static void setUpBroker() throws Exception {
brokerSvc.setBrokerName("TestBroker");
brokerSvc.addConnector("tcp://localhost:61616");
brokerSvc.setPersistent(false);
brokerSvc.setUseJmx(false);
brokerSvc.start();
}
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new CamelConfig().route();
}
// properties in .yml has to be loaded manually. Not sure of .properties file
@Override
protected Properties useOverridePropertiesWithPropertiesComponent() {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
try {
PropertySource<?> applicationYamlPropertySource = loader.load(
"properties", new ClassPathResource("application.yml"),null);// null indicated common properties for all profiles.
Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
Properties properties = new Properties();
properties.putAll(source);
return properties;
} catch (IOException e) {
LOG.error("application.yml file cannot be found.");
}
return null;
}
@Override
protected JndiRegistry createRegistry() throws Exception {
JndiRegistry jndi = super.createRegistry();
MockitoAnnotations.initMocks(this);
jndi.bind("queueEventHandler", queueEventHandler);
return jndi;
}
@Test
// Sleeping for a few seconds is necessary, because this line template.sendBody runs in a different thread and
// CamelTest takes a few seconds to do the routing.
public void testRoute() throws InterruptedException {
template.sendBody("activemq:productpushevent", "HelloWorld!");
Thread.sleep(2000);
verify(queueEventHandler, times(1)).handleQueueEvent(any());
}
@AfterClass
public static void shutDownBroker() throws Exception {
brokerSvc.stop();
}
}
对于使用MQ和Spring Boot的一条路由,如下所示:
@Component
public class InboundRoute extends RouteBuilder {
@Override
public void configure() {
JaxbDataFormat personDataFormat = new JaxbDataFormat();
personDataFormat.setContextPath(Person.class.getPackage().getName());
personDataFormat.setPrettyPrint(true);
from("direct:start").id("InboundRoute")
.log("inbound route")
.marshal(personDataFormat)
.to("log:com.company.app?showAll=true&multiline=true")
.convertBodyTo(String.class)
.inOnly("mq:q.empi.deim.in")
.transform(constant("DONE"));
}
}
为了替换endpoint并仅使用模拟,我使用了Advicewith:
@RunWith(CamelSpringBootRunner.class)
@UseAdviceWith
@SpringBootTest(classes = InboundApp.class)
@MockEndpoints("mock:a")
public class InboundRouteCamelTest {
@EndpointInject(uri = "mock:a")
private MockEndpoint mock;
@Produce(uri = "direct:start")
private ProducerTemplate template;
@Autowired
private CamelContext context;
@Test
public void whenInboundRouteIsCalled_thenSuccess() throws Exception {
mock.expectedMinimumMessageCount(1);
RouteDefinition route = context.getRouteDefinition("InboundRoute");
route.adviceWith(context, new AdviceWithRouteBuilder() {
@Override
public void configure() {
weaveByToUri("mq:q.empi.deim.in").replace().to("mock:a");
}
});
context.start();
String response = (String) template.requestBodyAndHeader("direct:start",
getSampleMessage("/SimplePatient.xml"), Exchange.CONTENT_TYPE, MediaType.APPLICATION_XML);
assertThat(response).isEqualTo("DONE");
mock.assertIsSatisfied();
}
private String getSampleMessage(String filename) throws Exception {
return IOUtils
.toString(this.getClass().getResourceAsStream(filename), StandardCharsets.UTF_8.name());
}
}
我使用以下依赖项:Spring Boot 2.1.4-RELEASE和Camel 2.23.2。完整的源代码可在Github上获得。
在支持Spring Boot 2的Camel 2.22.0和Continuous中,您可以使用以下模板测试支持Spring Boot 2的路由:
@RunWith(CamelSpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
...
})
@EnableAutoConfiguration
@DisableJmx
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class RouteTest {
@TestConfiguration
static class Config {
@Bean
CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
@Override
public void beforeApplicationStart(CamelContext camelContext) {
// configure Camel here
}
@Override
public void afterApplicationStart(CamelContext camelContext) {
// Start your manual routes here
}
};
}
@Bean
RouteBuilder routeBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
from("direct:someEndpoint").to("mock:done");
}
};
}
// further beans ...
}
@Produce(uri = "direct:start")
private ProducerTemplate template;
@EndpointInject(uri = "mock:done")
private MockEndpoint mockDone;
@Test
public void testCamelRoute() throws Exception {
mockDone.expectedMessageCount(1);
Map<String, Object> headers = new HashMap<>();
...
template.sendBodyAndHeaders("test", headers);
mockDone.assertIsSatisfied();
}
}
Spring Boot区分了@Configuration
和@TestConfiguration
。primer one将替换任何现有配置(如果在顶级类上进行了注释),而除了其他配置之外,还将运行@TestConfiguration
。
此外,在更大的项目中,您可能会遇到自动配置问题,因为您不能依靠Spring Boot 2来配置自定义数据库池或其他不正确的配置,或者在您有特定目录结构且配置不在直接祖先目录中的情况下。在这种情况下,最好省略@EnableAutoConfiguration
注释。为了让Spring仍然自动配置Camel,只需传递Camel自动配置。类
中提到的类@SpringBootTest
@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
Route1.class,
Route2.class,
RouteTest.Config.class,
CamelAutoConfiguration.class
}
由于不执行自动配置,Spring不会在测试类中加载测试配置,也不会初始化Camel。通过手动将这些配置添加到引导类中,Spring会帮你完成。
问题内容: 我尝试对Apache骆驼路线进行junit测试。像这样的东西: 构建器类的定义如下 “ myExportRouteProcessor”类仅从JPA存储库中获取一些数据,并将结果放入路由。我想要的是在测试类中触发此路由,以检查整个过程是否正确完成。当前,处理器未启动。我该怎么办? 问题答案: 您可以使用AdviceWithRouteBuilder#replaceFromWith直接替换测
我试着为阿帕奇骆驼路线做一个jUnit测试。类似于这样: builder类的定义如下 myExportRouteProcencer类只是从JPA存储库中获取一些数据,并将结果放入路由。我想要的是在测试类中触发此路由,以检查整个过程是否正确完成。目前,处理器没有被触发。我应该做些什么?
问题内容: 我一直在仔细研究Apache Camel文档,试图对它的两个 最基本 概念(端点和路由)有一个具体的了解,尽管这些术语在文档中各处都使用,但是我找不到真正定义它们的参考。是以及它们的用途。尽管它们的名称听起来很明显,而且我 想 我理解它们的含义,但是现在我已被分配到一项使我深深陷入Apache Camel Land的任务,而了解这些机制的绝对至关重要是。 我的猜测是,“端点”只是一个b
嗨,我在camel中有一个JMS消费者路由,我的要求是在特定事件时停止/暂停该路由(基于某个字段值),然后使用调度器恢复该路由。为此,我创建了两个路由,一个是我的原始jms消费者路由,另一个是调度程序路由,它们恢复jms消费者路由,虽然我能够暂停路由,但第二个路由不恢复暂停的路由,它显示的状态为已启动。 以下是我的两条路线 请帮助我如何实现上述场景。
我通过以下代码以编程方式创建JMS路由: 我有课: 我想在上述路由和endpoint之间交换一些信息/参数。根据我想要的参数值,选择要在这个消息侦听器容器中设置的连接工厂。 请让我知道我是否能够解释我的问题陈述。 还有其他方法可以实现这一点吗?我想在运行时构建连接工厂,路由也是如此。JmsEndpoint 中是否有任何方法可以用来了解路由 id?
我设置了一个endpoint,如下所示: 我用骆驼石英2.22.2和石英1.8.6 下面是从关闭到启动上下文的日志。