INT-4570: Add MessageCollectionCallback for Mongo (#2675)

* INT-4570: Add MessageCollectionCallback for Mongo

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

The `MongoDbOutboundGateway` is intended to be used with the
`requestMessage` context, however using a plain `CollectionCallback`
we don't have access to the `requestMessage`

* Deprecate `CollectionCallback` usage in favor of newly introduced
`MessageCollectionCallback` and `message-collection-callback` for XML

**Cherry-pick to 5.0.x**

* * Remove `message-collection-callback` in favor of
`MessageCollectionCallback<T> extends CollectionCallback<T>`

* * Rename a new setter to `setMessageCollectionCallback()` to avoid
reflection collision
This commit is contained in:
Artem Bilan
2018-12-21 15:27:03 -05:00
committed by Gary Russell
parent 0d09bdccd4
commit 1943c15afe
9 changed files with 159 additions and 46 deletions

View File

@@ -34,13 +34,13 @@ import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.CollectionCallback;
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.AbstractEndpoint;
import org.springframework.integration.endpoint.PollingConsumer;
import org.springframework.integration.handler.advice.RequestHandlerRetryAdvice;
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
import org.springframework.integration.mongodb.outbound.MongoDbOutboundGateway;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.MessageHandler;
@@ -143,7 +143,7 @@ public class MongoDbOutboundGatewayParserTests {
instanceOf(LiteralExpression.class));
assertEquals("foo", TestUtils.getPropertyValue(gateway, "collectionNameExpression.literalValue"));
assertThat(TestUtils.getPropertyValue(gateway, "collectionCallback"),
instanceOf(CollectionCallback.class));
instanceOf(MessageCollectionCallback.class));
}
@Test(expected = BeanDefinitionParsingException.class)

View File

@@ -33,7 +33,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.CollectionCallback;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
@@ -45,6 +44,7 @@ import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.handler.ReplyRequiredException;
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
import org.springframework.integration.mongodb.rules.MongoDbAvailable;
import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
import org.springframework.integration.support.MessageBuilder;
@@ -55,11 +55,11 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
/**
* @author Xavier Padró
* @author Gary Russell
* @author Artem Bilan
*
* @since 5.0
*/
@@ -315,7 +315,8 @@ public class MongoDbTests extends MongoDbAvailableTests {
@Bean
public IntegrationFlow gatewayCollectionCallbackFlow() {
return f -> f
.handle(collectionCallbackOutboundGateway(MongoCollection::countDocuments))
.handle(collectionCallbackOutboundGateway(
(collection, requestMessage) -> collection.countDocuments()))
.channel(getResultChannel());
}
@@ -389,7 +390,9 @@ public class MongoDbTests extends MongoDbAvailableTests {
.entityClass(Person.class);
}
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway(CollectionCallback<?> collectionCallback) {
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway(
MessageCollectionCallback<?> collectionCallback) {
return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter())
.collectionCallback(collectionCallback)
.collectionName(COLLECTION_NAME)

View File

@@ -37,6 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Query;
@@ -49,18 +50,16 @@ import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.client.MongoCollection;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Xavier Padró
* @author Gary Russell
* @author Gary Rssell
* @author Artem Bilan
*
* @since 5.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@DirtiesContext
public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@@ -96,14 +95,12 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
mongoTemplate.dropCollection(COLLECTION_NAME);
}
@SuppressWarnings("ConstantConditions")
@Test
@MongoDbAvailable
public void testNoFactorySpecified() {
MongoDbFactory nullFactory = null;
try {
new MongoDbOutboundGateway(nullFactory);
new MongoDbOutboundGateway((MongoDbFactory) null);
Assert.fail("Expected the test case to throw an IllegalArgumentException");
}
catch (IllegalArgumentException e) {
@@ -111,14 +108,11 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
}
}
@SuppressWarnings("ConstantConditions")
@Test
@MongoDbAvailable
public void testNoTemplateSpecified() {
MongoOperations mongoTemplate = null;
try {
new MongoDbOutboundGateway(mongoTemplate);
new MongoDbOutboundGateway((MongoTemplate) null);
Assert.fail("Expected the test case to throw an IllegalArgumentException");
}
catch (IllegalArgumentException e) {
@@ -194,7 +188,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testListOfResultsWithQueryExpression() throws Exception {
public void testListOfResultsWithQueryExpression() {
Message<String> message = MessageBuilder.withPayload("{}").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setEntityClass(Person.class);
@@ -209,7 +203,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testListOfResultsWithQueryExpressionReturningOneResult() throws Exception {
public void testListOfResultsWithQueryExpressionReturningOneResult() {
Message<String> message = MessageBuilder.withPayload("{name : 'Xavi'}").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setEntityClass(Person.class);
@@ -225,7 +219,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testSingleResultWithQueryExpressionAsString() throws Exception {
public void testSingleResultWithQueryExpressionAsString() {
Message<String> message = MessageBuilder.withPayload("{name : 'Artem'}").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setQueryExpression(PARSER.parseExpression("payload"));
@@ -241,7 +235,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testSingleResultWithQueryExpressionAsQuery() throws Exception {
public void testSingleResultWithQueryExpressionAsQuery() {
Message<String> message = MessageBuilder.withPayload("").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setQueryExpression(PARSER.parseExpression("new BasicQuery('{''name'' : ''Gary''}')"));
@@ -272,7 +266,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testWithNullCollectionNameExpression() throws Exception {
public void testWithNullCollectionNameExpression() {
MongoDbOutboundGateway gateway = new MongoDbOutboundGateway(mongoDbFactory);
gateway.setBeanFactory(beanFactory);
gateway.setQueryExpression(new LiteralExpression("{name : 'Xavi'}"));
@@ -289,7 +283,7 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testWithCollectionNameExpressionSpecified() throws Exception {
public void testWithCollectionNameExpressionSpecified() {
Message<String> message = MessageBuilder.withPayload("").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setQueryExpression(new LiteralExpression("{name : 'Xavi'}"));
@@ -308,13 +302,13 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testWithCollectionCallbackCount() throws Exception {
public void testWithCollectionCallbackCount() {
Message<String> message = MessageBuilder.withPayload("").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setEntityClass(Person.class);
gateway.setCollectionNameExpression(new LiteralExpression("data"));
gateway.setCollectionCallback(MongoCollection::countDocuments);
gateway.setMessageCollectionCallback((collection, requestMessage) -> collection.countDocuments());
gateway.afterPropertiesSet();
long result = (long) gateway.handleRequestMessage(message);
@@ -324,15 +318,15 @@ public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@Test
@MongoDbAvailable
public void testWithCollectionCallbackFindOne() throws Exception {
Message<String> message = MessageBuilder.withPayload("").build();
public void testWithCollectionCallbackFindOne() {
Message<String> message = MessageBuilder.withPayload("Mike").build();
MongoDbOutboundGateway gateway = createGateway();
gateway.setEntityClass(Person.class);
gateway.setCollectionNameExpression(new LiteralExpression("data"));
gateway.setRequiresReply(false);
gateway.setCollectionCallback(collection -> {
collection.insertOne(new Document("name", "Mike"));
gateway.setMessageCollectionCallback((collection, requestMessage) -> {
collection.insertOne(new Document("name", requestMessage.getPayload()));
return null;
});
gateway.afterPropertiesSet();

View File

@@ -23,13 +23,14 @@ import org.junit.Rule;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.CollectionCallback;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
import org.springframework.messaging.Message;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
@@ -66,7 +67,7 @@ public abstract class MongoDbAvailableTests {
}
}
public Person createPerson() {
protected Person createPerson() {
Address address = new Address();
address.setCity("Philadelphia");
address.setStreet("2121 Rawn street");
@@ -78,7 +79,7 @@ public abstract class MongoDbAvailableTests {
return person;
}
public Person createPerson(String name) {
protected Person createPerson(String name) {
Address address = new Address();
address.setCity("Philadelphia");
address.setStreet("2121 Rawn street");
@@ -169,10 +170,12 @@ public abstract class MongoDbAvailableTests {
}
public static class TestCollectionCallback implements CollectionCallback<Long> {
public static class TestCollectionCallback implements MessageCollectionCallback<Long> {
@Override
public Long doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
public Long doInCollection(MongoCollection<Document> collection, Message<?> message)
throws MongoException, DataAccessException {
return collection.countDocuments();
}