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

# Conflicts:
#	spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java
#	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundGatewayParserTests.java
#	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/dsl/MongoDbTests.java
#	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGatewayTests.java
#	spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/rules/MongoDbAvailableTests.java
#	src/reference/asciidoc/mongodb.adoc
This commit is contained in:
Artem Bilan
2018-12-21 15:27:03 -05:00
parent ae4b3fffb2
commit d5dd0a1240
9 changed files with 179 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.springframework.data.mongodb.core.query.Query;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.dsl.MessageHandlerSpec;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
import org.springframework.integration.mongodb.outbound.MongoDbOutboundGateway;
import org.springframework.messaging.Message;
@@ -33,6 +34,8 @@ import org.springframework.messaging.Message;
* A {@link MessageHandlerSpec} extension for the MongoDb Outbound endpoint {@link MongoDbOutboundGateway}
*
* @author Xavier Padró
* @author Artem Bilan
*
* @since 5.0
*/
public class MongoDbOutboundGatewaySpec
@@ -149,10 +152,26 @@ public class MongoDbOutboundGatewaySpec
* @param collectionCallback the {@link CollectionCallback} instance
* @param <P> the type of the message payload.
* @return the spec
* @deprecated in favor of {@link #collectionCallback(MessageCollectionCallback)}
*/
@Deprecated
public <P> MongoDbOutboundGatewaySpec collectionCallback(CollectionCallback<P> collectionCallback) {
this.target.setCollectionCallback(collectionCallback);
return this;
}
/**
* Reference to an instance of {@link MessageCollectionCallback}
* which specifies the database operation to execute in the request message context.
* This property is mutually exclusive with {@link #query} and {@link #queryExpression} properties.
* @param collectionCallback the {@link MessageCollectionCallback} instance
* @param <P> the type of the message payload.
* @return the spec
* @since 5.0.11
*/
public <P> MongoDbOutboundGatewaySpec collectionCallback(MessageCollectionCallback<P> collectionCallback) {
this.target.setMessageCollectionCallback(collectionCallback);
return this;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.mongodb.outbound;
import org.bson.Document;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.CollectionCallback;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCollection;
/**
* The callback to be used with the {@link MongoDbOutboundGateway}
* as an alternative to other query options on the gateway.
* <p>
* Plays the same role as standard {@link CollectionCallback},
* but with {@code Message<?> requestMessage} context during {@code handleMessage()}
* process in the {@link MongoDbOutboundGateway}.
*
* @author Artem Bilan
*
* @since 5.0.11
*
* @see CollectionCallback
*/
@FunctionalInterface
public interface MessageCollectionCallback<T> extends CollectionCallback<T> {
/**
* Perform a Mongo operation in the collection using request message as a context.
* @param collection never {@literal null}.
* @param requestMessage the request message ot use for operations
* @return can be {@literal null}.
* @throws MongoException the MongoDB-specific exception
* @throws DataAccessException the data access exception
*/
@Nullable
T doInCollection(MongoCollection<Document> collection, Message<?> requestMessage)
throws MongoException, DataAccessException;
@Override
default T doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
throw new UnsupportedOperationException("The 'doInCollection(MongoCollection<Document>, Message<?>)' " +
"must be implemented instead.");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2016-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,8 @@ import org.springframework.util.Assert;
* Makes outbound operations to query a MongoDb database using a {@link MongoOperations}
*
* @author Xavier Padró
* @author Artem Bilan
*
* @since 5.0
*/
public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler {
@@ -55,7 +57,7 @@ public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler
private Expression queryExpression;
private CollectionCallback<?> collectionCallback;
private MessageCollectionCallback<?> collectionCallback;
private boolean expectSingleResult = false;
@@ -90,8 +92,29 @@ public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler
this.queryExpression = EXPRESSION_PARSER.parseExpression(queryExpressionString);
}
/**
* Specify a {@link CollectionCallback} to perform against MongoDB collection.
* @param collectionCallback the callback to perform against MongoDB collection.
* @deprecated in favor of {@link #setMessageCollectionCallback(MessageCollectionCallback)}.
* Will be removed in 5.2
*/
@Deprecated
public void setCollectionCallback(CollectionCallback<?> collectionCallback) {
Assert.notNull(collectionCallback, "collectionCallback must not be null.");
Assert.notNull(collectionCallback, "'collectionCallback' must not be null.");
this.collectionCallback =
collectionCallback instanceof MessageCollectionCallback
? (MessageCollectionCallback) collectionCallback
: (collection, requestMessage) -> collectionCallback.doInCollection(collection);
}
/**
* Specify a {@link MessageCollectionCallback} to perform against MongoDB collection
* in the request message context.
* @param collectionCallback the callback to perform against MongoDB collection.
* @since 5.0.11
*/
public void setMessageCollectionCallback(MessageCollectionCallback<?> collectionCallback) {
Assert.notNull(collectionCallback, "'collectionCallback' must not be null.");
this.collectionCallback = collectionCallback;
}
@@ -152,7 +175,8 @@ public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler
Object result;
if (this.collectionCallback != null) {
result = this.mongoTemplate.execute(collectionName, this.collectionCallback);
result = this.mongoTemplate.execute(collectionName, // NOSONAR
collection -> this.collectionCallback.doInCollection(collection, requestMessage));
}
else {
Query query = buildQuery(requestMessage);

View File

@@ -239,7 +239,10 @@
<xsd:appinfo>
<xsd:documentation>
Reference to an instance of
org.springframework.data.mongodb.core.CollectionCallback
org.springframework.data.mongodb.core.CollectionCallback, preferable an
instance of
org.springframework.integration.mongodb.outbound.MessageCollectionCallback
with the request message context.
</xsd:documentation>
<tool:annotation kind="ref">
<tool:expected-type

View File

@@ -31,10 +31,10 @@ 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.mongodb.outbound.MessageCollectionCallback;
import org.springframework.integration.mongodb.outbound.MongoDbOutboundGateway;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.annotation.DirtiesContext;
@@ -128,7 +128,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.channel.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,10 +55,12 @@ 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
*/
@RunWith(SpringRunner.class)
@@ -313,7 +315,8 @@ public class MongoDbTests extends MongoDbAvailableTests {
@Bean
public IntegrationFlow gatewayCollectionCallbackFlow() {
return f -> f
.handle(collectionCallbackOutboundGateway(MongoCollection::count))
.handle(collectionCallbackOutboundGateway(
(collection, requestMessage) -> collection.count()))
.channel(getResultChannel());
}
@@ -387,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,17 +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 Rssell
* @author Artem Bilan
*
* @since 5.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
@DirtiesContext
public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests {
@@ -95,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) {
@@ -110,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) {
@@ -193,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);
@@ -208,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);
@@ -224,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"));
@@ -240,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''}')"));
@@ -271,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'}"));
@@ -288,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'}"));
@@ -307,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::count);
gateway.setMessageCollectionCallback((collection, requestMessage) -> collection.count());
gateway.afterPropertiesSet();
long result = (long) gateway.handleRequestMessage(message);
@@ -323,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;
@@ -64,7 +65,7 @@ public abstract class MongoDbAvailableTests {
}
}
public Person createPerson() {
protected Person createPerson() {
Address address = new Address();
address.setCity("Philadelphia");
address.setStreet("2121 Rawn street");
@@ -76,7 +77,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");
@@ -166,10 +167,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.count();
}

View File

@@ -187,12 +187,14 @@ The _MongoDb Inbound Channel Adapter_ is a polling consumer that reads data from
As you can see from the configuration above, you configure a _MongoDb Inbound Channel Adapter_ using the `inbound-channel-adapter` element, providing values for various attributes such as:
* `query` - a JSON query (see http://www.mongodb.org/display/DOCS/Querying[MongoDb Querying])
* `query-expression` - A SpEL expression that is evaluated to a JSON query String (as the `query` attribute above), or to an instance of `o.s.data.mongodb.core.query.Query`. Mutually exclusive with `query` attribute.
* `entity-class` - the type of the payload object; if not supplied, a `com.mongodb.DBObject` will be returned.
* `collection-name` or `collection-name-expression` - Identifies the name of the MongoDb collection to use.
* `mongodb-factory` - reference to an instance of `o.s.data.mongodb.MongoDbFactory`
* `mongo-template` - reference to an instance of `o.s.data.mongodb.core.MongoTemplate`
* `query`: A JSON query (see http://www.mongodb.org/display/DOCS/Querying[MongoDB Querying])
* `query-expression`: A SpEL expression that is evaluated to a JSON query string (as the `query` attribute above) or to an instance of `o.s.data.mongodb.core.query.Query`.
Mutually exclusive with the `query` attribute.
* `entity-class`: The type of the payload object. If not supplied, a `com.mongodb.DBObject` is returned.
* `collection-name` or `collection-name-expression`: Identifies the name of the MongoDB collection to use.
* `mongodb-factory`: Reference to an instance of `o.s.data.mongodb.MongoDbFactory`
* `mongo-template`: Reference to an instance of `o.s.data.mongodb.core.MongoTemplate`
* Other attributes that are common across all other inbound adapters (such as 'channel').
@@ -321,6 +323,20 @@ Please refer to http://www.mongodb.org/display/DOCS/Querying[MongoDB documentati
* `collection-callback` - reference to an instance of `org.springframework.data.mongodb.core.CollectionCallback`
(NOTE: you can not have both collection-callback and any of the query attributes).
* `collection-name` or `collection-name-expression`: Identifies the name of the MongoDB collection to use.
* `mongo-converter`: Reference to an instance of `o.s.data.mongodb.core.convert.MongoConverter` that assists with converting a raw Java object to a JSON document representation.
* `mongodb-factory`: Reference to an instance of `o.s.data.mongodb.MongoDbFactory`.
* `mongo-template`: Reference to an instance of `o.s.data.mongodb.core.MongoTemplate`.
NOTE: you can not set both `mongo-template` and `mongodb-factory`.
* `entity-class`: The fully qualified name of the entity class to be passed to the `find(..)` and `findOne(..)` methods in MongoTemplate.
If this attribute is not provided, the default value is `org.bson.Document`.
* `query` or `query-expression`: Specifies the MongoDB query.
See the http://www.mongodb.org/display/DOCS/Querying[MongoDB documentation] for more query samples.
* `collection-callback`: Reference to an instance of `org.springframework.data.mongodb.core.CollectionCallback`.
Preferable an instance of `org.springframework.integration.mongodb.outbound.MessageCollectionCallback` since 5.0.11 with the request message context.
See its Javadocs for more information.
NOTE: You can not have both `collection-callback` and any of the query attributes.
==== Configuring with Java Configuration
The following Spring Boot application provides an example of configuring the outbound gateway using Java configuration:
@@ -399,15 +415,14 @@ public class MongoDbJavaApplication {
}
----
Alternatively to the `query` and `query-expression` properties, you can specify other database operations through
the `collectionCallback` property.
As an alternate to the `query` and `query-expression` properties, you can specify other database operations by using the `collectionCallback` property as a reference to the `MessageCollectionCallback` functional interface implementation.
The following example specifies a count operation:
[source, java]
----
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway() {
return MongoDb.outboundGateway(this.mongoDbFactory, this.mongoConverter)
.collectionCallback(MongoCollection::count)
.collectionCallback((collection, requestMessage) -> collection.count())
.collectionName("foo");
}
----