diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/AbstractConfigurableMongoDbMessageStore.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/AbstractConfigurableMongoDbMessageStore.java index 95a2c72d40..9845238e21 100644 --- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/AbstractConfigurableMongoDbMessageStore.java +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/AbstractConfigurableMongoDbMessageStore.java @@ -18,11 +18,9 @@ package org.springframework.integration.mongodb.store; import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import org.apache.commons.logging.Log; @@ -33,11 +31,6 @@ import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.core.convert.TypeDescriptor; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.GenericConverter; -import org.springframework.core.serializer.support.DeserializingConverter; -import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.FindAndModifyOptions; @@ -51,6 +44,7 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; +import org.springframework.integration.mongodb.support.MongoDbMessageBytesConverter; import org.springframework.integration.store.AbstractMessageGroupStore; import org.springframework.integration.store.BasicMessageGroupStore; import org.springframework.integration.store.MessageGroup; @@ -138,9 +132,6 @@ public abstract class AbstractConfigurableMongoDbMessageStore extends AbstractMe this.mappingMongoConverter.afterPropertiesSet(); } this.mongoTemplate = new MongoTemplate(this.mongoDbFactory, this.mappingMongoConverter); - if (this.applicationContext != null) { - this.mongoTemplate.setApplicationContext(this.applicationContext); - } } this.messageBuilderFactory = IntegrationUtils.getMessageBuilderFactory(this.applicationContext); @@ -263,35 +254,4 @@ public abstract class AbstractConfigurableMongoDbMessageStore extends AbstractMe throw new UnsupportedOperationException("The operation isn't implemented for this class."); } - /** - * A {@link GenericConverter} implementation to convert {@link Message} to - * serialized {@link byte[]} to store {@link Message} to the MongoDB. - * And vice versa - to convert {@link byte[]} from the MongoDB to the {@link Message}. - */ - private static class MongoDbMessageBytesConverter implements GenericConverter { - - private final Converter serializingConverter = new SerializingConverter(); - - private final Converter deserializingConverter = new DeserializingConverter(); - - @Override - public Set getConvertibleTypes() { - Set convertiblePairs = new HashSet(); - convertiblePairs.add(new ConvertiblePair(Message.class, byte[].class)); - convertiblePairs.add(new ConvertiblePair(byte[].class, Message.class)); - return convertiblePairs; - } - - @Override - public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - if (Message.class.isAssignableFrom(sourceType.getObjectType())) { - return this.serializingConverter.convert(source); - } - else { - return this.deserializingConverter.convert((byte[]) source); - } - } - - } - } diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java index 0800afc08d..fcb99a4845 100644 --- a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/store/MongoDbMessageStore.java @@ -169,7 +169,6 @@ public class MongoDbMessageStore extends AbstractMessageGroupStore @Override public void afterPropertiesSet() throws Exception { if (this.applicationContext != null) { - this.template.setApplicationContext(this.applicationContext); this.converter.setApplicationContext(this.applicationContext); } this.converter.afterPropertiesSet(); diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoDbMessageBytesConverter.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoDbMessageBytesConverter.java new file mode 100644 index 0000000000..6b8395b3f2 --- /dev/null +++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoDbMessageBytesConverter.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 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.support; + +import java.util.HashSet; +import java.util.Set; + +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.GenericConverter; +import org.springframework.core.serializer.support.DeserializingConverter; +import org.springframework.core.serializer.support.SerializingConverter; +import org.springframework.messaging.Message; + +/** + * A {@link GenericConverter} implementation to convert {@link Message} to + * serialized {@link byte[]} to store {@link Message} to the MongoDB. + * And vice versa - to convert {@link byte[]} from the MongoDB to the {@link Message}. + + * @author Artem Bilan + * @since 4.2.10 + */ +public class MongoDbMessageBytesConverter implements GenericConverter { + + private final Converter serializingConverter = new SerializingConverter(); + + private final Converter deserializingConverter = new DeserializingConverter(); + + @Override + public Set getConvertibleTypes() { + Set convertiblePairs = new HashSet(); + convertiblePairs.add(new ConvertiblePair(Message.class, byte[].class)); + convertiblePairs.add(new ConvertiblePair(byte[].class, Message.class)); + return convertiblePairs; + } + + @Override + public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { + if (Message.class.isAssignableFrom(sourceType.getObjectType())) { + return this.serializingConverter.convert(source); + } + else { + return this.deserializingConverter.convert((byte[]) source); + } + } + +} diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/ConfigurableMongoDbMessageStore-CustomConverter.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/ConfigurableMongoDbMessageStore-CustomConverter.xml index ef4b35e43c..ff0a6d8972 100644 --- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/ConfigurableMongoDbMessageStore-CustomConverter.xml +++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/ConfigurableMongoDbMessageStore-CustomConverter.xml @@ -12,6 +12,8 @@ + + diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationConfigurableTests-context.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationConfigurableTests-context.xml index 3713864e60..87cfc91b9d 100644 --- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationConfigurableTests-context.xml +++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationConfigurableTests-context.xml @@ -2,8 +2,12 @@ + http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd"> + + diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationTests-context.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationTests-context.xml index a6ce73f3ad..074ca447b1 100644 --- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationTests-context.xml +++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/DelayerHandlerRescheduleIntegrationTests-context.xml @@ -2,8 +2,12 @@ + http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd"> + + diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-config.xml index 40044438bd..cb3231ae9c 100644 --- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-config.xml +++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-config.xml @@ -1,13 +1,17 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:int="http://www.springframework.org/schema/integration" + xmlns:mongo="http://www.springframework.org/schema/data/mongo" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd"> + + diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-configurable-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-configurable-config.xml index 1f4e4f1bac..7aa0279ccc 100644 --- a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-configurable-config.xml +++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/mongo-aggregator-configurable-config.xml @@ -1,13 +1,17 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:int="http://www.springframework.org/schema/integration" + xmlns:mongo="http://www.springframework.org/schema/data/mongo" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd"> + + diff --git a/src/reference/asciidoc/mongodb.adoc b/src/reference/asciidoc/mongodb.adoc index 0b860a6c84..671e4c5fca 100644 --- a/src/reference/asciidoc/mongodb.adoc +++ b/src/reference/asciidoc/mongodb.adoc @@ -13,7 +13,7 @@ To download, install, and run MongoDB please refer to the http://www.mongodb.org === Connecting to MongoDb To begin interacting with MongoDB you first need to connect to it. -Spring Integration builds on the support provided by another Spring project, http://www.springsource.org/spring-data/mongodb[Spring Data MongoDB], which provides a factory class called `MongoDbFactory` that simplifies integration with the MongoDB Client API. +Spring Integration builds on the support provided by another Spring project, http://projects.spring.io/spring-data-mongodb/[Spring Data MongoDB], which provides a factory class called `MongoDbFactory` that simplifies integration with the MongoDB Client API. _MongoDbFactory_ @@ -63,16 +63,16 @@ Or in Spring's XML configuration: As you can see `SimpleMongoDbFactory` takes two arguments: 1) a `Mongo` instance and 2) a String specifying the name of the database. If you need to configure properties such as `host`, `port`, etc, you can pass those using one of the constructors provided by the underlying `Mongo` class. -For more information on how to configure MongoDB, please refer to thehttp://static.springsource.org/spring-data/data-document/docs/current/reference/html/[Spring-Data-Document] reference. +For more information on how to configure MongoDB, please refer to the http://docs.spring.io/spring-data/data-mongo/docs/current/reference/html/[Spring-Data-MongoDB] reference. [[mongodb-message-store]] === MongoDB Message Store As described in EIP, a http://www.eaipatterns.com/MessageStore.html[Message Store] allows you to persist Messages. This can be very useful when dealing with components that have a capability to buffer messages (_QueueChannel, Aggregator, Resequencer_, etc.) if reliability is a concern. -In Spring Integration, the MessageStore strategy also provides the foundation for thehttp://www.eaipatterns.com/StoreInLibrary.html[ClaimCheck] pattern, which is described in EIP as well. +In Spring Integration, the `MessageStore` strategy also provides the foundation for the http://www.eaipatterns.com/StoreInLibrary.html[ClaimCheck] pattern, which is described in EIP as well. -Spring Integration's MongoDB module provides the `MongoDbMessageStore` which is an implementation of both the `MessageStore` strategy (mainly used by the _ClaimCheck_pattern) and the `MessageGroupStore` strategy (mainly used by the _Aggregator_ and _Resequencer_ patterns). +Spring Integration's MongoDB module provides the `MongoDbMessageStore` which is an implementation of both the `MessageStore` strategy (mainly used by the _ClaimCheck_ pattern) and the `MessageGroupStore` strategy (mainly used by the _Aggregator_ and _Resequencer_ patterns). [source,xml] ---- @@ -102,7 +102,7 @@ To achieve these capabilities, an alternative MongoDB `MessageStore` implementat _Spring Integration 3.0_ introduced the `ConfigurableMongoDbMessageStore` - `MessageStore` and `MessageGroupStore` implementation. This class can receive, as a constructor argument, a `MongoTemplate`, with which you can configure with a custom `WriteConcern`, for example. Another constructor requires a `MappingMongoConverter`, and a `MongoDbFactory`, which allows you to provide some custom conversions for `Message` s and their properties. -Note, by default, the `ConfigurableMongoDbMessageStore` uses standard Java serialization to write/read `Message` s to/from MongoDB and relies on default values for other properties from `MongoTemplate`, which is built from the provided `MongoDbFactory` and `MappingMongoConverter`. +Note, by default, the `ConfigurableMongoDbMessageStore` uses standard Java serialization to write/read `Message` s to/from MongoDB (see `MongoDbMessageBytesConverter`) and relies on default values for other properties from `MongoTemplate`, which is built from the provided `MongoDbFactory` and `MappingMongoConverter`. The default name for the collection stored by the `ConfigurableMongoDbMessageStore` is `configurableStoreMessages`. It is recommended to use this implementation for robust and flexible solutions when messages contain complex data types. @@ -213,17 +213,19 @@ You can do this using Transaction Synchronization feature that was added with Sp [source,xml] ---- - - - + channel="replyChannel" + query="{'name' : 'Bob'}" + entity-class="java.lang.Object" + auto-startup="false"> + + + - + @@ -234,14 +236,14 @@ You can do this using Transaction Synchronization feature that was added with Sp [source,java] ---- public class DocumentCleaner { - public void remove(MongoOperations mongoOperations, Object target, String collectionName) { - if (target instanceof List){ - List documents = (List) target; - for (Object document : documents) { - mongoOperations.remove(new BasicQuery(JSON.serialize(document)), collectionName); - } - } - } + public void remove(MongoOperations mongoOperations, Object target, String collectionName) { + if (target instanceof List){ + List documents = (List) target; + for (Object document : documents) { + mongoOperations.remove(new BasicQuery(JSON.serialize(document)), collectionName); + } + } + } } ---- @@ -252,7 +254,7 @@ If you don't have a 'real' transaction, you can use a `org.springframework.integ IMPORTANT: This does NOT make MongoDB itself transactional, it simply allows the synchronization of actions to be taken before/after success (commit) or after failure (rollback). Once your poller is transactional all you need to do is set an instance of the `o.s.i.transaction.TransactionSynchronizationFactory` on the `transactional` element. -`TransactionSynchronizationFactory` will create an instance of the `TransactioinSynchronization`. +`TransactionSynchronizationFactory` will create an instance of the `TransactionSynchronization`. For your convenience, we've exposed a default SpEL-based `TransactionSynchronizationFactory` which allows you to configure SpEL expressions, with their execution being coordinated (synchronized) with a transaction. Expressions for before-commit, after-commit, and after-rollback are supported, together with a channel for each where the evaluation result (if any) will be sent. For each sub-element you can specify `expression` and/or `channel` attributes.