/* * Copyright 2007-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.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.bson.Document; import org.bson.conversions.Bson; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.BeanFactory; 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.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.mongodb.rules.MongoDbAvailable; import org.springframework.integration.mongodb.rules.MongoDbAvailableTests; import com.mongodb.util.JSON; /** * @author Amol Nayak * @author Oleg Zhurakousky * @author Gary Russell * @author Yaron Yamin * * @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 validateSuccessfulQueryWithSingleElementIfOneInListAsDbObject() 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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); @SuppressWarnings("unchecked") List<Document> results = ((List<Document>) messageSource.receive().getPayload()); assertEquals(1, results.size()); Document resultObject = results.get(0); assertEquals("Oleg", resultObject.get("name")); } @Test @MongoDbAvailable public void validateSuccessfulQueryWithSingleElementIfOneInList() 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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); @SuppressWarnings("unchecked") List<Person> results = ((List<Person>) 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 validateSuccessfulQueryWithSingleElementIfOneInListAndSingleResult() 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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); Person person = (Person) messageSource.receive().getPayload(); assertEquals("Oleg", person.getName()); assertEquals("PA", person.getAddress().getState()); } @Test @MongoDbAvailable public void validateSuccessfulSubObjectQueryWithSingleElementIfOneInList() 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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); @SuppressWarnings("unchecked") List<Person> results = ((List<Person>) messageSource.receive().getPayload()); Person person = results.get(0); assertEquals("Oleg", person.getName()); assertEquals("PA", person.getAddress().getState()); } @Test @MongoDbAvailable public void validateSuccessfulQueryWithMultipleElements() throws Exception { List<Person> persons = queryMultipleElements(new LiteralExpression("{'address.state' : 'PA'}")); assertEquals(3, persons.size()); } @Test @MongoDbAvailable public void validateSuccessfulStringQueryExpressionWithMultipleElements() throws Exception { List<Person> persons = queryMultipleElements(new SpelExpressionParser() .parseExpression("\"{'address.state' : 'PA'}\"")); assertEquals(3, persons.size()); } @Test @MongoDbAvailable public void validateSuccessfulBasicQueryExpressionWithMultipleElements() throws Exception { List<Person> persons = queryMultipleElements(new SpelExpressionParser() .parseExpression("new BasicQuery(\"{'address.state' : 'PA'}\").limit(2)")); assertEquals(2, persons.size()); } @SuppressWarnings("unchecked") private List<Person> queryMultipleElements(Expression queryExpression) 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"); MongoDbMessageSource messageSource = new MongoDbMessageSource(mongoDbFactory, queryExpression); messageSource.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); return (List<Person>) messageSource.receive().getPayload(); } @Test @MongoDbAvailable public void validateSuccessfulQueryWithNullReturn() 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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); assertNull(messageSource.receive()); } @SuppressWarnings("unchecked") @Test @MongoDbAvailable public void validateSuccessfulQueryWithCustomConverter() 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()); messageSource.setBeanFactory(mock(BeanFactory.class)); converter.afterPropertiesSet(); converter = spy(converter); messageSource.setMongoConverter(converter); messageSource.afterPropertiesSet(); List<Person> persons = (List<Person>) messageSource.receive().getPayload(); assertEquals(3, persons.size()); verify(converter, times(3)).read((Class<Person>) Mockito.any(), Mockito.any(Bson.class)); } @SuppressWarnings("unchecked") @Test @MongoDbAvailable public void validateSuccessfulQueryWithMongoTemplate() 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.setBeanFactory(mock(BeanFactory.class)); 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<Person> persons = (List<Person>) messageSource.receive().getPayload(); assertEquals(3, persons.size()); verify(converter, times(3)).read((Class<Person>) Mockito.any(), Mockito.any(Bson.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.setBeanFactory(mock(BeanFactory.class)); messageSource.afterPropertiesSet(); Document result = (Document) messageSource.receive().getPayload(); Object id = result.get("_id"); result.put("company", "PepBoys"); template.save(result, "data"); result = (Document) messageSource.receive().getPayload(); assertEquals(id, result.get("_id")); } }