使用apache camel进行测试回滚事务

时间:2015-10-03 10:02:33

标签: java transactions apache-camel integration-testing message-queue

我正在努力进行一项有效的junit测试,以回滚在camel路由期间发生的操作。

我有一个侦听目录的camel路由设置。它期待一个csv文件。当csv文件出现时,它会创建新的SearchAnalytics数据。它在csv文件中的每一行中向表中添加一个新行。

我放置的默认spring事务方法似乎不适用于camel路由上发生的操作。

以下代码有效。但是,它会永久保存数据,并且不会回滚插入数据。这意味着测试只会传递一次,除非我手动删除数据。

  

鉴于我的示例代码如何使其回滚事务?

我的路线看起来像这样

from("ftp://some__remote__ftp_dir_path")
  .routeId("searchAnalyticsImport")             
  .choice()
    .when(simple("${in.header.CamelFileName} contains '.csv'"))
    .split().method("csvSplitter", "iterator").streaming() // reads the csv file returns data objects
    .processRef("searchAnalyticsProcesser")  // this some dao saves
    .to(Queues.SOME_REQUEST)
.end();

Junit测试

@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { TestAppConfig.class})
public class searchAnalyticsImportTest  {

    @EndpointInject(uri = "mock:sippmatcher.requestqueue?preserveMessageQos=true")
    private MockEndpoint mockEndpointRequest;

    @Before
    public void setup() throws Exception {

        camelContext.getRouteDefinition("searchAnalyticsImport").adviceWith(camelContext, new AdviceWithRouteBuilder() {
            @Override
            public void configure() throws Exception {

                replaceFromWith("file://"+this.getClass().getResource("path to folder etc...")+"?noop=true");

                interceptSendToEndpoint(Queues.SOME_REQUEST)
                        .skipSendToOriginalEndpoint()
                        .to(mockEndpointRequest);
            }
        });
    }

    @Test
    public void simpleTest() throws Exception{

        // there are 2 results in the test csv file.. need to poll the results till it completes
        PollWithTimeout.run("keep polling until route has been statisfied", 15000, new PollWithTimeout.Attempt() {
            @Override
            public boolean complete() {
                Date dateTime1MinuteAgo = new DateTime().minusMinutes(1).toDate();

                Integer newSearchCount = searchAnalysiticDao.findBySearchStartedAfter(dateTime1MinuteAgo).size();

                System.out.println("Recently added count: " + newSearchCount);
                return (newSearchCount == 2);
            }
        });

        mockEndpointRequest.expectedMessageCount(2);
        mockEndpointRequest.assertIsSatisfied();
    }
}

1 个答案:

答案 0 :(得分:1)

  

将bean添加到Context (将为此添加javaconfig选项)

如Andreas的评论部分所述,您可以将.transacted添加到路由中,并确保将事务管理器bean注入上下文文件中。

<强>路线

from("ftp://some__remote__ftp_dir_path")
  .routeId("searchAnalyticsImport") 
  .end()
  .transacted("PROPAGATION_REQUIRED")            
  etc....

Context Bean配置

<bean id="jmsTransactionManager"
      class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="pooledConnectionFactory" />
    <property name="defaultTimeout" value="30"/>
</bean>

<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
    <property name="transactionManager" ref="jmsTransactionManager" />
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
  

或者将事务添加到dao

您可以在 searchAnalyticsProcesser 中调用的dao方法中使用以下注释。仍然需要事务maanger bean,但您可以在注释中按名称指定它。

@Transactional(
    propagation = Propagation.REQUIRED,
    readOnly = false,
    value="transactionManager",
    rollbackFor = {
       Exception.class
      })
public void insertStuff()