diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java index 4c9525d41..1b4190544 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java @@ -27,6 +27,7 @@ import java.lang.annotation.Target; * @author Jon Brisbin * @author Oliver Gierke * @author Philipp Schneider + * @author Johno Crawford */ @Target({ ElementType.TYPE }) @Documented @@ -78,4 +79,12 @@ public @interface CompoundIndex { * @return */ boolean background() default false; + + /** + * Configures the number of seconds after which the collection should expire. Defaults to -1 for no expiry. + * + * @see http://docs.mongodb.org/manual/tutorial/expire-data/ + * @return + */ + int expireAfterSeconds() default -1; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java index 1d23f16b9..f918fa026 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java @@ -26,6 +26,7 @@ import java.lang.annotation.Target; * @author Jon Brisbin * @author Oliver Gierke * @author Philipp Schneider + * @author Johno Crawford */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @@ -50,4 +51,12 @@ public @interface Indexed { * @return */ boolean background() default false; + + /** + * Configures the number of seconds after which the collection should expire. Defaults to -1 for no expiry. + * + * @see http://docs.mongodb.org/manual/tutorial/expire-data/ + * @return + */ + int expireAfterSeconds() default -1; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index 862c3a523..97e909369 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -44,6 +44,7 @@ import com.mongodb.util.JSON; * @author Jon Brisbin * @author Oliver Gierke * @author Philipp Schneider + * @author Johno Crawford */ public class MongoPersistentEntityIndexCreator implements ApplicationListener, MongoPersistentProperty>> { @@ -108,7 +109,7 @@ public class MongoPersistentEntityIndexCreator implements DBObject definition = (DBObject) JSON.parse(index.def()); ensureIndex(indexColl, index.name(), definition, index.unique(), index.dropDups(), index.sparse(), - index.background()); + index.background(), index.expireAfterSeconds()); if (log.isDebugEnabled()) { log.debug("Created compound index " + index); @@ -143,7 +144,7 @@ public class MongoPersistentEntityIndexCreator implements DBObject definition = new BasicDBObject(persistentProperty.getFieldName(), direction); ensureIndex(collection, name, definition, index.unique(), index.dropDups(), index.sparse(), - index.background()); + index.background(), index.expireAfterSeconds()); if (log.isDebugEnabled()) { log.debug("Created property index " + index); @@ -192,9 +193,11 @@ public class MongoPersistentEntityIndexCreator implements * @param unique whether it shall be a unique index * @param dropDups whether to drop duplicates * @param sparse sparse or not + * @param background whether the index will be created in the background + * @param expireAfterSeconds the time to live for documents in the collection */ protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique, - boolean dropDups, boolean sparse, boolean background) { + boolean dropDups, boolean sparse, boolean background, int expireAfterSeconds) { DBObject opts = new BasicDBObject(); opts.put("name", name); @@ -203,6 +206,10 @@ public class MongoPersistentEntityIndexCreator implements opts.put("unique", unique); opts.put("background", background); + if (expireAfterSeconds != -1) { + opts.put("expireAfterSeconds", expireAfterSeconds); + } + mongoDbFactory.getDb().getCollection(collection).ensureIndex(indexDefinition, opts); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java index 06ed0380e..885f77d57 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreatorUnitTests.java @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.util.Collections; +import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,14 +40,13 @@ import com.mongodb.DBObject; * * @author Oliver Gierke * @author Philipp Schneider + * @author Johno Crawford */ @RunWith(MockitoJUnitRunner.class) public class MongoPersistentEntityIndexCreatorUnitTests { - @Mock - MongoDbFactory factory; - @Mock - ApplicationContext context; + @Mock MongoDbFactory factory; + @Mock ApplicationContext context; @Test public void buildsIndexDefinitionUsingFieldName() { @@ -58,6 +58,7 @@ public class MongoPersistentEntityIndexCreatorUnitTests { assertThat(creator.indexDefinition.keySet(), hasItem("fieldname")); assertThat(creator.name, is("indexName")); assertThat(creator.background, is(false)); + assertThat(creator.expireAfterSeconds, is(-1)); } @Test @@ -106,6 +107,20 @@ public class MongoPersistentEntityIndexCreatorUnitTests { assertThat(creator.background, is(true)); } + /** + * @see DATAMONGO-544 + */ + @Test + public void expireAfterSecondsIfConfigured() { + + MongoMappingContext mappingContext = prepareMappingContext(Milk.class); + DummyMongoPersistentEntityIndexCreator creator = new DummyMongoPersistentEntityIndexCreator(mappingContext, factory); + + assertThat(creator.indexDefinition, is(notNullValue())); + assertThat(creator.indexDefinition.keySet(), hasItem("expiry")); + assertThat(creator.expireAfterSeconds, is(60)); + } + private static MongoMappingContext prepareMappingContext(Class type) { MongoMappingContext mappingContext = new MongoMappingContext(); @@ -117,16 +132,18 @@ public class MongoPersistentEntityIndexCreatorUnitTests { static class Person { - @Indexed(name = "indexName") - @Field("fieldname") - String field; + @Indexed(name = "indexName") @Field("fieldname") String field; } static class AnotherPerson { - @Indexed(background = true) - String lastname; + @Indexed(background = true) String lastname; + } + + static class Milk { + + @Indexed(expireAfterSeconds = 60) Date expiry; } static class DummyMongoPersistentEntityIndexCreator extends MongoPersistentEntityIndexCreator { @@ -134,6 +151,7 @@ public class MongoPersistentEntityIndexCreatorUnitTests { DBObject indexDefinition; String name; boolean background; + int expireAfterSeconds; public DummyMongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) { super(mappingContext, mongoDbFactory); @@ -141,11 +159,12 @@ public class MongoPersistentEntityIndexCreatorUnitTests { @Override protected void ensureIndex(String collection, String name, DBObject indexDefinition, boolean unique, - boolean dropDups, boolean sparse, boolean background) { + boolean dropDups, boolean sparse, boolean background, int expireAfterSeconds) { this.name = name; this.indexDefinition = indexDefinition; this.background = background; + this.expireAfterSeconds = expireAfterSeconds; } } }