From ecadc6548350c605aa181dbdce1a6675f64aa744 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 1 Sep 2014 17:00:27 +0200 Subject: [PATCH] #8 - Some polishing of the example. Introduced the usage of Lombok to be able to get rid off the getters and setters. Simplified the configuration to use Spring Boot's auto-configuration. The initializer is now an enum manually triggered with a MongoOperations instance. Switched from MongoTemplate to MongoOperations where possible. Polished some JavaDoc. Original pull request: #10. --- mongodb/text-search/pom.xml | 2 +- .../mongodb/textsearch/BlogPost.java | 52 ++--------------- .../textsearch/MongoTestConfiguration.java | 40 +++++-------- .../textsearch/TextSearchRepositoryTests.java | 10 +++- .../textsearch/TextSearchTemplateTests.java | 30 +++++----- .../mongodb/util/BlogPostInitializer.java | 57 ++++++++++++------- .../mongodb/util/ConsoleResultPrinter.java | 2 +- .../src/test/resources/logback.xml | 4 +- 8 files changed, 83 insertions(+), 114 deletions(-) diff --git a/mongodb/text-search/pom.xml b/mongodb/text-search/pom.xml index 23be76f5..702ddd70 100644 --- a/mongodb/text-search/pom.xml +++ b/mongodb/text-search/pom.xml @@ -23,4 +23,4 @@ 1.0.0 - \ No newline at end of file + diff --git a/mongodb/text-search/src/main/java/example/springdata/mongodb/textsearch/BlogPost.java b/mongodb/text-search/src/main/java/example/springdata/mongodb/textsearch/BlogPost.java index b278c77f..f50b7945 100644 --- a/mongodb/text-search/src/main/java/example/springdata/mongodb/textsearch/BlogPost.java +++ b/mongodb/text-search/src/main/java/example/springdata/mongodb/textsearch/BlogPost.java @@ -17,15 +17,21 @@ package example.springdata.mongodb.textsearch; import java.util.List; +import lombok.Data; + import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.index.TextIndexed; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.TextScore; /** + * Document representation of a {@link BlogPost} carrying annotation based information for text indexes. + * * @author Christoph Strobl + * @author Oliver Gierke */ @Document +@Data public class BlogPost { private @Id String id; @@ -33,50 +39,4 @@ public class BlogPost { private @TextIndexed(weight = 2) String content; private @TextIndexed List categories; private @TextScore Float score; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public List getCategories() { - return categories; - } - - public void setCategories(List categories) { - this.categories = categories; - } - - public Float getScore() { - return score; - } - - public void setScore(Float score) { - this.score = score; - } - - @Override - public String toString() { - return "BlogPost [score=" + score + ", id=" + id + ", title=" + title + ", categories=" + getCategories() + "]"; - } - } diff --git a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/MongoTestConfiguration.java b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/MongoTestConfiguration.java index f92a8fd2..5218cf6f 100644 --- a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/MongoTestConfiguration.java +++ b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/MongoTestConfiguration.java @@ -15,46 +15,35 @@ */ package example.springdata.mongodb.textsearch; +import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import org.springframework.context.annotation.Bean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.config.AbstractMongoConfiguration; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; - -import com.mongodb.Mongo; -import com.mongodb.MongoClient; +import org.springframework.data.mongodb.core.MongoOperations; import example.springdata.mongodb.util.BlogPostInitializer; /** * @author Christoph Strobl + * @author Oliver Gierke */ @Configuration -@EnableMongoRepositories -public class MongoTestConfiguration extends AbstractMongoConfiguration { +@EnableAutoConfiguration +public class MongoTestConfiguration { - static final String DATABASE_NAME = "s2gx2014-blog"; - static final String BLOG_POST_ATOM_FEED_SOURCE = "https://spring.io/blog.atom"; - - @Override - protected String getDatabaseName() { - return DATABASE_NAME; - } - - @Override - public Mongo mongo() throws Exception { - return new MongoClient(); - } + @Autowired MongoOperations operations; /** * Initializes the repository with a predefined set of entities. * * @return + * @throws Exception */ - @Bean - public BlogPostInitializer initializer() { - return new BlogPostInitializer(BLOG_POST_ATOM_FEED_SOURCE); + @PostConstruct + void initialize() throws Exception { + BlogPostInitializer.INSTANCE.initialize(operations); } /** @@ -63,8 +52,7 @@ public class MongoTestConfiguration extends AbstractMongoConfiguration { * @throws Exception */ @PreDestroy - public void dropTestDB() throws Exception { - mongo().dropDatabase(getDatabaseName()); + void dropTestDB() throws Exception { + operations.dropCollection(BlogPost.class); } - } diff --git a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchRepositoryTests.java b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchRepositoryTests.java index f56d456e..6c52aaea 100644 --- a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchRepositoryTests.java +++ b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchRepositoryTests.java @@ -22,12 +22,16 @@ import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.mapping.TextScore; import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** + * Integration tests showing the text search functionality using repositories. + * * @author Christoph Strobl + * @author Oliver Gierke */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { MongoTestConfiguration.class }) @@ -44,6 +48,7 @@ public class TextSearchRepositoryTests { TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release"); List blogPosts = repo.findAllBy(criteria); + printResult(blogPosts, criteria); } @@ -55,6 +60,7 @@ public class TextSearchRepositoryTests { TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release").notMatching("engineering"); List blogPosts = repo.findAllBy(criteria); + printResult(blogPosts, criteria); } @@ -66,17 +72,19 @@ public class TextSearchRepositoryTests { TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingPhrase("release candidate"); List blogPosts = repo.findAllBy(criteria); + printResult(blogPosts, criteria); } /** - * Sort by relevance relying on the value marked with {@link org.springframework.data.mongodb.core.mapping.TextScore}. + * Sort by relevance relying on the value marked with {@link TextScore}. */ @Test public void findAllBlogPostsByPhraseSortByScore() { TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingPhrase("release candidate"); List blogPosts = repo.findAllByOrderByScoreDesc(criteria); + printResult(blogPosts, criteria); } } diff --git a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchTemplateTests.java b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchTemplateTests.java index 5f2706e8..0eda7067 100644 --- a/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchTemplateTests.java +++ b/mongodb/text-search/src/test/java/example/springdata/mongodb/textsearch/TextSearchTemplateTests.java @@ -22,14 +22,14 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import org.springframework.boot.autoconfigure.mongo.MongoProperties; +import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.index.TextIndexDefinition; import org.springframework.data.mongodb.core.index.TextIndexDefinition.TextIndexDefinitionBuilder; import org.springframework.data.mongodb.core.query.TextCriteria; import org.springframework.data.mongodb.core.query.TextQuery; -import com.mongodb.MongoClient; - import example.springdata.mongodb.util.BlogPostInitializer; /** @@ -37,16 +37,19 @@ import example.springdata.mongodb.util.BlogPostInitializer; */ public class TextSearchTemplateTests { - MongoTemplate template; + MongoOperations operations; @Before public void setUp() throws Exception { - template = new MongoTemplate(new MongoClient(), MongoTestConfiguration.DATABASE_NAME); - template.dropCollection(BlogPost.class); + MongoProperties properties = new MongoProperties(); + + operations = new MongoTemplate(properties.createMongoClient(null), properties.getMongoClientDatabase()); + operations.dropCollection(BlogPost.class); createIndex(); - loadTestData(); + + BlogPostInitializer.INSTANCE.initialize(this.operations); } /** @@ -57,7 +60,8 @@ public class TextSearchTemplateTests { public void findAllBlogPostsWithRelease() { TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny("release"); - List blogPosts = template.find(query(criteria), BlogPost.class); + List blogPosts = operations.find(query(criteria), BlogPost.class); + printResult(blogPosts, criteria); } @@ -73,7 +77,8 @@ public class TextSearchTemplateTests { query.setScoreFieldName("score"); query.sortByScore(); - List blogPosts = template.find(query, BlogPost.class); + List blogPosts = operations.find(query, BlogPost.class); + printResult(blogPosts, criteria); } @@ -106,13 +111,6 @@ public class TextSearchTemplateTests { .onField("categories") // .build(); - template.indexOps(BlogPost.class).ensureIndex(textIndex); + operations.indexOps(BlogPost.class).ensureIndex(textIndex); } - - private void loadTestData() throws Exception { - - BlogPostInitializer initializer = new BlogPostInitializer(MongoTestConfiguration.BLOG_POST_ATOM_FEED_SOURCE); - initializer.initialize(this.template); - } - } diff --git a/mongodb/text-search/src/test/java/example/springdata/mongodb/util/BlogPostInitializer.java b/mongodb/text-search/src/test/java/example/springdata/mongodb/util/BlogPostInitializer.java index 91e6fe07..a3a58699 100644 --- a/mongodb/text-search/src/test/java/example/springdata/mongodb/util/BlogPostInitializer.java +++ b/mongodb/text-search/src/test/java/example/springdata/mongodb/util/BlogPostInitializer.java @@ -18,11 +18,12 @@ package example.springdata.mongodb.util; import java.util.ArrayList; import java.util.List; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.extern.slf4j.Slf4j; + import org.springframework.core.convert.converter.Converter; -import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.http.ResponseEntity; +import org.springframework.util.Assert; import org.springframework.web.client.RestTemplate; import com.sun.syndication.feed.atom.Category; @@ -33,47 +34,58 @@ import com.sun.syndication.feed.atom.Feed; import example.springdata.mongodb.textsearch.BlogPost; /** + * Component to initialize {@link BlogPost}s by accessing the latest ones from the Spring blog. + * * @author Christoph Strobl + * @author Oliver Gierke */ -public class BlogPostInitializer implements InitializingBean { +@Slf4j +public enum BlogPostInitializer { - private final String url; - private final RestTemplate restTemplate; - private final Converter converter; + INSTANCE; - @Autowired MongoTemplate mongoTemplate; + private final RestTemplate restTemplate = new RestTemplate(); + private final Converter converter = EntryConverter.INSTANCE; + private final String url = "https://spring.io/blog.atom"; - public BlogPostInitializer(String url) { + /** + * Initializes the given {@link MongoOperations} with {@link BlogPost}s from the Spring Blog. + * + * @param operations must not be {@literal null}. + */ + public void initialize(MongoOperations operations) { - restTemplate = new RestTemplate(); - this.converter = new EntryConverter(); - this.url = url; - } - - public void initialize(MongoTemplate mongoTemplate) { + Assert.notNull(operations, "MongoOperations must not be null!"); ResponseEntity feed = restTemplate.getForEntity(url, Feed.class); + int count = 0; + if (feed.hasBody()) { for (Object entry : feed.getBody().getEntries()) { if (entry instanceof Entry) { - mongoTemplate.save(converter.convert((Entry) entry)); + operations.save(converter.convert((Entry) entry)); + count++; } } } - } - @Override - public void afterPropertiesSet() throws Exception { - initialize(this.mongoTemplate); + log.info("Imported {} blog posts from spring.io!", count); } /** * {@link Converter} implementation capable of converting atom feed {@link Entry} into {@link BlogPost}. * * @author Christoph Strobl + * @author Oliver Gierke */ - static class EntryConverter implements Converter { + private enum EntryConverter implements Converter { + INSTANCE; + + /* + * (non-Javadoc) + * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) + */ @Override public BlogPost convert(Entry source) { @@ -89,15 +101,16 @@ public class BlogPostInitializer implements InitializingBean { } List categories = new ArrayList(); + for (Object category : source.getCategories()) { if (category instanceof Category) { categories.add(((Category) category).getLabel()); } } + post.setCategories(categories); return post; } } - } diff --git a/mongodb/text-search/src/test/java/example/springdata/mongodb/util/ConsoleResultPrinter.java b/mongodb/text-search/src/test/java/example/springdata/mongodb/util/ConsoleResultPrinter.java index c76577a8..5c4ae508 100644 --- a/mongodb/text-search/src/test/java/example/springdata/mongodb/util/ConsoleResultPrinter.java +++ b/mongodb/text-search/src/test/java/example/springdata/mongodb/util/ConsoleResultPrinter.java @@ -36,7 +36,7 @@ public class ConsoleResultPrinter { for (BlogPost blogPost : blogPosts) { System.out.println(blogPost); } + System.out.println("XXXXXXXXXXXX -- XXXXXXXXXXXX -- XXXXXXXXXXXX\r\n"); } - } diff --git a/mongodb/text-search/src/test/resources/logback.xml b/mongodb/text-search/src/test/resources/logback.xml index 61c86dd9..f4b3ab75 100644 --- a/mongodb/text-search/src/test/resources/logback.xml +++ b/mongodb/text-search/src/test/resources/logback.xml @@ -10,5 +10,7 @@ + + - \ No newline at end of file +