INT-4163: UnProxy MessageSource for TX Resource

JIRA: https://jira.spring.io/browse/INT-4163

When `MessageSource` is proxy, the `TransactionSynchronizationManager.getResource(this)` logic in the `MessageSource` doesn't work,
because TX resource is bound to the `Proxy` in the `SourcePollingChannelAdapter`

* Introduce `SourcePollingChannelAdapter.originalSource` property and store there a target `MessageSource` object extracted from the AOP Proxy
* Use `originalSource` as a resource to bind to the TX
* Modify `MongoDbInboundChannelAdapterIntegrationTests` to ensure that `AbstractMessageSourceAdvice` proxying the `MessageSource` doesn't effect `TransactionSynchronizationManager.getResource(this)` logic
* Refactor for some MongoDb test to rely on the `@RunWith(SpringJUnit4ClassRunner.class)` for context loading for better test class performance

**Cherry-pick to 4.3.x, 4.2.x**

Fallback to provided source if `target` from Proxy is `null`

Fix [UnusedImport] issue
This commit is contained in:
Artem Bilan
2016-11-07 12:41:03 -05:00
committed by Gary Russell
parent acf7424dbc
commit e2d18054e6
6 changed files with 296 additions and 210 deletions

View File

@@ -25,6 +25,7 @@ import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.Lifecycle;
import org.springframework.integration.aop.AbstractMessageSourceAdvice;
import org.springframework.integration.context.ExpressionCapable;
@@ -55,6 +56,8 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
private final Collection<Advice> appliedAdvices = new HashSet<Advice>();
private volatile MessageSource<?> originalSource;
private volatile MessageSource<?> source;
private volatile MessageChannel outputChannel;
@@ -70,6 +73,10 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
*/
public void setSource(MessageSource<?> source) {
this.source = source;
Object target = extractProxyTarget(source);
this.originalSource = target != null ? (MessageSource<?>) target : source;
if (source instanceof ExpressionCapable) {
setPrimaryExpression(((ExpressionCapable) source).getExpression());
}
@@ -219,7 +226,7 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
@Override
protected Object getResourceToBind() {
return this.source;
return this.originalSource;
}
@Override
@@ -227,4 +234,21 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
return IntegrationResourceHolder.MESSAGE_SOURCE;
}
private static Object extractProxyTarget(Object target) {
if (!(target instanceof Advised)) {
return target;
}
Advised advised = (Advised) target;
if (advised.getTargetSource() == null) {
return null;
}
try {
return extractProxyTarget(advised.getTargetSource().getTarget());
}
catch (Exception e) {
throw new BeanCreationException("Could not extract target", e);
}
}
}

View File

@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-mongodb="http://www.springframework.org/schema/integration/mongodb"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/mongodb http://www.springframework.org/schema/integration/mongodb/spring-integration-mongodb.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<mongo:db-factory id="mongoDbFactory" dbname="test" />
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapter"
channel="replyChannel"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="100" />
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterNamedFactory"
mongodb-factory="mongoDbFactory"
channel="replyChannel"
query="{'name' : 'Bob'}"
auto-startup="false">
<int:poller fixed-rate="5000" />
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithTemplate"
channel="replyChannel"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
expect-single-result="true"
entity-class="org.springframework.integration.mongodb.rules.MongoDbAvailableTests.Person"
auto-startup="false">
<int:poller fixed-rate="5000" />
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithNamedCollection"
channel="replyChannel"
collection-name="foo"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="5000" />
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithNamedCollectionExpression"
channel="replyChannel"
collection-name-expression="'foo'"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="5000" />
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="inboundAdapterWithOnSuccessDisposition"
channel="replyChannel"
query="{'name' : 'Bob'}"
auto-startup="false">
<int:poller fixed-rate="200" max-messages-per-poll="1">
<int:advice-chain synchronization-factory="syncFactory">
<bean
class="org.springframework.integration.mongodb.config.MongoDbInboundChannelAdapterIntegrationTests.TestMessageSourceAdvice" />
<tx:advice>
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
</int:advice-chain>
</int:poller>
</int-mongodb:inbound-channel-adapter>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="@documentCleaner.remove(#mongoTemplate, payload, headers.mongo_collectionName)" />
</int:transaction-synchronization-factory>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithConverter"
channel="replyChannel"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
mongo-converter="mongoConverter"
auto-startup="false">
<int:poller fixed-rate="100" />
</int-mongodb:inbound-channel-adapter>
<bean id="documentCleaner"
class="org.springframework.integration.mongodb.config.MongoDbInboundChannelAdapterIntegrationTests.DocumentCleaner" />
<bean id="mongoDbTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory" />
</bean>
<bean id="mongoConverter"
class="org.springframework.integration.mongodb.rules.MongoDbAvailableTests.TestMongoConverter">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg>
<bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
</constructor-arg>
</bean>
<int:channel id="replyChannel">
<int:queue />
</int:channel>
<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager" />
</beans>

View File

@@ -22,174 +22,181 @@ import static org.junit.Assert.assertNull;
import java.util.List;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.integration.aop.AbstractMessageSourceAdvice;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.mongodb.rules.MongoDbAvailable;
import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
import org.springframework.messaging.Message;
import org.springframework.messaging.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
/**
* @author Oleg Zhurakousky
* @author Artem Bilan
* @since 2.2
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class MongoDbInboundChannelAdapterIntegrationTests extends MongoDbAvailableTests {
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private PollableChannel replyChannel;
@Autowired
@Qualifier("mongoInboundAdapter")
private SourcePollingChannelAdapter mongoInboundAdapter;
@Autowired
@Qualifier("mongoInboundAdapterNamedFactory")
private SourcePollingChannelAdapter mongoInboundAdapterNamedFactory;
@Autowired
@Qualifier("mongoInboundAdapterWithTemplate")
private SourcePollingChannelAdapter mongoInboundAdapterWithTemplate;
@Autowired
@Qualifier("mongoInboundAdapterWithNamedCollection")
private SourcePollingChannelAdapter mongoInboundAdapterWithNamedCollection;
@Autowired
@Qualifier("mongoInboundAdapterWithNamedCollectionExpression")
private SourcePollingChannelAdapter mongoInboundAdapterWithNamedCollectionExpression;
@Autowired
@Qualifier("inboundAdapterWithOnSuccessDisposition")
private SourcePollingChannelAdapter inboundAdapterWithOnSuccessDisposition;
@Autowired
@Qualifier("mongoInboundAdapterWithConverter")
private SourcePollingChannelAdapter mongoInboundAdapterWithConverter;
@Test
@MongoDbAvailable
public void testWithDefaultMongoFactory() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "data");
this.mongoTemplate.save(createPerson("Bob"), "data");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapter", SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapter.start();
@SuppressWarnings("unchecked")
Message<List<Person>> message = (Message<List<Person>>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().get(0).getName());
assertNotNull(replyChannel.receive(10000));
context.close();
assertNotNull(this.replyChannel.receive(10000));
this.mongoInboundAdapter.stop();
}
@Test
@MongoDbAvailable
public void testWithNamedMongoFactory() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "data");
this.mongoTemplate.save(this.createPerson("Bob"), "data");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterNamedFactory",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapterNamedFactory.start();
@SuppressWarnings("unchecked")
Message<List<DBObject>> message = (Message<List<DBObject>>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().get(0).get("name"));
context.close();
this.mongoInboundAdapterNamedFactory.stop();
}
@Test
@MongoDbAvailable
public void testWithMongoTemplate() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "data");
this.mongoTemplate.save(this.createPerson("Bob"), "data");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithTemplate",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapterWithTemplate.start();
@SuppressWarnings("unchecked")
Message<Person> message = (Message<Person>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().getName());
context.close();
this.mongoInboundAdapterWithTemplate.stop();
}
@Test
@MongoDbAvailable
public void testWithNamedCollection() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "foo");
this.mongoTemplate.save(this.createPerson("Bob"), "foo");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithNamedCollection",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapterWithNamedCollection.start();
@SuppressWarnings("unchecked")
Message<List<Person>> message = (Message<List<Person>>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().get(0).getName());
context.close();
this.mongoInboundAdapterWithNamedCollection.stop();
}
@Test
@MongoDbAvailable
public void testWithNamedCollectionExpression() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "foo");
this.mongoTemplate.save(this.createPerson("Bob"), "foo");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithNamedCollectionExpression",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapterWithNamedCollectionExpression.start();
@SuppressWarnings("unchecked")
Message<List<Person>> message = (Message<List<Person>>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().get(0).getName());
context.close();
this.mongoInboundAdapterWithNamedCollectionExpression.stop();
}
@Test
@MongoDbAvailable
public void testWithOnSuccessDisposition() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "data");
this.mongoTemplate.save(createPerson("Bob"), "data");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("inboundAdapterWithOnSuccessDisposition",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.inboundAdapterWithOnSuccessDisposition.start();
assertNotNull(replyChannel.receive(10000));
Thread.sleep(300);
assertNull(replyChannel.receive(100));
context.close();
this.inboundAdapterWithOnSuccessDisposition.stop();
assertNull(this.mongoTemplate.findOne(new Query(Criteria.where("name").is("Bob")), Person.class, "data"));
}
@Test
@MongoDbAvailable
public void testWithMongoConverter() throws Exception {
MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.save(this.createPerson("Bob"), "data");
this.mongoTemplate.save(this.createPerson("Bob"), "data");
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithConverter",
SourcePollingChannelAdapter.class);
QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
spca.start();
this.mongoInboundAdapterWithConverter.start();
@SuppressWarnings("unchecked")
Message<List<Person>> message = (Message<List<Person>>) replyChannel.receive(10000);
assertNotNull(message);
assertEquals("Bob", message.getPayload().get(0).getName());
assertNotNull(replyChannel.receive(10000));
context.close();
this.mongoInboundAdapterWithConverter.stop();
}
@Test(expected = BeanDefinitionParsingException.class)
@@ -206,7 +213,7 @@ public class MongoDbInboundChannelAdapterIntegrationTests extends MongoDbAvailab
@Test(expected = BeanDefinitionParsingException.class)
@MongoDbAvailable
public void testFailureWithCollectionAndCollectioinExpression() throws Exception {
public void testFailureWithCollectionAndCollectionExpression() throws Exception {
new ClassPathXmlApplicationContext("inbound-fail-c-cex.xml", this.getClass()).close();
}
@@ -229,4 +236,18 @@ public class MongoDbInboundChannelAdapterIntegrationTests extends MongoDbAvailab
}
public static final class TestMessageSourceAdvice extends AbstractMessageSourceAdvice {
@Override
public boolean beforeReceive(MessageSource<?> source) {
return true;
}
@Override
public Message<?> afterReceive(Message<?> result, MessageSource<?> source) {
return result;
}
}
}

View File

@@ -18,87 +18,115 @@ package org.springframework.integration.mongodb.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.mongodb.inbound.MongoDbMessageSource;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Oleg Zhurakousky
* @author Gary Russell
* @author Artem Bilan
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class MongoDbInboundChannelAdapterParserTests {
@Autowired
private MongoDbFactory mongoDbFactory;
@Autowired
private MongoConverter mongoConverter;
@Autowired
private MongoTemplate mongoDbTemplate;
@Autowired
@Qualifier("minimalConfig.adapter")
private SourcePollingChannelAdapter minimalConfigAdapter;
@Autowired
@Qualifier("fullConfigWithCollectionExpression.adapter")
private SourcePollingChannelAdapter fullConfigWithCollectionExpressionAdapter;
@Autowired
@Qualifier("fullConfigWithCollectionName.adapter")
private SourcePollingChannelAdapter fullConfigWithCollectionNameAdapter;
@Autowired
@Qualifier("fullConfigWithMongoTemplate.adapter")
private SourcePollingChannelAdapter fullConfigWithMongoTemplateAdapter;
@Test
public void minimalConfig() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("minimalConfig.adapter", SourcePollingChannelAdapter.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(this.minimalConfigAdapter, "source",
MongoDbMessageSource.class);
assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
assertEquals(false, TestUtils.getPropertyValue(this.minimalConfigAdapter, "shouldTrack"));
assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertEquals(this.mongoDbFactory, TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
assertEquals("data", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
context.close();
}
@Test
public void fullConfigWithCollectionExpression() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("fullConfigWithCollectionExpression.adapter", SourcePollingChannelAdapter.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(this.fullConfigWithCollectionExpressionAdapter,
"source", MongoDbMessageSource.class);
assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
assertEquals(false, TestUtils.getPropertyValue(this.fullConfigWithCollectionExpressionAdapter, "shouldTrack"));
assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertEquals(context.getBean("mongoConverter"), TestUtils.getPropertyValue(source, "mongoConverter"));
assertEquals(this.mongoDbFactory, TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertEquals(this.mongoConverter, TestUtils.getPropertyValue(source, "mongoConverter"));
assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof SpelExpression);
assertEquals("'foo'", TestUtils.getPropertyValue(source, "collectionNameExpression.expression"));
context.close();
}
@Test
public void fullConfigWithCollectionName() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("fullConfigWithCollectionName.adapter", SourcePollingChannelAdapter.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(this.fullConfigWithCollectionNameAdapter, "source",
MongoDbMessageSource.class);
assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
assertEquals(false, TestUtils.getPropertyValue(this.fullConfigWithCollectionNameAdapter, "shouldTrack"));
assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertEquals(context.getBean("mongoConverter"), TestUtils.getPropertyValue(source, "mongoConverter"));
assertEquals(this.mongoDbFactory, TestUtils.getPropertyValue(source, "mongoDbFactory"));
assertEquals(this.mongoConverter, TestUtils.getPropertyValue(source, "mongoConverter"));
assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
assertEquals("foo", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
context.close();
}
@Test
public void fullConfigWithMongoTemplate() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
SourcePollingChannelAdapter spca = context.getBean("fullConfigWithMongoTemplate.adapter", SourcePollingChannelAdapter.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
MongoDbMessageSource source = TestUtils.getPropertyValue(this.fullConfigWithMongoTemplateAdapter, "source",
MongoDbMessageSource.class);
assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
assertEquals(false, TestUtils.getPropertyValue(this.fullConfigWithMongoTemplateAdapter, "shouldTrack"));
assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
assertEquals(context.getBean("mongoDbTemplate"), TestUtils.getPropertyValue(source, "mongoTemplate"));
assertSame(this.mongoDbTemplate, TestUtils.getPropertyValue(source, "mongoTemplate"));
assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
assertEquals("foo", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
context.close();
}
@Test(expected = BeanDefinitionParsingException.class)
@@ -112,4 +140,5 @@ public class MongoDbInboundChannelAdapterParserTests {
new ClassPathXmlApplicationContext("inbound-adapter-parser-fail-template-converter-config.xml", this.getClass())
.close();
}
}

View File

@@ -1,102 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-mongodb="http://www.springframework.org/schema/integration/mongodb"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/mongodb http://www.springframework.org/schema/integration/mongodb/spring-integration-mongodb.xsd">
<mongo:db-factory id="mongoDbFactory" dbname="test"/>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapter"
channel="replyChannel"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="100"/>
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterNamedFactory"
mongodb-factory="mongoDbFactory"
channel="replyChannel"
query="{'name' : 'Bob'}"
auto-startup="false">
<int:poller fixed-rate="5000"/>
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithTemplate"
channel="replyChannel"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
expect-single-result="true"
entity-class="org.springframework.integration.mongodb.rules.MongoDbAvailableTests.Person"
auto-startup="false">
<int:poller fixed-rate="5000"/>
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithNamedCollection"
channel="replyChannel"
collection-name="foo"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="5000"/>
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithNamedCollectionExpression"
channel="replyChannel"
collection-name-expression="'foo'"
mongo-template="mongoDbTemplate"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
auto-startup="false">
<int:poller fixed-rate="5000"/>
</int-mongodb:inbound-channel-adapter>
<int-mongodb:inbound-channel-adapter id="inboundAdapterWithOnSuccessDisposition"
channel="replyChannel"
query="{'name' : 'Bob'}"
auto-startup="false">
<int:poller fixed-rate="200" max-messages-per-poll="1">
<int:transactional synchronization-factory="syncFactory"/>
</int:poller>
</int-mongodb:inbound-channel-adapter>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="@documentCleaner.remove(#mongoTemplate, payload, headers.mongo_collectionName)"/>
</int:transaction-synchronization-factory>
<int-mongodb:inbound-channel-adapter id="mongoInboundAdapterWithConverter"
channel="replyChannel"
query="{'name' : 'Bob'}"
entity-class="java.lang.Object"
mongo-converter="mongoConverter"
auto-startup="false">
<int:poller fixed-rate="100"/>
</int-mongodb:inbound-channel-adapter>
<bean id="documentCleaner" class="org.springframework.integration.mongodb.config.MongoDbInboundChannelAdapterIntegrationTests.DocumentCleaner"/>
<bean id="mongoDbTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
</bean>
<bean id="mongoConverter" class="org.springframework.integration.mongodb.rules.MongoDbAvailableTests.TestMongoConverter">
<constructor-arg ref="mongoDbFactory"/>
<constructor-arg>
<bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext"/>
</constructor-arg>
</bean>
<int:channel id="replyChannel">
<int:queue/>
</int:channel>
<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager"/>
</beans>