Skip to content

Commit d5dd0a1

Browse files
committed
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
1 parent ae4b3ff commit d5dd0a1

File tree

9 files changed

+179
-51
lines changed

9 files changed

+179
-51
lines changed

spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/dsl/MongoDbOutboundGatewaySpec.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 the original author or authors.
2+
* Copyright 2016-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,13 +26,16 @@
2626
import org.springframework.expression.common.LiteralExpression;
2727
import org.springframework.integration.dsl.MessageHandlerSpec;
2828
import org.springframework.integration.expression.FunctionExpression;
29+
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
2930
import org.springframework.integration.mongodb.outbound.MongoDbOutboundGateway;
3031
import org.springframework.messaging.Message;
3132

3233
/**
3334
* A {@link MessageHandlerSpec} extension for the MongoDb Outbound endpoint {@link MongoDbOutboundGateway}
3435
*
3536
* @author Xavier Padró
37+
* @author Artem Bilan
38+
*
3639
* @since 5.0
3740
*/
3841
public class MongoDbOutboundGatewaySpec
@@ -149,10 +152,26 @@ public <P> MongoDbOutboundGatewaySpec collectionNameFunction(Function<Message<P>
149152
* @param collectionCallback the {@link CollectionCallback} instance
150153
* @param <P> the type of the message payload.
151154
* @return the spec
155+
* @deprecated in favor of {@link #collectionCallback(MessageCollectionCallback)}
152156
*/
157+
@Deprecated
153158
public <P> MongoDbOutboundGatewaySpec collectionCallback(CollectionCallback<P> collectionCallback) {
154159
this.target.setCollectionCallback(collectionCallback);
155160
return this;
156161
}
157162

163+
/**
164+
* Reference to an instance of {@link MessageCollectionCallback}
165+
* which specifies the database operation to execute in the request message context.
166+
* This property is mutually exclusive with {@link #query} and {@link #queryExpression} properties.
167+
* @param collectionCallback the {@link MessageCollectionCallback} instance
168+
* @param <P> the type of the message payload.
169+
* @return the spec
170+
* @since 5.0.11
171+
*/
172+
public <P> MongoDbOutboundGatewaySpec collectionCallback(MessageCollectionCallback<P> collectionCallback) {
173+
this.target.setMessageCollectionCallback(collectionCallback);
174+
return this;
175+
}
176+
158177
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.integration.mongodb.outbound;
18+
19+
import org.bson.Document;
20+
21+
import org.springframework.dao.DataAccessException;
22+
import org.springframework.data.mongodb.core.CollectionCallback;
23+
import org.springframework.lang.Nullable;
24+
import org.springframework.messaging.Message;
25+
26+
import com.mongodb.MongoException;
27+
import com.mongodb.client.MongoCollection;
28+
29+
/**
30+
* The callback to be used with the {@link MongoDbOutboundGateway}
31+
* as an alternative to other query options on the gateway.
32+
* <p>
33+
* Plays the same role as standard {@link CollectionCallback},
34+
* but with {@code Message<?> requestMessage} context during {@code handleMessage()}
35+
* process in the {@link MongoDbOutboundGateway}.
36+
*
37+
* @author Artem Bilan
38+
*
39+
* @since 5.0.11
40+
*
41+
* @see CollectionCallback
42+
*/
43+
@FunctionalInterface
44+
public interface MessageCollectionCallback<T> extends CollectionCallback<T> {
45+
46+
/**
47+
* Perform a Mongo operation in the collection using request message as a context.
48+
* @param collection never {@literal null}.
49+
* @param requestMessage the request message ot use for operations
50+
* @return can be {@literal null}.
51+
* @throws MongoException the MongoDB-specific exception
52+
* @throws DataAccessException the data access exception
53+
*/
54+
@Nullable
55+
T doInCollection(MongoCollection<Document> collection, Message<?> requestMessage)
56+
throws MongoException, DataAccessException;
57+
58+
@Override
59+
default T doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
60+
throw new UnsupportedOperationException("The 'doInCollection(MongoCollection<Document>, Message<?>)' " +
61+
"must be implemented instead.");
62+
}
63+
64+
}

spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbOutboundGateway.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 the original author or authors.
2+
* Copyright 2016-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,8 @@
4141
* Makes outbound operations to query a MongoDb database using a {@link MongoOperations}
4242
*
4343
* @author Xavier Padró
44+
* @author Artem Bilan
45+
*
4446
* @since 5.0
4547
*/
4648
public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler {
@@ -55,7 +57,7 @@ public class MongoDbOutboundGateway extends AbstractReplyProducingMessageHandler
5557

5658
private Expression queryExpression;
5759

58-
private CollectionCallback<?> collectionCallback;
60+
private MessageCollectionCallback<?> collectionCallback;
5961

6062
private boolean expectSingleResult = false;
6163

@@ -90,8 +92,29 @@ public void setQueryExpressionString(String queryExpressionString) {
9092
this.queryExpression = EXPRESSION_PARSER.parseExpression(queryExpressionString);
9193
}
9294

95+
/**
96+
* Specify a {@link CollectionCallback} to perform against MongoDB collection.
97+
* @param collectionCallback the callback to perform against MongoDB collection.
98+
* @deprecated in favor of {@link #setMessageCollectionCallback(MessageCollectionCallback)}.
99+
* Will be removed in 5.2
100+
*/
101+
@Deprecated
93102
public void setCollectionCallback(CollectionCallback<?> collectionCallback) {
94-
Assert.notNull(collectionCallback, "collectionCallback must not be null.");
103+
Assert.notNull(collectionCallback, "'collectionCallback' must not be null.");
104+
this.collectionCallback =
105+
collectionCallback instanceof MessageCollectionCallback
106+
? (MessageCollectionCallback) collectionCallback
107+
: (collection, requestMessage) -> collectionCallback.doInCollection(collection);
108+
}
109+
110+
/**
111+
* Specify a {@link MessageCollectionCallback} to perform against MongoDB collection
112+
* in the request message context.
113+
* @param collectionCallback the callback to perform against MongoDB collection.
114+
* @since 5.0.11
115+
*/
116+
public void setMessageCollectionCallback(MessageCollectionCallback<?> collectionCallback) {
117+
Assert.notNull(collectionCallback, "'collectionCallback' must not be null.");
95118
this.collectionCallback = collectionCallback;
96119
}
97120

@@ -152,7 +175,8 @@ protected Object handleRequestMessage(Message<?> requestMessage) {
152175
Object result;
153176

154177
if (this.collectionCallback != null) {
155-
result = this.mongoTemplate.execute(collectionName, this.collectionCallback);
178+
result = this.mongoTemplate.execute(collectionName, // NOSONAR
179+
collection -> this.collectionCallback.doInCollection(collection, requestMessage));
156180
}
157181
else {
158182
Query query = buildQuery(requestMessage);

spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-5.0.xsd

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,10 @@
239239
<xsd:appinfo>
240240
<xsd:documentation>
241241
Reference to an instance of
242-
org.springframework.data.mongodb.core.CollectionCallback
242+
org.springframework.data.mongodb.core.CollectionCallback, preferable an
243+
instance of
244+
org.springframework.integration.mongodb.outbound.MessageCollectionCallback
245+
with the request message context.
243246
</xsd:documentation>
244247
<tool:annotation kind="ref">
245248
<tool:expected-type

spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundGatewayParserTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
import org.springframework.context.ApplicationContext;
3232
import org.springframework.context.support.ClassPathXmlApplicationContext;
3333
import org.springframework.data.mongodb.MongoDbFactory;
34-
import org.springframework.data.mongodb.core.CollectionCallback;
3534
import org.springframework.data.mongodb.core.convert.MongoConverter;
3635
import org.springframework.expression.common.LiteralExpression;
3736
import org.springframework.expression.spel.standard.SpelExpression;
37+
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
3838
import org.springframework.integration.mongodb.outbound.MongoDbOutboundGateway;
3939
import org.springframework.integration.test.util.TestUtils;
4040
import org.springframework.test.annotation.DirtiesContext;
@@ -128,7 +128,7 @@ public void fullConfigWithMongoDbCollectionCallback() {
128128
instanceOf(LiteralExpression.class));
129129
assertEquals("foo", TestUtils.getPropertyValue(gateway, "collectionNameExpression.literalValue"));
130130
assertThat(TestUtils.getPropertyValue(gateway, "collectionCallback"),
131-
instanceOf(CollectionCallback.class));
131+
instanceOf(MessageCollectionCallback.class));
132132
}
133133

134134
@Test(expected = BeanDefinitionParsingException.class)

spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/dsl/MongoDbTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.context.annotation.Configuration;
3434
import org.springframework.data.mongodb.MongoDbFactory;
3535
import org.springframework.data.mongodb.core.BulkOperations;
36-
import org.springframework.data.mongodb.core.CollectionCallback;
3736
import org.springframework.data.mongodb.core.MongoOperations;
3837
import org.springframework.data.mongodb.core.MongoTemplate;
3938
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
@@ -45,6 +44,7 @@
4544
import org.springframework.integration.dsl.IntegrationFlow;
4645
import org.springframework.integration.dsl.channel.MessageChannels;
4746
import org.springframework.integration.handler.ReplyRequiredException;
47+
import org.springframework.integration.mongodb.outbound.MessageCollectionCallback;
4848
import org.springframework.integration.mongodb.rules.MongoDbAvailable;
4949
import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
5050
import org.springframework.integration.support.MessageBuilder;
@@ -55,10 +55,12 @@
5555
import org.springframework.test.context.junit4.SpringRunner;
5656

5757
import com.mongodb.MongoClient;
58-
import com.mongodb.client.MongoCollection;
5958

6059
/**
6160
* @author Xavier Padró
61+
* @author Gary Russell
62+
* @author Artem Bilan
63+
*
6264
* @since 5.0
6365
*/
6466
@RunWith(SpringRunner.class)
@@ -313,7 +315,8 @@ public IntegrationFlow gatewayCollectionNameFunctionFlow() {
313315
@Bean
314316
public IntegrationFlow gatewayCollectionCallbackFlow() {
315317
return f -> f
316-
.handle(collectionCallbackOutboundGateway(MongoCollection::count))
318+
.handle(collectionCallbackOutboundGateway(
319+
(collection, requestMessage) -> collection.count()))
317320
.channel(getResultChannel());
318321
}
319322

@@ -387,7 +390,9 @@ private MongoDbOutboundGatewaySpec collectionNameFunctionOutboundGateway(boolean
387390
.entityClass(Person.class);
388391
}
389392

390-
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway(CollectionCallback<?> collectionCallback) {
393+
private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway(
394+
MessageCollectionCallback<?> collectionCallback) {
395+
391396
return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter())
392397
.collectionCallback(collectionCallback)
393398
.collectionName(COLLECTION_NAME)

0 commit comments

Comments
 (0)