Sping Boot Apache Camel 路线测试

q9yhzks0  于 2022-11-07  发布在  Apache
关注(0)|答案(4)|浏览(183)

我有一个Springboot应用程序,其中配置了一些Camel路由。

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:testQueuequeueEventHandler::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*。但是可以通过将SpringCamelContext.class添加到@SpringBootTest类来解决这个问题。但是我的ProducerTemplate仍然是null
请建议。我用的是 Camel 2. 18和春 Boot 1. 4。

k2arahey

k2arahey1#

在支持Spring Boot 2的Camel 2.22.0及后续版本中,您可以使用以下模板来测试支持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();
  }
}

Sping Boot 区分了@Configuration@TestConfiguration。初级配置将替换任何现有配置(如果在顶级类上进行了注解),而@TestConfiguration将在其他配置之外运行。
此外,应当理解,在较大的项目中,您可能会遇到自动配置问题,因为您不能依赖Sping Boot 2来正确配置您的自定义数据库池,或者在您具有特定的目录结构并且配置不在直接祖先目录中的情况下。在这种情况下,省略@EnableAutoConfiguration注解可能是更好的选择。为了告诉Spring仍然自动-配置Camel,您只需将CamelAutoConfiguration.class传递给@SpringBootTest中提到的类

@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = {
    Route1.class,
    Route2.class,
    RouteTest.Config.class,
    CamelAutoConfiguration.class
}

由于没有执行自动配置,Spring不会在您的测试类中加载测试配置,也不会初始化Camel。通过手动将这些配置添加到 Boot 类中,Spring将为您完成这一操作。

jk9hmnmh

jk9hmnmh2#

对于使用MQ和Sping 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"));
      }
    }

我使用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());
      }
    }

我使用以下依赖项:Sping Boot 2.1.4-RELEASE和Camel 2.23.2。完整的源代码可以在Github上找到。

eeq64g8w

eeq64g8w3#

这是我最后的做法:

@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();
        }
    }
anhgbhbe

anhgbhbe4#

您是否尝试使用Camel测试运行程序?

@RunWith(CamelSpringJUnit4ClassRunner.class)

如果使用camel-spring-boot依赖关系,您可能知道它使用自动配置来设置Camel:

CamelAutoConfiguration.java

这意味着您可能还需要在测试中添加@EnableAutoConfiguration

相关问题