/* * 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.dsl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Arrays; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.BulkOperations; import org.springframework.data.mongodb.core.CollectionCallback; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.integration.config.EnableIntegration; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.channel.MessageChannels; import org.springframework.integration.handler.ReplyRequiredException; import org.springframework.integration.mongodb.rules.MongoDbAvailable; import org.springframework.integration.mongodb.rules.MongoDbAvailableTests; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.PollableChannel; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; /** * @author Xavier PadrĂ³ * @since 5.0 */ @RunWith(SpringRunner.class) @DirtiesContext public class MongoDbTests extends MongoDbAvailableTests { private static final String COLLECTION_NAME = "data"; @Autowired private PollableChannel getResultChannel; @Autowired @Qualifier("gatewaySingleQueryFlow.input") private MessageChannel gatewaySingleQueryFlow; @Autowired @Qualifier("gatewaySingleQueryWithTemplateFlow.input") private MessageChannel gatewaySingleQueryWithTemplateFlow; @Autowired @Qualifier("gatewaySingleQueryExpressionFlow.input") private MessageChannel gatewaySingleQueryExpressionFlow; @Autowired @Qualifier("gatewayQueryExpressionFlow.input") private MessageChannel gatewayQueryExpressionFlow; @Autowired @Qualifier("gatewayQueryExpressionLimitFlow.input") private MessageChannel gatewayQueryExpressionLimitFlow; @Autowired @Qualifier("gatewayQueryFunctionFlow.input") private MessageChannel gatewayQueryFunctionFlow; @Autowired @Qualifier("gatewayCollectionNameFunctionFlow.input") private MessageChannel gatewayCollectionNameFunctionFlow; @Autowired @Qualifier("gatewayCollectionCallbackFlow.input") private MessageChannel gatewayCollectionCallbackFlow; @Autowired private MongoOperations mongoTemplate; @Before public void setUp() throws Exception { createPersons(); } @After public void cleanUp() { mongoTemplate.dropCollection(COLLECTION_NAME); } @Test @MongoDbAvailable public void testGatewayWithSingleQuery() { gatewaySingleQueryFlow.send(MessageBuilder .withPayload("Xavi") .setHeader("collection", "data") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); Person retrievedPerson = (Person) result.getPayload(); assertEquals("Xavi", retrievedPerson.getName()); } @Test @MongoDbAvailable public void testGatewayWithSingleQueryWithTemplate() { gatewaySingleQueryWithTemplateFlow.send(MessageBuilder.withPayload("Xavi").build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); Person retrievedPerson = (Person) result.getPayload(); assertEquals("Xavi", retrievedPerson.getName()); } @Test @MongoDbAvailable public void testGatewayWithSingleQueryExpression() { gatewaySingleQueryExpressionFlow.send(MessageBuilder .withPayload("") .setHeader("query", "{'name' : 'Artem'}") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); Person retrievedPerson = (Person) result.getPayload(); assertEquals("Artem", retrievedPerson.getName()); } @Test(expected = ReplyRequiredException.class) @MongoDbAvailable public void testGatewayWithSingleQueryExpressionNoPersonFound() { gatewaySingleQueryExpressionFlow.send(MessageBuilder .withPayload("") .setHeader("query", "{'name' : 'NonExisting'}") .build()); this.getResultChannel.receive(10_000); } @Test @MongoDbAvailable public void testGatewayWithQueryExpression() { gatewayQueryExpressionFlow.send(MessageBuilder .withPayload("") .setHeader("query", "{}") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); List<Person> retrievedPersons = getPersons(result); assertEquals(4, retrievedPersons.size()); } @Test @MongoDbAvailable public void testGatewayWithQueryExpressionAndLimit() { gatewayQueryExpressionLimitFlow.send(MessageBuilder .withPayload("") .setHeader("query", "{}") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); List<Person> retrievedPersons = getPersons(result); assertEquals(2, retrievedPersons.size()); } @Test @MongoDbAvailable public void testGatewayWithQueryFunction() { gatewayQueryFunctionFlow.send(MessageBuilder .withPayload("Gary") .setHeader("collection", "data") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); Person person = (Person) result.getPayload(); assertEquals("Gary", person.getName()); } @Test @MongoDbAvailable public void testGatewayWithCollectionNameFunction() { gatewayCollectionNameFunctionFlow.send(MessageBuilder .withPayload("data") .setHeader("query", "{'name' : 'Gary'}") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); Person person = (Person) result.getPayload(); assertEquals("Gary", person.getName()); } @Test @MongoDbAvailable public void testGatewayWithCollectionCallback() { gatewayCollectionCallbackFlow.send(MessageBuilder .withPayload("") .build()); Message<?> result = this.getResultChannel.receive(10_000); assertNotNull(result); long count = (Long) result.getPayload(); assertEquals(4, count); } @SuppressWarnings("unchecked") private List<Person> getPersons(Message<?> message) { return (List<Person>) message.getPayload(); } private void createPersons() { 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(); } @Configuration @EnableIntegration public static class ContextConfiguration { @Bean public IntegrationFlow gatewaySingleQueryFlow() { return f -> f .handle(queryOutboundGateway("{name: 'Xavi'}", true)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewaySingleQueryWithTemplateFlow() { return f -> f .handle(queryOutboundGatewayWithTemplate("{name: 'Xavi'}", true)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewaySingleQueryExpressionFlow() { return f -> f .handle(queryExpressionOutboundGateway(true)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewayQueryExpressionFlow() { return f -> f .handle(queryExpressionOutboundGateway(false)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewayQueryExpressionLimitFlow() { return f -> f .handle(queryExpressionOutboundGateway(false, 2)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewayQueryFunctionFlow() { return f -> f .handle(queryFunctionOutboundGateway(true)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewayCollectionNameFunctionFlow() { return f -> f .handle(collectionNameFunctionOutboundGateway(true)) .channel(getResultChannel()); } @Bean public IntegrationFlow gatewayCollectionCallbackFlow() { return f -> f .handle(collectionCallbackOutboundGateway(MongoCollection::count)) .channel(getResultChannel()); } @Bean public MessageChannel getResultChannel() { return MessageChannels.queue().get(); } @Bean public MongoDbFactory mongoDbFactory() { return new SimpleMongoDbFactory(new MongoClient(), "test"); } @Bean public MongoConverter mongoConverter() { return new TestMongoConverter(mongoDbFactory(), new MongoMappingContext()); } @Bean public MongoOperations mongoTemplate() { return new MongoTemplate(mongoDbFactory()); } private MongoDbOutboundGatewaySpec queryOutboundGateway(String query, boolean expectSingleResult) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .query(query) .collectionNameExpression("headers.collection") .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec queryOutboundGatewayWithTemplate(String query, boolean expectSingleResult) { return MongoDb.outboundGateway(mongoTemplate()) .query(query) .collectionName(COLLECTION_NAME) .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec queryExpressionOutboundGateway(boolean expectSingleResult) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .queryExpression("headers.query") .collectionName(COLLECTION_NAME) .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec queryExpressionOutboundGateway(boolean expectSingleResult, int maxResults) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .queryExpression("new BasicQuery('{''address.state'' : ''PA''}').limit(" + maxResults + ")") .collectionName(COLLECTION_NAME) .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec queryFunctionOutboundGateway(boolean expectSingleResult) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .queryFunction(msg -> Query.query(Criteria.where("name") .is(msg.getPayload()))) .collectionNameExpression("headers.collection") .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec collectionNameFunctionOutboundGateway(boolean expectSingleResult) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .queryExpression("headers.query") .<String>collectionNameFunction(Message::getPayload) .expectSingleResult(expectSingleResult) .entityClass(Person.class); } private MongoDbOutboundGatewaySpec collectionCallbackOutboundGateway(CollectionCallback<?> collectionCallback) { return MongoDb.outboundGateway(mongoDbFactory(), mongoConverter()) .collectionCallback(collectionCallback) .collectionName(COLLECTION_NAME) .entityClass(Person.class); } } }