diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/dsl/MongoDbOutboundGatewaySpec.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/dsl/MongoDbOutboundGatewaySpec.java
index 97d99fa3d6..1e2d89131f 100644
--- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/dsl/MongoDbOutboundGatewaySpec.java
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/dsl/MongoDbOutboundGatewaySpec.java
@@ -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
the type of the message payload.
* @return the spec
+ * @deprecated in favor of {@link #collectionCallback(MessageCollectionCallback)}
*/
+ @Deprecated
public
MongoDbOutboundGatewaySpec collectionCallback(CollectionCallback
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
the type of the message payload.
+ * @return the spec
+ * @since 5.0.11
+ */
+ public
MongoDbOutboundGatewaySpec collectionCallback(MessageCollectionCallback
collectionCallback) {
+ this.target.setMessageCollectionCallback(collectionCallback);
+ return this;
+ }
+
}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MessageCollectionCallback.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MessageCollectionCallback.java
new file mode 100644
index 0000000000..f64d491f3f
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MessageCollectionCallback.java
@@ -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.
+ *
+ * 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 extends CollectionCallback {
+
+ /**
+ * 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 collection, Message> requestMessage)
+ throws MongoException, DataAccessException;
+
+ @Override
+ default T doInCollection(MongoCollection collection) throws MongoException, DataAccessException {
+ throw new UnsupportedOperationException("The 'doInCollection(MongoCollection, Message>)' " +
+ "must be implemented instead.");
+ }
+
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java
index af53b2a649..58ecf59c7d 100644
--- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java
@@ -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); // NOSONAR
+ result = this.mongoTemplate.execute(collectionName, // NOSONAR
+ collection -> this.collectionCallback.doInCollection(collection, requestMessage));
}
else {
Query query = buildQuery(requestMessage);
diff --git a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-5.1.xsd b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-5.1.xsd
index 2567357a9b..a46939bb84 100644
--- a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-5.1.xsd
+++ b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-5.1.xsd
@@ -244,7 +244,10 @@
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.
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)
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGatewayTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGatewayTests.java
index 37f36fc1e9..20640ea97f 100644
--- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGatewayTests.java
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGatewayTests.java
@@ -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 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 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 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 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 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 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 message = MessageBuilder.withPayload("").build();
+ public void testWithCollectionCallbackFindOne() {
+ Message 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();
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/rules/MongoDbAvailableTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/rules/MongoDbAvailableTests.java
index 95ef3d354c..72d4f486ed 100644
--- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/rules/MongoDbAvailableTests.java
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/rules/MongoDbAvailableTests.java
@@ -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 {
+ public static class TestCollectionCallback implements MessageCollectionCallback {
@Override
- public Long doInCollection(MongoCollection collection) throws MongoException, DataAccessException {
+ public Long doInCollection(MongoCollection collection, Message> message)
+ throws MongoException, DataAccessException {
+
return collection.countDocuments();
}
diff --git a/src/reference/asciidoc/mongodb.adoc b/src/reference/asciidoc/mongodb.adoc
index 652c836e98..4ae9e451a0 100644
--- a/src/reference/asciidoc/mongodb.adoc
+++ b/src/reference/asciidoc/mongodb.adoc
@@ -224,7 +224,8 @@ The following example shows how to configure a MongoDB inbound channel adapter:
As the preceding configuration shows, you configure a MongoDb inbound channel adapter by using the `inbound-channel-adapter` element and 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 the `query` attribute.
+* `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`
@@ -364,6 +365,8 @@ 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
@@ -448,7 +451,7 @@ public class MongoDbJavaApplication {
----
====
-As an alternate to the `query` and `query-expression` properties, you can specify other database operations by using 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:
====
@@ -456,7 +459,7 @@ The following example specifies a count operation:
----
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway() {
return MongoDb.outboundGateway(this.mongoDbFactory, this.mongoConverter)
- .collectionCallback(MongoCollection::count)
+ .collectionCallback((collection, requestMessage) -> collection.count())
.collectionName("myCollection");
}
----