diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParser.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParser.java
new file mode 100644
index 0000000000..56b82a1d3e
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParser.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.mongodb.inbound.MongoDbMessageSource;
+/**
+ * Parser for Mongodb store inbound adapters
+ *
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ * @since 2.2
+ */
+public class MongoDbInboundChannelAdapterParser extends AbstractPollingInboundChannelAdapterParser {
+
+ @Override
+ protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MongoDbMessageSource.class);
+
+ // Will parse and validate 'mongodb-template', 'mongodb-factory',
+ // 'collection-name', 'collection-name-expression' and 'mongo-converter'
+ MongoParserUtils.processCommonAttributes(element, parserContext, builder);
+
+ RootBeanDefinition queryExpressionDef =
+ IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("query", "query-expression",
+ parserContext, element, true);
+
+ builder.addConstructorArgValue(queryExpressionDef);
+
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "entity-class");
+ IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expect-single-result");
+
+ String beanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
+ builder.getBeanDefinition(), parserContext.getRegistry());
+ return new RuntimeBeanReference(beanName);
+ }
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbNamespaceHandler.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbNamespaceHandler.java
new file mode 100644
index 0000000000..e5ff963b5d
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbNamespaceHandler.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
+
+/**
+ * Namespace handler for Spring Integration's 'mongodb' namespace.
+ *
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ *
+ * @since 2.2
+ */
+public class MongoDbNamespaceHandler extends AbstractIntegrationNamespaceHandler {
+
+ public void init() {
+ registerBeanDefinitionParser("inbound-channel-adapter", new MongoDbInboundChannelAdapterParser());
+ registerBeanDefinitionParser("outbound-channel-adapter", new MongoDbOutboundChannelAdapterParser());
+ }
+}
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParser.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParser.java
new file mode 100644
index 0000000000..cfa509c9ca
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParser.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007-2012 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.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
+import org.springframework.integration.mongodb.outbound.MongoDbStoringMessageHandler;
+/**
+ * Parser for Mongodb store outbound adapters
+ *
+ * @author Oleg Zhurakousky
+ * @since 2.2
+ */
+public class MongoDbOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
+
+ @Override
+ protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoDbStoringMessageHandler.class);
+
+ // Will parse and validate 'mongodb-template', 'mongodb-factory',
+ // 'collection-name', 'collection-name-expression' and 'mongo-converter'
+ MongoParserUtils.processCommonAttributes(element, parserContext, builder);
+
+ return builder.getBeanDefinition();
+ }
+}
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoParserUtils.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoParserUtils.java
new file mode 100644
index 0000000000..5f1bc8941e
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/MongoParserUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+/**
+ * Utility class used by mongo parsers
+ *
+ * @author Oleg Zhurakousky
+ * @author Gary Russell
+ * @since 2.2
+ */
+class MongoParserUtils {
+
+ /**
+ * Will parse and validate
+ * 'mongodb-template', 'mongodb-factory', 'collection-name', 'collection-name-expression' and 'mongo-converter'
+ *
+ * @param element
+ * @param parserContext
+ * @param builder
+ */
+ public static void processCommonAttributes(Element element, ParserContext parserContext, BeanDefinitionBuilder builder){
+ String mongoDbTemplate = element.getAttribute("mongo-template");
+ String mongoDbFactory = element.getAttribute("mongodb-factory");
+
+ if (StringUtils.hasText(mongoDbTemplate) && StringUtils.hasText(mongoDbFactory)){
+ parserContext.getReaderContext().error("Only one of '" + mongoDbTemplate + "' or '"
+ + mongoDbFactory + "' is allowed", element);
+ }
+
+ if (StringUtils.hasText(mongoDbTemplate)){
+ builder.addConstructorArgReference(mongoDbTemplate);
+ if (StringUtils.hasText(element.getAttribute("mongo-converter"))) {
+ parserContext.getReaderContext().error("'mongo-converter' is not allowed with 'mongo-template'",
+ element);
+ }
+ }
+ else {
+ if (!StringUtils.hasText(mongoDbFactory)) {
+ mongoDbFactory = "mongoDbFactory";
+ }
+ builder.addConstructorArgReference(mongoDbFactory);
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "mongo-converter");
+ }
+
+ RootBeanDefinition collectionNameExpressionDef =
+ IntegrationNamespaceUtils.createExpressionDefinitionFromValueOrExpression("collection-name", "collection-name-expression",
+ parserContext, element, false);
+
+
+ if (collectionNameExpressionDef != null){
+ builder.addPropertyValue("collectionNameExpression", collectionNameExpressionDef);
+ }
+
+ }
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/package-info.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/package-info.java
new file mode 100644
index 0000000000..682a467d53
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains parser classes for the MongoDb namespace support.
+ */
+package org.springframework.integration.mongodb.config;
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSource.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSource.java
new file mode 100644
index 0000000000..d07ae89bc2
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSource.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2007-2012 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.inbound;
+
+import java.util.List;
+
+import org.springframework.context.MessageSource;
+import org.springframework.data.mongodb.MongoDbFactory;
+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;
+import org.springframework.expression.Expression;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.integration.Message;
+import org.springframework.integration.context.IntegrationObjectSupport;
+import org.springframework.integration.core.PseudoTransactionalMessageSource;
+import org.springframework.integration.mongodb.support.MongoHeaders;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.integration.util.ExpressionUtils;
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+import com.mongodb.DBObject;
+
+/**
+ * An instance of {@link MessageSource} which returns a {@link Message} with a payload
+ * which is the result of execution of a {@link Query}. When expectSingleResult is false
+ * (default),
+ * the MongoDb {@link Query} is executed using {@link MongoOperations#find(Query, Class)}
+ * method which returns a {@link List}. The returned {@link List} will be used as
+ * the payoad of the {@link Message} returned by the {{@link #receive()} method.
+ * An empty {@link List} is treated as null, thus resulting in no {@link Message} returned
+ * by the {{@link #receive()} method.
+ *
+ * When expectSingleResult is true, the {@link MongoOperations#findOne(Query, Class)} is
+ * used instead, and the message payload will be the single object returned from the
+ * query.
+ *
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ *
+ * @since 2.2
+ */
+public class MongoDbMessageSource extends IntegrationObjectSupport
+ implements PseudoTransactionalMessageSource{
+
+ private final Expression queryExpression;
+
+ private volatile Expression collectionNameExpression = new LiteralExpression("data");
+
+ private volatile StandardEvaluationContext evaluationContext;
+
+ private volatile MongoOperations mongoTemplate;
+
+ private volatile MongoConverter mongoConverter;
+
+ private volatile MongoDbFactory mongoDbFactory;
+
+ private volatile boolean initialized = false;
+
+ private volatile Class> entityClass = DBObject.class;
+
+ private volatile boolean expectSingleResult = false;
+
+ /**
+ * Creates an instance with the provided {@link MongoDbFactory} and SpEL expression
+ * which should resolve to a MongoDb 'query' string
+ * (see http://www.mongodb.org/display/DOCS/Querying).
+ * The 'queryExpression' will be evaluated on every call to the {@link #receive()} method.
+ *
+ * @param mongoDbFactory
+ * @param queryExpression
+ */
+ public MongoDbMessageSource(MongoDbFactory mongoDbFactory, Expression queryExpression){
+ Assert.notNull(mongoDbFactory, "'mongoDbFactory' must not be null");
+ Assert.notNull(queryExpression, "'queryExpression' must not be null");
+
+ this.mongoDbFactory = mongoDbFactory;
+ this.queryExpression = queryExpression;
+ }
+
+ /**
+ * Creates an instance with the provided {@link MongoOperations} and SpEL expression
+ * which should resolve to a Mongo 'query' string
+ * (see http://www.mongodb.org/display/DOCS/Querying).
+ * It assumes that the {@link MongoOperations} is fully initialized and ready to be used.
+ * The 'queryExpression' will be evaluated on every call to the {@link #receive()} method.
+ *
+ * @param mongoTemplate
+ * @param queryExpression
+ */
+ public MongoDbMessageSource(MongoOperations mongoTemplate, Expression queryExpression){
+ Assert.notNull(mongoTemplate, "'mongoTemplate' must not be null");
+ Assert.notNull(queryExpression, "'queryExpression' must not be null");
+
+ this.mongoTemplate = mongoTemplate;
+ this.queryExpression = queryExpression;
+ }
+
+ /**
+ * Allows you to set the type of the entityClass that will be passed to the
+ * {@link MongoTemplate#find(Query, Class)} or {@link MongoTemplate#findOne(Query, Class)}
+ * method.
+ * Default is {@link DBObject}.
+ *
+ * @param entityClass
+ */
+ public void setEntityClass(Class> entityClass) {
+ Assert.notNull(entityClass, "'entityClass' must not be null");
+ this.entityClass = entityClass;
+ }
+
+ /**
+ * Allows you to manage which find* method to invoke on {@link MongoTemplate}.
+ * Default is 'false', which means the {@link #receive()} method will use
+ * the {@link MongoTemplate#find(Query, Class)} method. If set to 'true',
+ * {@link #receive()} will use {@link MongoTemplate#findOne(Query, Class)},
+ * and the payload of the returned {@link Message} will be the returned target Object of type
+ * identified by {{@link #entityClass} instead of a List.
+ *
+ * @param expectSingleResult
+ */
+ public void setExpectSingleResult(boolean expectSingleResult) {
+ this.expectSingleResult = expectSingleResult;
+ }
+
+ /**
+ * Sets the SpEL {@link Expression} that should resolve to a collection name
+ * used by the {@link Query}. The resulting collection name will be included
+ * in the {@link MongoHeaders#COLLECTION_NAME} header.
+ *
+ * @param collectionNameExpression
+ */
+ public void setCollectionNameExpression(Expression collectionNameExpression) {
+ Assert.notNull(collectionNameExpression, "'collectionNameExpression' must not be null");
+ this.collectionNameExpression = collectionNameExpression;
+ }
+
+ /**
+ * Allows you to provide a custom {@link MongoConverter} used to assist in deserialization
+ * data read from MongoDb. Only allowed if this instance was constructed with a
+ * {@link MongoDbFactory}.
+ *
+ * @param mongoConverter
+ */
+ public void setMongoConverter(MongoConverter mongoConverter) {
+ Assert.isNull(this.mongoTemplate,
+ "'mongoConverter' can not be set when instance was constructed with MongoTemplate");
+ this.mongoConverter = mongoConverter;
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ if (this.getBeanFactory() != null){
+ this.evaluationContext =
+ ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
+ }
+ else {
+ this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
+ }
+
+ if (this.mongoTemplate == null){
+ this.mongoTemplate = new MongoTemplate(this.mongoDbFactory, this.mongoConverter);
+ }
+ this.initialized = true;
+ }
+
+ /**
+ * Will execute a {@link Query} returning its results as the Message payload.
+ * The payload can be either {@link List} of elements of objects of type
+ * identified by {{@link #entityClass}, or a single element of type identified by {{@link #entityClass}
+ * based on the value of {{@link #expectSingleResult} attribute which defaults to 'false' resulting
+ * {@link Message} with payload of type {@link List}. The collection name used in the
+ * query will be provided in the {@link MongoHeaders#COLLECTION_NAME} header.
+ */
+ public Message receive() {
+ Assert.isTrue(this.initialized, "This class is not yet initialized. Invoke its afterPropertiesSet() method");
+ Message message = null;
+ Query query = new BasicQuery(this.queryExpression.getValue(this.evaluationContext, String.class));
+ Assert.notNull(query, "'queryExpression' must not evaluate to null");
+ String collectionName = this.collectionNameExpression.getValue(this.evaluationContext, String.class);
+ Assert.notNull(collectionName, "'collectionNameExpression' must not evaluate to null");
+
+ Object result = null;
+ if (this.expectSingleResult){
+ result = this.mongoTemplate.
+ findOne(query, this.entityClass, collectionName);
+ }
+ else {
+ List> results = this.mongoTemplate.
+ find(query, this.entityClass, collectionName);
+ if (!CollectionUtils.isEmpty(results)){
+ result = results;
+ }
+ }
+ if (result != null){
+ message = MessageBuilder.withPayload(result)
+ .setHeader(MongoHeaders.COLLECTION_NAME, collectionName)
+ .build();
+ }
+
+ return message;
+ }
+
+ /**
+ * Returns the mongo-template.
+ */
+ public MongoOperations getResource() {
+ return this.mongoTemplate;
+ }
+
+ public void afterCommit(Object object) {
+
+ }
+
+ public void afterRollback(Object object) {
+
+ }
+
+ public void afterReceiveNoTx(MongoOperations resource) {
+
+ }
+
+ public void afterSendNoTx(MongoOperations resource) {
+
+ }
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/package-info.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/package-info.java
new file mode 100644
index 0000000000..d76784f51e
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/inbound/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides classes related to the Mongo inbound channel adapters
+ */
+package org.springframework.integration.mongodb.inbound;
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java
new file mode 100644
index 0000000000..b55130da3a
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandler.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2007-2012 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.springframework.data.mongodb.MongoDbFactory;
+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.expression.Expression;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.integration.Message;
+import org.springframework.integration.core.MessageHandler;
+import org.springframework.integration.handler.AbstractMessageHandler;
+import org.springframework.integration.util.ExpressionUtils;
+import org.springframework.util.Assert;
+/**
+ * Implementation of {@link MessageHandler} which writes Message payload into a MongoDb collection
+ * identified by evaluation of the {@link #collectionNameExpression}.
+ *
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ * @since 2.2
+ *
+ */
+public class MongoDbStoringMessageHandler extends AbstractMessageHandler {
+
+ private volatile MongoOperations mongoTemplate;
+
+ private volatile MongoDbFactory mongoDbFactory;
+
+ private volatile MongoConverter mongoConverter;
+
+ private volatile StandardEvaluationContext evaluationContext;
+
+ private volatile Expression collectionNameExpression = new LiteralExpression("data");
+
+ private volatile boolean initialized = false;
+
+ /**
+ * Will construct this instance using provided {@link MongoDbFactory}
+ *
+ * @param mongoDbFactory
+ */
+ public MongoDbStoringMessageHandler(MongoDbFactory mongoDbFactory){
+ Assert.notNull(mongoDbFactory, "'mongoDbFactory' must not be null");
+
+ this.mongoDbFactory = mongoDbFactory;
+ }
+
+ /**
+ * Will construct this instance using fully created and initialized instance of
+ * provided {@link MongoOperations}
+ *
+ * @param mongoTemplate
+ */
+ public MongoDbStoringMessageHandler(MongoOperations mongoTemplate){
+ Assert.notNull(mongoTemplate, "'mongoTemplate' must not be null");
+
+ this.mongoTemplate = mongoTemplate;
+ }
+
+ /**
+ * Allows you to provide custom {@link MongoConverter} used to assist in serialization
+ * of data written to MongoDb. Only allowed if this instance was constructed with a
+ * {@link MongoDbFactory}.
+ *
+ * @param mongoConverter
+ */
+ public void setMongoConverter(MongoConverter mongoConverter) {
+ Assert.isNull(this.mongoTemplate,
+ "'mongoConverter' can not be set when instance was constructed with MongoTemplate");
+ this.mongoConverter = mongoConverter;
+ }
+
+ /**
+ * Sets the SpEL {@link Expression} that should resolve to a collection name
+ * used by {@link MongoOperations} to store data
+ *
+ * @param collectionNameExpression
+ */
+ public void setCollectionNameExpression(Expression collectionNameExpression) {
+ Assert.notNull(collectionNameExpression, "'collectionNameExpression' must not be null");
+ this.collectionNameExpression = collectionNameExpression;
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ if (this.getBeanFactory() != null) {
+ this.evaluationContext =
+ ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
+ }
+ else {
+ this.evaluationContext = ExpressionUtils.createStandardEvaluationContext();
+ }
+ if (this.mongoTemplate == null){
+ this.mongoTemplate = new MongoTemplate(this.mongoDbFactory, this.mongoConverter);
+ }
+ this.initialized = true;
+ }
+
+ @Override
+ protected void handleMessageInternal(Message> message) throws Exception {
+ Assert.isTrue(this.initialized, "This class is not yet initialized. Invoke its afterPropertiesSet() method");
+ String collectionName = this.collectionNameExpression.getValue(this.evaluationContext, message, String.class);
+ Assert.notNull(collectionName, "'collectionNameExpression' must not evaluate to null");
+
+ Object payload = message.getPayload();
+
+ this.mongoTemplate.save(payload, collectionName);
+ }
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/package-info.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/package-info.java
new file mode 100644
index 0000000000..76f94d97ab
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/outbound/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides classes related to the Mongo outbound channel adapters
+ */
+package org.springframework.integration.mongodb.outbound;
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoHeaders.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoHeaders.java
new file mode 100644
index 0000000000..19308dc82f
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/MongoHeaders.java
@@ -0,0 +1,16 @@
+package org.springframework.integration.mongodb.support;
+
+/**
+ * Pre-defined names and prefixes to be used for
+ * for dealing with headers required by Mongo components
+ *
+ * @author Gary Russell
+ * @since 2.2
+ */
+public class MongoHeaders {
+
+ public static final String PREFIX = "mongo_";
+
+ public static final String COLLECTION_NAME = PREFIX + "collectionName";
+
+}
diff --git a/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/package-info.java b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/package-info.java
new file mode 100644
index 0000000000..fa8441666b
--- /dev/null
+++ b/spring-integration-mongodb/src/main/java/org/springframework/integration/mongodb/support/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides supporting classes for this module.
+ */
+package org.springframework.integration.mongodb.support;
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/resources/META-INF/spring.handlers b/spring-integration-mongodb/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 0000000000..2eeef28742
--- /dev/null
+++ b/spring-integration-mongodb/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://www.springframework.org/schema/integration/mongodb=org.springframework.integration.mongodb.config.MongoDbNamespaceHandler
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/resources/META-INF/spring.schemas b/spring-integration-mongodb/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 0000000000..ddab48351f
--- /dev/null
+++ b/spring-integration-mongodb/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1,2 @@
+http\://www.springframework.org/schema/integration/mongodb/spring-integration-mongodb-2.2.xsd=org/springframework/integration/mongodb/config/spring-integration-mongodb-2.2.xsd
+http\://www.springframework.org/schema/integration/mongodb/spring-integration-mongodb.xsd=org/springframework/integration/mongodb/config/spring-integration-mongodb-2.2.xsd
\ No newline at end of file
diff --git a/spring-integration-mongodb/src/main/resources/META-INF/spring.tooling b/spring-integration-mongodb/src/main/resources/META-INF/spring.tooling
new file mode 100644
index 0000000000..49bdf56465
--- /dev/null
+++ b/spring-integration-mongodb/src/main/resources/META-INF/spring.tooling
@@ -0,0 +1,4 @@
+# Tooling related information for the integration mongodb namespace
+http\://www.springframework.org/schema/integration/mongodb@name=integration mongodb Namespace
+http\://www.springframework.org/schema/integration/mongodb@prefix=int-mongodb
+http\://www.springframework.org/schema/integration/mongodb@icon=org/springframework/integration/mongodb/config/spring-integration-mongodb.gif
diff --git a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-2.2.xsd b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-2.2.xsd
new file mode 100644
index 0000000000..bb359f1da9
--- /dev/null
+++ b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb-2.2.xsd
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Defines mongodb inbound channel adapter that
+ creates
+
+
+
+
+
+
+
+
+
+
+
+ String representation of MongoDb Query (e.g.,
+ query="{'name' : 'Bob'}").
+ Please refer to MongoDb documentation for more query samples
+ http://www.mongodb.org/display/DOCS/Querying
+ This attribute is
+ mutually exclusive with 'query-expression' attribute.
+
+
+
+
+
+
+ SpEL expression which should resolve to a
+ String value identifying the
+ MongoDb Query. Also see 'query' attribute
+ This attribute is mutually exclusive with 'query' attribute.
+
+
+
+
+
+
+
+ The fully qualified name of the entity class to be passed to
+ find(..) or findOne(..) method MongoTemplate.
+ If this attribute is not provided the default value is com.mongodb.DBObject
+
+
+
+
+
+
+
+
+
+
+ Allows you to manage find* method of MongoTemplate is used to query MongoDb. Default value for this
+ attribute is 'false'. This means that we'll use find(..) method thus resulting in a Message with
+ payload of type List of entities identified by 'entity-class' attribute. If you want/expect a single
+ value set this attribute to 'true' which will result in invocation of findOne(..) method resulting in
+ the payload of type identified by 'entity-class' attribute (default com.mongodb.DBObject)
+
+
+
+
+
+
+
+
+
+
+
+ Defines mongodb outbound channel adapter that
+ writes the contents of the
+ Message into
+ org.springframework.data.mongodb.support.collections.mongodbStore
+
+
+
+
+
+
+
+
+
+
+
+
+ Common configuration for mongodb adapters.
+
+
+
+
+
+
+ Reference to a Message Channel that will be used
+ by this adapter to
+ 'receiveFrom' or 'sendTo' Messages depending on the adapter type (e.g.,
+ inbound/outbound)
+
+
+
+
+
+
+
+
+ Reference to an instance of
+ org.springframework.data.mongodb.MongoDbFactory
+
+
+
+
+
+
+
+
+
+
+
+ Reference to an instance of
+ org.springframework.data.mongodb.core.MongoTemplate
+
+
+
+
+
+
+
+
+
+ Identifies the name of the MongoDb collection to
+ use.
+ This attribute is mutually exclusive with
+ 'collection-name-expression'
+ attribute.
+
+
+
+
+
+
+ SpEL expression which should resolve to a String
+ value identifying the
+ name of the MongoDb collection to use.
+ This
+ attribute is mutually exclusive with 'collection-name' attribute.
+
+
+
+
+
+
+
+
+
+
+
+ Reference to an instance of
+ org.springframework.data.mongodb.core.convert.MongoConverter
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb.gif b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb.gif
new file mode 100644
index 0000000000..351817f7b3
Binary files /dev/null and b/spring-integration-mongodb/src/main/resources/org/springframework/integration/mongodb/config/spring-integration-mongodb.gif differ
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterIntegrationTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterIntegrationTests.java
new file mode 100644
index 0000000000..7fb3d045a8
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterIntegrationTests.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.BasicQuery;
+import org.springframework.integration.Message;
+import org.springframework.integration.channel.QueueChannel;
+import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
+import org.springframework.integration.mongodb.rules.MongoDbAvailable;
+import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
+
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+/**
+ * @author Oleg Zhurakousky
+ * @since 2.2
+ */
+public class MongoDbInboundChannelAdapterIntegrationTests extends MongoDbAvailableTests {
+
+ @Test
+ @MongoDbAvailable
+ public void testWithDefaultMongoFactory() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "data");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapter", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message> message = (Message>) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().get(0).getName());
+ assertNotNull(replyChannel.receive(1000));
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithNamedMongoFactory() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "data");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterNamedFactory", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message> message = (Message>) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().get(0).get("name"));
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithMongoTemplate() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "data");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithTemplate", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message message = (Message) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().getName());
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithNamedCollection() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "foo");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithNamedCollection", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message> message = (Message>) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().get(0).getName());
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithNamedCollectionExpression() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "foo");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithNamedCollectionExpression", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message> message = (Message>) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().get(0).getName());
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithOnSuccessDisposition() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "data");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("inboundAdapterWithOnSuccessDisposition", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ assertNotNull(replyChannel.receive(1000));
+ Thread.sleep(300);
+ assertNull(replyChannel.receive(1000));
+ spca.stop();
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithMongoConverter() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Bob"), "data");
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("inbound-adapter-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("mongoInboundAdapterWithConverter", SourcePollingChannelAdapter.class);
+ QueueChannel replyChannel = context.getBean("replyChannel", QueueChannel.class);
+ spca.start();
+
+ @SuppressWarnings("unchecked")
+ Message> message = (Message>) replyChannel.receive(1000);
+ assertNotNull(message);
+ assertEquals("Bob", message.getPayload().get(0).getName());
+ assertNotNull(replyChannel.receive(1000));
+ spca.stop();
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ @MongoDbAvailable
+ public void testFailureWithQueryAndQueryExpression() throws Exception{
+ new ClassPathXmlApplicationContext("inbound-fail-q-qex.xml", this.getClass());
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ @MongoDbAvailable
+ public void testFailureWithFactoryAndTemplate() throws Exception{
+ new ClassPathXmlApplicationContext("inbound-fail-factory-template.xml", this.getClass());
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ @MongoDbAvailable
+ public void testFailureWithCollectionAndCollectioinExpression() throws Exception{
+ new ClassPathXmlApplicationContext("inbound-fail-c-cex.xml", this.getClass());
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ @MongoDbAvailable
+ public void testFailureWithTemplateAndConverter() throws Exception{
+ new ClassPathXmlApplicationContext("inbound-fail-converter-template.xml", this.getClass());
+ }
+
+ public static 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);
+ }
+ }
+ }
+ }
+
+}
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParserTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParserTests.java
new file mode 100644
index 0000000000..7e31fd8939
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbInboundChannelAdapterParserTests.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.expression.spel.standard.SpelExpression;
+import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
+import org.springframework.integration.mongodb.inbound.MongoDbMessageSource;
+import org.springframework.integration.test.util.TestUtils;
+/**
+ * @author Oleg Zhurakousky
+ */
+public class MongoDbInboundChannelAdapterParserTests {
+
+ @Test
+ public void minimalConfig(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("minimalConfig.adapter", SourcePollingChannelAdapter.class);
+ MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
+
+ assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
+ assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("data", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
+ }
+
+ @Test
+ public void fullConfigWithCollectionExpression(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("fullConfigWithCollectionExpression.adapter", SourcePollingChannelAdapter.class);
+ MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
+
+ assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
+ assertEquals(context.getBean("mongoConverter"), TestUtils.getPropertyValue(source, "mongoConverter"));
+ assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof SpelExpression);
+ assertEquals("'foo'", TestUtils.getPropertyValue(source, "collectionNameExpression.expression"));
+ }
+
+ @Test
+ public void fullConfigWithCollectionName(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("fullConfigWithCollectionName.adapter", SourcePollingChannelAdapter.class);
+ MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
+
+ assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(source, "mongoDbFactory"));
+ assertEquals(context.getBean("mongoConverter"), TestUtils.getPropertyValue(source, "mongoConverter"));
+ assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("foo", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
+ }
+
+ @Test
+ public void fullConfigWithMongoTemplate(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-config.xml", this.getClass());
+ SourcePollingChannelAdapter spca = context.getBean("fullConfigWithMongoTemplate.adapter", SourcePollingChannelAdapter.class);
+ MongoDbMessageSource source = TestUtils.getPropertyValue(spca, "source", MongoDbMessageSource.class);
+
+ assertEquals(false, TestUtils.getPropertyValue(spca, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(source, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbTemplate"), TestUtils.getPropertyValue(source, "mongoTemplate"));
+ assertNotNull(TestUtils.getPropertyValue(source, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(source, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("foo", TestUtils.getPropertyValue(source, "collectionNameExpression.literalValue"));
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ public void templateAndFactoryFail(){
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-fail-template-factory-config.xml", this.getClass());
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ public void templateAndConverterFail(){
+ new ClassPathXmlApplicationContext("inbound-adapter-parser-fail-template-converter-config.xml", this.getClass());
+ }
+}
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterIntegrationTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterIntegrationTests.java
new file mode 100644
index 0000000000..37f8d1f059
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterIntegrationTests.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.BasicQuery;
+import org.springframework.integration.Message;
+import org.springframework.integration.MessageChannel;
+import org.springframework.integration.message.GenericMessage;
+import org.springframework.integration.mongodb.rules.MongoDbAvailable;
+import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
+import org.springframework.integration.support.MessageBuilder;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.util.JSON;
+/**
+ * @author Oleg Zhurakousky
+ */
+public class MongoDbOutboundChannelAdapterIntegrationTests extends MongoDbAvailableTests {
+
+ @Test
+ @MongoDbAvailable
+ public void testWithDefaultMongoFactory() throws Exception{
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("outbound-adapter-config.xml", this.getClass());
+
+ MessageChannel channel = context.getBean("simpleAdapter", MessageChannel.class);
+ Message message = new GenericMessage(this.createPerson("Bob"));
+ channel.send(message);
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ assertNotNull(template.find(new BasicQuery("{'name' : 'Bob'}"), Person.class, "data"));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithNamedCollection() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory("foo");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("outbound-adapter-config.xml", this.getClass());
+
+ MessageChannel channel = context.getBean("simpleAdapterWithNamedCollection", MessageChannel.class);
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).setHeader("collectionName", "foo").build();
+ channel.send(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ assertNotNull(template.find(new BasicQuery("{'name' : 'Bob'}"), Person.class, "foo"));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithTemplate() throws Exception{
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory("foo");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("outbound-adapter-config.xml", this.getClass());
+
+ MessageChannel channel = context.getBean("simpleAdapterWithTemplate", MessageChannel.class);
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).setHeader("collectionName", "foo").build();
+ channel.send(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ assertNotNull(template.find(new BasicQuery("{'name' : 'Bob'}"), Person.class, "foo"));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testSavingDbObject() throws Exception{
+
+ BasicDBObject dbObject = (BasicDBObject) JSON.parse("{'foo' : 'bar'}");
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory("foo");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("outbound-adapter-config.xml", this.getClass());
+
+ MessageChannel channel = context.getBean("simpleAdapterWithTemplate", MessageChannel.class);
+ Message message = MessageBuilder.withPayload(dbObject).setHeader("collectionName", "foo").build();
+ channel.send(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ assertNotNull(template.find(new BasicQuery("{'foo' : 'bar'}"), BasicDBObject.class, "foo"));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void testWithMongoConverter() throws Exception{
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("outbound-adapter-config.xml", this.getClass());
+
+ MessageChannel channel = context.getBean("simpleAdapterWithConverter", MessageChannel.class);
+ Message message = new GenericMessage(this.createPerson("Bob"));
+ channel.send(message);
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ assertNotNull(template.find(new BasicQuery("{'name' : 'Bob'}"), Person.class, "data"));
+ }
+}
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParserTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParserTests.java
new file mode 100644
index 0000000000..dd4d14ccd1
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/MongoDbOutboundChannelAdapterParserTests.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2002-2012 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.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.expression.spel.standard.SpelExpression;
+import org.springframework.integration.mongodb.outbound.MongoDbStoringMessageHandler;
+import org.springframework.integration.test.util.TestUtils;
+/**
+ * @author Oleg Zhurakousky
+ */
+public class MongoDbOutboundChannelAdapterParserTests {
+
+ @Test
+ public void minimalConfig(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-config.xml", this.getClass());
+ MongoDbStoringMessageHandler handler =
+ TestUtils.getPropertyValue(context.getBean("minimalConfig.adapter"), "handler", MongoDbStoringMessageHandler.class);
+ assertEquals("minimalConfig.adapter", TestUtils.getPropertyValue(handler, "componentName"));
+ assertEquals(false, TestUtils.getPropertyValue(handler, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(handler, "mongoDbFactory"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(handler, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("data", TestUtils.getPropertyValue(handler, "collectionNameExpression.literalValue"));
+ }
+
+ @Test
+ public void fullConfigWithCollectionExpression(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-config.xml", this.getClass());
+ MongoDbStoringMessageHandler handler =
+ TestUtils.getPropertyValue(context.getBean("fullConfigWithCollectionExpression.adapter"), "handler", MongoDbStoringMessageHandler.class);
+ assertEquals("fullConfigWithCollectionExpression.adapter", TestUtils.getPropertyValue(handler, "componentName"));
+ assertEquals(false, TestUtils.getPropertyValue(handler, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(handler, "mongoDbFactory"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(handler, "collectionNameExpression") instanceof SpelExpression);
+ assertEquals("headers.collectionName", TestUtils.getPropertyValue(handler, "collectionNameExpression.expression"));
+ }
+
+ @Test
+ public void fullConfigWithCollection(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-config.xml", this.getClass());
+ MongoDbStoringMessageHandler handler =
+ TestUtils.getPropertyValue(context.getBean("fullConfigWithCollection.adapter"), "handler", MongoDbStoringMessageHandler.class);
+ assertEquals("fullConfigWithCollection.adapter", TestUtils.getPropertyValue(handler, "componentName"));
+ assertEquals(false, TestUtils.getPropertyValue(handler, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "mongoTemplate"));
+ assertEquals(context.getBean("mongoDbFactory"), TestUtils.getPropertyValue(handler, "mongoDbFactory"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(handler, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("foo", TestUtils.getPropertyValue(handler, "collectionNameExpression.literalValue"));
+ }
+
+ @Test
+ public void fullConfigWithMongoTemplate(){
+ ClassPathXmlApplicationContext context =
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-config.xml", this.getClass());
+ MongoDbStoringMessageHandler handler =
+ TestUtils.getPropertyValue(context.getBean("fullConfigWithMongoTemplate.adapter"), "handler", MongoDbStoringMessageHandler.class);
+ assertEquals("fullConfigWithMongoTemplate.adapter", TestUtils.getPropertyValue(handler, "componentName"));
+ assertEquals(false, TestUtils.getPropertyValue(handler, "shouldTrack"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "mongoTemplate"));
+ assertNotNull(TestUtils.getPropertyValue(handler, "evaluationContext"));
+ assertTrue(TestUtils.getPropertyValue(handler, "collectionNameExpression") instanceof LiteralExpression);
+ assertEquals("foo", TestUtils.getPropertyValue(handler, "collectionNameExpression.literalValue"));
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ public void templateAndFactoryFail(){
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-fail-template-factory-config.xml", this.getClass());
+ }
+
+ @Test(expected=BeanDefinitionParsingException.class)
+ public void templateAndConverterFail(){
+ new ClassPathXmlApplicationContext("outbound-adapter-parser-fail-template-converter-config.xml", this.getClass());
+ }
+}
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-config.xml
new file mode 100644
index 0000000000..5d6cd19452
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-config.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-config.xml
new file mode 100644
index 0000000000..8f9235e9d4
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-config.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-converter-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-converter-config.xml
new file mode 100644
index 0000000000..ddf64fc161
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-converter-config.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-factory-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-factory-config.xml
new file mode 100644
index 0000000000..e6cbdc205f
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-adapter-parser-fail-template-factory-config.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-c-cex.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-c-cex.xml
new file mode 100644
index 0000000000..58253861d6
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-c-cex.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-converter-template.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-converter-template.xml
new file mode 100644
index 0000000000..0f8e8c3e5a
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-converter-template.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-factory-template.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-factory-template.xml
new file mode 100644
index 0000000000..b6f45f0790
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-factory-template.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-q-qex.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-q-qex.xml
new file mode 100644
index 0000000000..925f277440
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/inbound-fail-q-qex.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-config.xml
new file mode 100644
index 0000000000..11f2bf4c2c
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-config.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-config.xml
new file mode 100644
index 0000000000..033665318f
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-config.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-converter-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-converter-config.xml
new file mode 100644
index 0000000000..92da91477a
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-converter-config.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-factory-config.xml b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-factory-config.xml
new file mode 100644
index 0000000000..1e23827597
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/config/outbound-adapter-parser-fail-template-factory-config.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSourceTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSourceTests.java
new file mode 100644
index 0000000000..cdb71b8aa2
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/inbound/MongoDbMessageSourceTests.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2007-2012 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.inbound;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
+import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.integration.mongodb.rules.MongoDbAvailable;
+import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
+
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+
+/**
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ *
+ * @since 2.2
+ *
+ */
+public class MongoDbMessageSourceTests extends MongoDbAvailableTests {
+ /**
+ * Tests by providing a null MongoDB Factory
+ *
+ */
+ @Test(expected=IllegalArgumentException.class)
+ public void withNullMongoDBFactory() {
+ Expression expression = mock(Expression.class);
+ new MongoDbMessageSource((MongoDbFactory)null, expression);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void withNullMongoTemplate() {
+ Expression expression = mock(Expression.class);
+ new MongoDbMessageSource((MongoOperations)null, expression);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void withNullQueryExpression() {
+ MongoDbFactory mongoDbFactory = mock(MongoDbFactory.class);
+ new MongoDbMessageSource(mongoDbFactory, null);
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithSinigleElementIfOneInListAsDbObject() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson(), "data");
+
+ Expression queryExpression = new LiteralExpression("{'name' : 'Oleg'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.afterPropertiesSet();
+ @SuppressWarnings("unchecked")
+ List results = ((List)messageSource.receive().getPayload());
+ assertEquals(1, results.size());
+ DBObject resultObject = results.get(0);
+
+ assertEquals("Oleg", resultObject.get("name"));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithSinigleElementIfOneInList() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson(), "data");
+
+ Expression queryExpression = new LiteralExpression("{'name' : 'Oleg'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.setEntityClass(Object.class);
+ messageSource.afterPropertiesSet();
+ @SuppressWarnings("unchecked")
+ List results = ((List)messageSource.receive().getPayload());
+ assertEquals(1, results.size());
+ Person person = results.get(0);
+ assertEquals("Oleg", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithSinigleElementIfOneInListAndSingleResult() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson(), "data");
+
+ Expression queryExpression = new LiteralExpression("{'name' : 'Oleg'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.setEntityClass(Object.class);
+ messageSource.setExpectSingleResult(true);
+ messageSource.afterPropertiesSet();
+ Person person = (Person)messageSource.receive().getPayload();
+
+ assertEquals("Oleg", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ }
+
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullSubObjectQueryWithSinigleElementIfOneInList() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson(), "data");
+
+ Expression queryExpression = new LiteralExpression("{'address.state' : 'PA'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.setEntityClass(Object.class);
+ messageSource.afterPropertiesSet();
+ @SuppressWarnings("unchecked")
+ List results = ((List)messageSource.receive().getPayload());
+ Person person = results.get(0);
+ assertEquals("Oleg", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithMultipleElements() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Manny"), "data");
+ template.save(this.createPerson("Moe"), "data");
+ template.save(this.createPerson("Jack"), "data");
+
+ Expression queryExpression = new LiteralExpression("{'address.state' : 'PA'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.afterPropertiesSet();
+ @SuppressWarnings("unchecked")
+ List persons = (List) messageSource.receive().getPayload();
+ assertEquals(3, persons.size());
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithNullReturn() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Manny"), "data");
+ template.save(this.createPerson("Moe"), "data");
+ template.save(this.createPerson("Jack"), "data");
+
+ Expression queryExpression = new LiteralExpression("{'address.state' : 'NJ'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.afterPropertiesSet();
+ assertNull(messageSource.receive());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithCustomConverter() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(this.createPerson("Manny"), "data");
+ template.save(this.createPerson("Moe"), "data");
+ template.save(this.createPerson("Jack"), "data");
+
+ Expression queryExpression = new LiteralExpression("{'address.state' : 'PA'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ MappingMongoConverter converter = new TestMongoConverter(mongoDbFactory, new MongoMappingContext());
+ converter.afterPropertiesSet();
+ converter = spy(converter);
+ messageSource.setMongoConverter(converter);
+ messageSource.afterPropertiesSet();
+
+ List persons = (List) messageSource.receive().getPayload();
+ assertEquals(3, persons.size());
+ verify(converter, times(3)).read((Class) Mockito.any(), Mockito.any(DBObject.class));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ @MongoDbAvailable
+ public void validateSuccessfullQueryWithMongoTemplate() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MappingMongoConverter converter = new TestMongoConverter(mongoDbFactory, new MongoMappingContext());
+ converter.afterPropertiesSet();
+ converter = spy(converter);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory, converter);
+ Expression queryExpression = new LiteralExpression("{'address.state' : 'PA'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(template, queryExpression);
+ messageSource.afterPropertiesSet();
+
+ MongoTemplate writingTemplate = new MongoTemplate(mongoDbFactory, converter);
+ writingTemplate.save(this.createPerson("Manny"), "data");
+ writingTemplate.save(this.createPerson("Moe"), "data");
+ writingTemplate.save(this.createPerson("Jack"), "data");
+
+ List persons = (List) messageSource.receive().getPayload();
+ assertEquals(3, persons.size());
+ verify(converter, times(3)).read((Class) Mockito.any(), Mockito.any(DBObject.class));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validatePipelineInModifyOut() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ template.save(JSON.parse("{'name' : 'Manny', 'id' : 1}"), "data");
+
+ Expression queryExpression = new LiteralExpression("{'name' : 'Manny'}");
+ MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression);
+ messageSource.setExpectSingleResult(true);
+ messageSource.afterPropertiesSet();
+ DBObject result = (DBObject) messageSource.receive().getPayload();
+ Object id = result.get("_id");
+ result.put("company","PepBoys");
+ template.save(result, "data");
+ result = (DBObject) messageSource.receive().getPayload();
+ assertEquals(id, result.get("_id"));
+ }
+}
diff --git a/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandlerTests.java b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandlerTests.java
new file mode 100644
index 0000000000..b564cafc82
--- /dev/null
+++ b/spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/outbound/MongoDbStoringMessageHandlerTests.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2007-2012 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 static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.springframework.data.mongodb.MongoDbFactory;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
+import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
+import org.springframework.data.mongodb.core.query.BasicQuery;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.expression.common.LiteralExpression;
+import org.springframework.integration.Message;
+import org.springframework.integration.mongodb.rules.MongoDbAvailable;
+import org.springframework.integration.mongodb.rules.MongoDbAvailableTests;
+import org.springframework.integration.support.MessageBuilder;
+
+import com.mongodb.DBObject;
+
+/**
+ * @author Amol Nayak
+ * @author Oleg Zhurakousky
+ *
+ * @since 2.2
+ */
+public class MongoDbStoringMessageHandlerTests extends MongoDbAvailableTests {
+
+ @Test(expected=IllegalArgumentException.class)
+ public void withNullMongoDBFactory() {
+ new MongoDbStoringMessageHandler((MongoDbFactory)null);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void withNullMongoTemplate() {
+ new MongoDbStoringMessageHandler((MongoOperations)null);
+ }
+
+
+ @Test
+ @MongoDbAvailable
+ public void validateMessageHandlingWithDefaultCollection() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoDbStoringMessageHandler handler = new MongoDbStoringMessageHandler(mongoDbFactory);
+ handler.afterPropertiesSet();
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).build();
+ handler.handleMessage(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ Query query = new BasicQuery("{'name' : 'Bob'}");
+ Person person = template.findOne(query, Person.class, "data");
+
+ assertEquals("Bob", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateMessageHandlingWithNamedCollection() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoDbStoringMessageHandler handler = new MongoDbStoringMessageHandler(mongoDbFactory);
+ handler.setCollectionNameExpression(new LiteralExpression("foo"));
+ handler.afterPropertiesSet();
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).build();
+ handler.handleMessage(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ Query query = new BasicQuery("{'name' : 'Bob'}");
+ Person person = template.findOne(query, Person.class, "foo");
+
+ assertEquals("Bob", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateMessageHandlingWithMongoConverter() throws Exception {
+
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MongoDbStoringMessageHandler handler = new MongoDbStoringMessageHandler(mongoDbFactory);
+ handler.setCollectionNameExpression(new LiteralExpression("foo"));
+ MappingMongoConverter converter = new TestMongoConverter(mongoDbFactory, new MongoMappingContext());
+ converter.afterPropertiesSet();
+ converter = spy(converter);
+ handler.setMongoConverter(converter);
+ handler.afterPropertiesSet();
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).build();
+ handler.handleMessage(message);
+
+ MongoTemplate template = new MongoTemplate(mongoDbFactory);
+ Query query = new BasicQuery("{'name' : 'Bob'}");
+ Person person = template.findOne(query, Person.class, "foo");
+
+ assertEquals("Bob", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ verify(converter, times(1)).write(Mockito.any(), Mockito.any(DBObject.class));
+ }
+
+ @Test
+ @MongoDbAvailable
+ public void validateMessageHandlingWithMongoTemplate() throws Exception {
+ MongoDbFactory mongoDbFactory = this.prepareMongoFactory();
+ MappingMongoConverter converter = new TestMongoConverter(mongoDbFactory, new MongoMappingContext());
+ converter.afterPropertiesSet();
+ converter = spy(converter);
+ MongoTemplate template = new MongoTemplate(mongoDbFactory, converter);
+
+
+ MongoDbStoringMessageHandler handler = new MongoDbStoringMessageHandler(template);
+ handler.setCollectionNameExpression(new LiteralExpression("foo"));
+ handler.afterPropertiesSet();
+ Message message = MessageBuilder.withPayload(this.createPerson("Bob")).build();
+ handler.handleMessage(message);
+
+ MongoTemplate readingTemplate = new MongoTemplate(mongoDbFactory);
+ Query query = new BasicQuery("{'name' : 'Bob'}");
+ Person person = readingTemplate.findOne(query, Person.class, "foo");
+
+ assertEquals("Bob", person.getName());
+ assertEquals("PA", person.getAddress().getState());
+ verify(converter, times(1)).write(Mockito.any(), Mockito.any(DBObject.class));
+ }
+}
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 1cd6cf2aea..3b2bdbb9ee 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
@@ -17,15 +17,21 @@
package org.springframework.integration.mongodb.rules;
import org.junit.Rule;
+
+import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
+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 com.mongodb.DBObject;
import com.mongodb.Mongo;
/**
* Convenience base class that enables unit test methods to rely upon the {@link MongoDbAvailable} annotation.
- *
+ *
* @author Oleg Zhurakousky
* @since 2.1
*/
@@ -33,13 +39,101 @@ public abstract class MongoDbAvailableTests {
@Rule
public MongoDbAvailableRule redisAvailableRule = new MongoDbAvailableRule();
-
-
- protected MongoDbFactory prepareMongoFactory() throws Exception{
+
+
+ protected MongoDbFactory prepareMongoFactory(String... additionalCollectionToDrop) throws Exception{
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(new Mongo(), "test");
MongoTemplate template = new MongoTemplate(mongoDbFactory);
template.dropCollection("messages");
+ template.dropCollection("data");
+ for (String additionalCollection : additionalCollectionToDrop) {
+ template.dropCollection(additionalCollection);
+ }
return mongoDbFactory;
}
+ public Person createPerson(){
+ Address address = new Address();
+ address.setCity("Philadelphia");
+ address.setStreet("2121 Rawn street");
+ address.setState("PA");
+
+ Person person = new Person();
+ person.setAddress(address);
+ person.setName("Oleg");
+ return person;
+ }
+
+ public Person createPerson(String name){
+ Address address = new Address();
+ address.setCity("Philadelphia");
+ address.setStreet("2121 Rawn street");
+ address.setState("PA");
+
+ Person person = new Person();
+ person.setAddress(address);
+ person.setName(name);
+ return person;
+ }
+
+ public static class Person {
+ private Address address;
+ private String name;
+ public Address getAddress() {
+ return address;
+ }
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ public static class Address {
+ private String street;
+ private String city;
+ private String state;
+ public String getStreet() {
+ return street;
+ }
+ public void setStreet(String street) {
+ this.street = street;
+ }
+ public String getCity() {
+ return city;
+ }
+ public void setCity(String city) {
+ this.city = city;
+ }
+ public String getState() {
+ return state;
+ }
+ public void setState(String state) {
+ this.state = state;
+ }
+ }
+
+ public static class TestMongoConverter extends MappingMongoConverter {
+
+ public TestMongoConverter(
+ MongoDbFactory mongoDbFactory,
+ MappingContext extends MongoPersistentEntity>, MongoPersistentProperty> mappingContext) {
+ super(mongoDbFactory, mappingContext);
+ }
+
+ @Override
+ public void write(Object source, DBObject target) {
+ super.write(source, target);
+ }
+
+ @Override
+ public S read(Class clazz, DBObject source) {
+ return super.read(clazz, source);
+ }
+ }
+
}