/* * Copyright 2016-2017 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.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import java.util.function.Function; import org.bson.Document; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.BulkOperations; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.convert.MongoConverter; 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.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.expression.FunctionExpression; import org.springframework.integration.mongodb.rules.MongoDbAvailable; import org.springframework.integration.mongodb.rules.MongoDbAvailableTests; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.mongodb.client.MongoCollection; /** * @author Xavier PadrĂ³ * @since 5.0 */ @ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext public class MongoDbOutboundGatewayTests extends MongoDbAvailableTests { private static final String COLLECTION_NAME = "data"; private static final SpelExpressionParser PARSER = new SpelExpressionParser(); @Autowired private BeanFactory beanFactory; @Autowired private MongoOperations mongoTemplate; @Autowired private MongoConverter mongoConverter; @Autowired private MongoDbFactory mongoDbFactory; @Before public void setUp() { BulkOperations bulkOperations = this.mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, COLLECTION_NAME); bulkOperations.insert(Arrays.asList( this.createPerson("Artem"), this.createPerson("Gary"), this.createPerson("Oleg"), this.createPerson("Xavi"))); bulkOperations.execute(); } @After public void cleanUp() { mongoTemplate.dropCollection(COLLECTION_NAME); } @SuppressWarnings("ConstantConditions") @Test @MongoDbAvailable public void testNoFactorySpecified() { MongoDbFactory nullFactory = null; try { new MongoDbOutboundGateway(nullFactory); Assert.fail("Expected the test case to throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { assertEquals("MongoDbFactory translator must not be null!", e.getMessage()); } } @SuppressWarnings("ConstantConditions") @Test @MongoDbAvailable public void testNoTemplateSpecified() { MongoOperations mongoTemplate = null; try { new MongoDbOutboundGateway(mongoTemplate); Assert.fail("Expected the test case to throw an IllegalArgumentException"); } catch (IllegalArgumentException e) { assertEquals("mongoTemplate must not be null.", e.getMessage()); } } @Test @MongoDbAvailable public void testNoQuerySpecified() { Message<String> message = MessageBuilder.withPayload("test").build(); MongoDbOutboundGateway gateway = createGateway(); try { gateway.afterPropertiesSet(); gateway.handleRequestMessage(message); Assert.fail("Expected the test case to throw an IllegalArgumentException"); } catch (IllegalStateException e) { assertEquals("no query or collectionCallback is specified", e.getMessage()); } } @Test @MongoDbAvailable public void testListOfResultsWithQueryExpressionAndLimit() { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setQueryExpression( PARSER.parseExpression("new BasicQuery('{''address.state'' : ''PA''}').limit(2)")); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); List<Person> persons = getPersonsFromResult(result); assertEquals(2, persons.size()); } @Test @MongoDbAvailable public void testListOfResultsWithQueryFunction() { Message<String> message = MessageBuilder.withPayload("Xavi").build(); MongoDbOutboundGateway gateway = createGateway(); Function<Message<String>, Query> queryFunction = msg -> new BasicQuery("{'name' : '" + msg.getPayload() + "'}"); FunctionExpression<Message<String>> functionExpression = new FunctionExpression<>(queryFunction); gateway.setQueryExpression(functionExpression); gateway.setExpectSingleResult(true); gateway.setEntityClass(Person.class); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); Person person = (Person) result; assertEquals("Xavi", person.getName()); } @Test @MongoDbAvailable public void testListOfResultsWithQueryExpressionNotInitialized() { MongoDbOutboundGateway gateway = new MongoDbOutboundGateway(mongoDbFactory); gateway.setBeanFactory(beanFactory); gateway.setMongoConverter(mongoConverter); try { gateway.afterPropertiesSet(); Assert.fail("Expected the test case to throw an IllegalStateException"); } catch (IllegalStateException e) { assertEquals("no query or collectionCallback is specified", e.getMessage()); } } @Test @MongoDbAvailable public void testListOfResultsWithQueryExpression() throws Exception { Message<String> message = MessageBuilder.withPayload("{}").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setEntityClass(Person.class); gateway.setQueryExpression(PARSER.parseExpression("payload")); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); List<Person> persons = getPersonsFromResult(result); assertEquals(4, persons.size()); } @Test @MongoDbAvailable public void testListOfResultsWithQueryExpressionReturningOneResult() throws Exception { Message<String> message = MessageBuilder.withPayload("{name : 'Xavi'}").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setEntityClass(Person.class); gateway.setQueryExpression(PARSER.parseExpression("payload")); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); List<Person> persons = getPersonsFromResult(result); assertEquals(1, persons.size()); assertEquals("Xavi", persons.get(0).getName()); } @Test @MongoDbAvailable public void testSingleResultWithQueryExpressionAsString() throws Exception { Message<String> message = MessageBuilder.withPayload("{name : 'Artem'}").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setQueryExpression(PARSER.parseExpression("payload")); gateway.setExpectSingleResult(true); gateway.setEntityClass(Person.class); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); Person person = (Person) result; assertEquals("Artem", person.getName()); } @Test @MongoDbAvailable public void testSingleResultWithQueryExpressionAsQuery() throws Exception { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setQueryExpression(PARSER.parseExpression("new BasicQuery('{''name'' : ''Gary''}')")); gateway.setExpectSingleResult(true); gateway.setEntityClass(Person.class); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); Person person = (Person) result; assertEquals("Gary", person.getName()); } @Test @MongoDbAvailable public void testSingleResultWithQueryExpressionAndNoEntityClass() { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setQueryExpression(new LiteralExpression("{name : 'Xavi'}")); gateway.setExpectSingleResult(true); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); Document person = (Document) result; assertEquals("Xavi", person.get("name")); } @Test @MongoDbAvailable public void testWithNullCollectionNameExpression() throws Exception { MongoDbOutboundGateway gateway = new MongoDbOutboundGateway(mongoDbFactory); gateway.setBeanFactory(beanFactory); gateway.setQueryExpression(new LiteralExpression("{name : 'Xavi'}")); gateway.setExpectSingleResult(true); try { gateway.afterPropertiesSet(); Assert.fail("Expected the test case to throw an IllegalArgumentException"); } catch (IllegalStateException e) { assertEquals("no collection name specified", e.getMessage()); } } @Test @MongoDbAvailable public void testWithCollectionNameExpressionSpecified() throws Exception { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setQueryExpression(new LiteralExpression("{name : 'Xavi'}")); gateway.setExpectSingleResult(true); gateway.setCollectionNameExpression(new LiteralExpression("anotherCollection")); gateway.afterPropertiesSet(); Object result = gateway.handleRequestMessage(message); assertNull(result); LiteralExpression collectionNameExpression = (LiteralExpression) TestUtils.getPropertyValue(gateway, "collectionNameExpression"); assertNotNull(collectionNameExpression); assertEquals("anotherCollection", collectionNameExpression.getValue()); } @Test @MongoDbAvailable public void testWithCollectionCallbackCount() throws Exception { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setEntityClass(Person.class); gateway.setCollectionNameExpression(new LiteralExpression("data")); gateway.setCollectionCallback(MongoCollection::count); gateway.afterPropertiesSet(); long result = (long) gateway.handleRequestMessage(message); assertEquals(4, result); } @Test @MongoDbAvailable public void testWithCollectionCallbackFindOne() throws Exception { Message<String> message = MessageBuilder.withPayload("").build(); MongoDbOutboundGateway gateway = createGateway(); gateway.setEntityClass(Person.class); gateway.setCollectionNameExpression(new LiteralExpression("data")); gateway.setRequiresReply(false); gateway.setCollectionCallback(collection -> { collection.insertOne(new Document("name", "Mike")); return null; }); gateway.afterPropertiesSet(); gateway.handleRequestMessage(message); List<Person> persons = this.mongoTemplate.find(new Query(), Person.class, COLLECTION_NAME); assertEquals(5, persons.size()); assertTrue(persons.stream().anyMatch(p -> p.getName().equals("Mike"))); } @SuppressWarnings("unchecked") private List<Person> getPersonsFromResult(Object result) { return (List<Person>) result; } private MongoDbOutboundGateway createGateway() { MongoDbOutboundGateway gateway = new MongoDbOutboundGateway(mongoDbFactory); gateway.setBeanFactory(beanFactory); gateway.setCollectionNameExpression(new LiteralExpression("data")); return gateway; } }