From 57baff78ab660cc65a09602aefaec15aac212029 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Tue, 23 Jul 2019 17:46:48 +0200 Subject: [PATCH 01/10] added index type ttl, added ttl index options --- .../java/com/arangodb/entity/IndexType.java | 3 +- .../com/arangodb/model/TtlIndexOptions.java | 87 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/arangodb/model/TtlIndexOptions.java diff --git a/src/main/java/com/arangodb/entity/IndexType.java b/src/main/java/com/arangodb/entity/IndexType.java index b08f0a3d5..1507ec3d8 100644 --- a/src/main/java/com/arangodb/entity/IndexType.java +++ b/src/main/java/com/arangodb/entity/IndexType.java @@ -22,8 +22,9 @@ /** * @author Mark Vollmary + * @author Heiko Kernbach * */ public enum IndexType { - primary, hash, skiplist, persistent, geo, geo1, geo2, fulltext, edge + primary, hash, skiplist, persistent, geo, geo1, geo2, fulltext, edge, ttl } diff --git a/src/main/java/com/arangodb/model/TtlIndexOptions.java b/src/main/java/com/arangodb/model/TtlIndexOptions.java new file mode 100644 index 000000000..066fcc681 --- /dev/null +++ b/src/main/java/com/arangodb/model/TtlIndexOptions.java @@ -0,0 +1,87 @@ +/* + * DISCLAIMER + * + * Copyright 2019 ArangoDB GmbH, Cologne, Germany + * + * 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. + * + * Copyright holder is ArangoDB GmbH, Cologne, Germany + */ + +package com.arangodb.model; + +import com.arangodb.entity.IndexType; + +/** + * @author Heiko Kernbach + * + * @see API Documentation + */ +public class TtlIndexOptions { + + private Iterable fields; + private final IndexType type = IndexType.ttl; + private Long expireAfter; + private String name; + + public TtlIndexOptions() { + super(); + } + + protected Iterable getFields() { + return fields; + } + + /** + * @param fields + * A list of attribute paths + * @return options + */ + protected TtlIndexOptions fields(final Iterable fields) { + this.fields = fields; + return this; + } + + protected IndexType getType() { + return type; + } + + /** + * @param expireAfter + * The time (in seconds) after a document’s creation after which the documents count as “expired”. + * @return options + */ + public TtlIndexOptions expireAfter(final Long expireAfter) { + this.expireAfter = expireAfter; + return this; + } + + protected Long getExpireAfter() { + return expireAfter; + } + + /** + * @param name + * the name of the index + * @return options + */ + public TtlIndexOptions name(final String name) { + this.name = name; + return this; + } + + protected String getName() { + return name; + } + +} From b5a362dd1200c3c681b58b27f023ac3db58f4979 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 11:34:44 +0200 Subject: [PATCH 02/10] more work on ttl index --- .../java/com/arangodb/ArangoCollection.java | 30 ++++++++++--------- .../internal/ArangoCollectionImpl.java | 21 +++++-------- .../internal/InternalArangoCollection.java | 26 ++++++---------- .../com/arangodb/model/OptionsBuilder.java | 4 +++ .../com/arangodb/ArangoCollectionTest.java | 15 ++++++++++ 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/arangodb/ArangoCollection.java b/src/main/java/com/arangodb/ArangoCollection.java index 0f0dd8c10..e032af15b 100644 --- a/src/main/java/com/arangodb/ArangoCollection.java +++ b/src/main/java/com/arangodb/ArangoCollection.java @@ -32,20 +32,7 @@ import com.arangodb.entity.IndexEntity; import com.arangodb.entity.MultiDocumentEntity; import com.arangodb.entity.Permissions; -import com.arangodb.model.CollectionCreateOptions; -import com.arangodb.model.CollectionPropertiesOptions; -import com.arangodb.model.DocumentCreateOptions; -import com.arangodb.model.DocumentDeleteOptions; -import com.arangodb.model.DocumentExistsOptions; -import com.arangodb.model.DocumentImportOptions; -import com.arangodb.model.DocumentReadOptions; -import com.arangodb.model.DocumentReplaceOptions; -import com.arangodb.model.DocumentUpdateOptions; -import com.arangodb.model.FulltextIndexOptions; -import com.arangodb.model.GeoIndexOptions; -import com.arangodb.model.HashIndexOptions; -import com.arangodb.model.PersistentIndexOptions; -import com.arangodb.model.SkiplistIndexOptions; +import com.arangodb.model.*; /** * Interface for operations on ArangoDB collection level. @@ -53,6 +40,7 @@ * @see Collection API Documentation * @see Documents API Documentation * @author Mark Vollmary + * @author Heiko Kernbach */ public interface ArangoCollection extends ArangoSerializationAccessor { @@ -544,6 +532,20 @@ MultiDocumentEntity> deleteDocuments( */ IndexEntity ensureFulltextIndex(Iterable fields, FulltextIndexOptions options) throws ArangoDBException; + /** + * Creates a ttl index for the collection, if it does not already exist. + * + * @see API + * Documentation + * @param fields + * A list of attribute paths + * @param options + * Additional options, can be null + * @return information about the index + * @throws ArangoDBException + */ + IndexEntity ensureTtlIndex(Iterable fields, TtlIndexOptions options) throws ArangoDBException; + /** * Fetches a list of all indexes on this collection. * diff --git a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index fb3f78154..0880824fa 100644 --- a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -22,6 +22,7 @@ import java.util.Collection; +import com.arangodb.model.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,20 +39,6 @@ import com.arangodb.entity.MultiDocumentEntity; import com.arangodb.entity.Permissions; import com.arangodb.internal.util.DocumentUtil; -import com.arangodb.model.CollectionCreateOptions; -import com.arangodb.model.CollectionPropertiesOptions; -import com.arangodb.model.DocumentCreateOptions; -import com.arangodb.model.DocumentDeleteOptions; -import com.arangodb.model.DocumentExistsOptions; -import com.arangodb.model.DocumentImportOptions; -import com.arangodb.model.DocumentReadOptions; -import com.arangodb.model.DocumentReplaceOptions; -import com.arangodb.model.DocumentUpdateOptions; -import com.arangodb.model.FulltextIndexOptions; -import com.arangodb.model.GeoIndexOptions; -import com.arangodb.model.HashIndexOptions; -import com.arangodb.model.PersistentIndexOptions; -import com.arangodb.model.SkiplistIndexOptions; import com.arangodb.velocypack.VPackSlice; /** @@ -301,6 +288,12 @@ public IndexEntity ensureFulltextIndex(final Iterable fields, final Full return executor.execute(createFulltextIndexRequest(fields, options), IndexEntity.class); } + @Override + public IndexEntity ensureTtlIndex(final Iterable fields, final TtlIndexOptions options) + throws ArangoDBException { + return executor.execute(createTtlIndexRequest(fields, options), IndexEntity.class); + } + @Override public Collection getIndexes() throws ArangoDBException { return executor.execute(getIndexesRequest(), getIndexesResponseDeserializer()); diff --git a/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/src/main/java/com/arangodb/internal/InternalArangoCollection.java index 1aee8ace9..310cc023a 100644 --- a/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -39,23 +39,7 @@ import com.arangodb.internal.util.ArangoSerializationFactory.Serializer; import com.arangodb.internal.util.DocumentUtil; import com.arangodb.internal.util.RequestUtils; -import com.arangodb.model.CollectionPropertiesOptions; -import com.arangodb.model.CollectionRenameOptions; -import com.arangodb.model.DocumentCreateOptions; -import com.arangodb.model.DocumentDeleteOptions; -import com.arangodb.model.DocumentExistsOptions; -import com.arangodb.model.DocumentImportOptions; -import com.arangodb.model.DocumentReadOptions; -import com.arangodb.model.DocumentReplaceOptions; -import com.arangodb.model.DocumentUpdateOptions; -import com.arangodb.model.FulltextIndexOptions; -import com.arangodb.model.GeoIndexOptions; -import com.arangodb.model.HashIndexOptions; -import com.arangodb.model.ImportType; -import com.arangodb.model.OptionsBuilder; -import com.arangodb.model.PersistentIndexOptions; -import com.arangodb.model.SkiplistIndexOptions; -import com.arangodb.model.UserAccessOptions; +import com.arangodb.model.*; import com.arangodb.util.ArangoSerializer; import com.arangodb.velocypack.Type; import com.arangodb.velocypack.VPackSlice; @@ -654,6 +638,14 @@ protected Request createFulltextIndexRequest(final Iterable fields, fina return request; } + protected Request createTtlIndexRequest(final Iterable fields, final TtlIndexOptions options) { + final Request request = request(db.name(), RequestType.POST, PATH_API_INDEX); + request.putQueryParam(COLLECTION, name); + request.setBody( + util().serialize(OptionsBuilder.build(options != null ? options : new TtlIndexOptions(), fields))); + return request; + } + protected Request getIndexesRequest() { final Request request = request(db.name(), RequestType.GET, PATH_API_INDEX); request.putQueryParam(COLLECTION, name); diff --git a/src/main/java/com/arangodb/model/OptionsBuilder.java b/src/main/java/com/arangodb/model/OptionsBuilder.java index 5c348cfb7..7c5e92e58 100644 --- a/src/main/java/com/arangodb/model/OptionsBuilder.java +++ b/src/main/java/com/arangodb/model/OptionsBuilder.java @@ -62,6 +62,10 @@ public static FulltextIndexOptions build(final FulltextIndexOptions options, fin return options.fields(fields); } + public static TtlIndexOptions build(final TtlIndexOptions options, final Iterable fields) { + return options.fields(fields); + } + public static CollectionCreateOptions build(final CollectionCreateOptions options, final String name) { return options.name(name); } diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index 7fd358fbc..06678d6d1 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1287,6 +1287,21 @@ public void createFulltextIndexWithOptions() { assertThat(indexResult.getName(), is("myFulltextIndex")); } + @Test + public void createTtlIndex() { + final Collection fields = new ArrayList(); + fields.add("a"); + final IndexEntity indexResult = db.collection(COLLECTION_NAME).ensureFulltextIndex(fields, null); + assertThat(indexResult, is(notNullValue())); + assertThat(indexResult.getConstraint(), is(nullValue())); + assertThat(indexResult.getFields(), hasItem("a")); + assertThat(indexResult.getId(), startsWith(COLLECTION_NAME)); + assertThat(indexResult.getIsNewlyCreated(), is(true)); + assertThat(indexResult.getSparse(), is(true)); + assertThat(indexResult.getType(), is(IndexType.fulltext)); + assertThat(indexResult.getUnique(), is(false)); + } + @Test public void getIndexes() { final Collection fields = new ArrayList(); From 7858f2f88a7c12c416819bb044cc290f535db3bb Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 16:08:13 +0200 Subject: [PATCH 03/10] modified index ttl options --- src/main/java/com/arangodb/entity/IndexEntity.java | 5 +++++ src/main/java/com/arangodb/model/TtlIndexOptions.java | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/arangodb/entity/IndexEntity.java b/src/main/java/com/arangodb/entity/IndexEntity.java index fdea737f4..04bfee2fa 100644 --- a/src/main/java/com/arangodb/entity/IndexEntity.java +++ b/src/main/java/com/arangodb/entity/IndexEntity.java @@ -40,6 +40,7 @@ public class IndexEntity implements Entity { private Boolean geoJson; private Boolean constraint; private Boolean deduplicate; + private Integer expireAfter; public IndexEntity() { super(); @@ -85,6 +86,10 @@ public Boolean getGeoJson() { return geoJson; } + public Integer getExpireAfter() { + return expireAfter; + } + public Boolean getConstraint() { return constraint; } diff --git a/src/main/java/com/arangodb/model/TtlIndexOptions.java b/src/main/java/com/arangodb/model/TtlIndexOptions.java index 066fcc681..9342b1f58 100644 --- a/src/main/java/com/arangodb/model/TtlIndexOptions.java +++ b/src/main/java/com/arangodb/model/TtlIndexOptions.java @@ -31,7 +31,7 @@ public class TtlIndexOptions { private Iterable fields; private final IndexType type = IndexType.ttl; - private Long expireAfter; + private Integer expireAfter; private String name; public TtlIndexOptions() { @@ -61,12 +61,12 @@ protected IndexType getType() { * The time (in seconds) after a document’s creation after which the documents count as “expired”. * @return options */ - public TtlIndexOptions expireAfter(final Long expireAfter) { + public TtlIndexOptions expireAfter(final Integer expireAfter) { this.expireAfter = expireAfter; return this; } - protected Long getExpireAfter() { + protected Integer getExpireAfter() { return expireAfter; } From 8a9b9c4260105c63cac56d8425f80bcffbb2c391 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 16:08:24 +0200 Subject: [PATCH 04/10] added ttl index test --- .../com/arangodb/ArangoCollectionTest.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index dad5664f2..3de1427ec 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1289,18 +1289,34 @@ public void createFulltextIndexWithOptions() { } @Test - public void createTtlIndex() { + public void createTtlIndexWithoutOptions() { final Collection fields = new ArrayList(); fields.add("a"); - final IndexEntity indexResult = db.collection(COLLECTION_NAME).ensureFulltextIndex(fields, null); + try { + final IndexEntity indexResult = db.collection(COLLECTION_NAME).ensureTtlIndex(fields, null); + } catch (final ArangoDBException e) { + assertThat(e.getResponseCode(), is(400)); + assertThat(e.getErrorNum(), is(10)); + assertThat(e.getMessage(), containsString("expireAfter attribute must be a number")); + } + } + + @Test + public void createTtlIndexWithOptions() { + final Collection fields = new ArrayList(); + fields.add("a"); + + final TtlIndexOptions options = new TtlIndexOptions(); + options.name("myTtlIndex"); + options.expireAfter(3600); + + final IndexEntity indexResult = db.collection(COLLECTION_NAME).ensureTtlIndex(fields, options); assertThat(indexResult, is(notNullValue())); - assertThat(indexResult.getConstraint(), is(nullValue())); assertThat(indexResult.getFields(), hasItem("a")); assertThat(indexResult.getId(), startsWith(COLLECTION_NAME)); assertThat(indexResult.getIsNewlyCreated(), is(true)); - assertThat(indexResult.getSparse(), is(true)); - assertThat(indexResult.getType(), is(IndexType.fulltext)); - assertThat(indexResult.getUnique(), is(false)); + assertThat(indexResult.getType(), is(IndexType.ttl)); + assertThat(indexResult.getName(), is("myTtlIndex")); } @Test From aa20b69bc819420040cb514daa1a4f679cc53750 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 16:12:18 +0200 Subject: [PATCH 05/10] trigger test only with version >= 3.5 --- src/test/java/com/arangodb/ArangoCollectionTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index 3de1427ec..173848ede 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1290,6 +1290,9 @@ public void createFulltextIndexWithOptions() { @Test public void createTtlIndexWithoutOptions() { + if (!requireVersion(3, 5)) { + return; + } final Collection fields = new ArrayList(); fields.add("a"); try { @@ -1303,6 +1306,9 @@ public void createTtlIndexWithoutOptions() { @Test public void createTtlIndexWithOptions() { + if (!requireVersion(3, 5)) { + return; + } final Collection fields = new ArrayList(); fields.add("a"); From 07e0c4ce8c3de95dbd86224d4ec42454546897da Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 16:14:42 +0200 Subject: [PATCH 06/10] also check ttl expireAfter attribute --- src/test/java/com/arangodb/ArangoCollectionTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/arangodb/ArangoCollectionTest.java b/src/test/java/com/arangodb/ArangoCollectionTest.java index 173848ede..ff40f3c50 100644 --- a/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -1322,6 +1322,7 @@ public void createTtlIndexWithOptions() { assertThat(indexResult.getId(), startsWith(COLLECTION_NAME)); assertThat(indexResult.getIsNewlyCreated(), is(true)); assertThat(indexResult.getType(), is(IndexType.ttl)); + assertThat(indexResult.getExpireAfter(), is(3600)); assertThat(indexResult.getName(), is("myTtlIndex")); } From 175f650113176c74d3eeaca986d51d90e7f75ddc Mon Sep 17 00:00:00 2001 From: hkernbach Date: Wed, 24 Jul 2019 16:47:22 +0200 Subject: [PATCH 07/10] changelog --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 20fdec3e9..f61705a3c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ### Added - added support for named indices +- added support for TTL indices - added minReplicationAttribute for collections and graphs ## [5.0.7] - 2019-07-19 From c9cfbdec9f2d2318a191633c3c6bbf9df94dc836 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Fri, 2 Aug 2019 16:25:54 +0200 Subject: [PATCH 08/10] properly shut down the executor service --- src/main/java/com/arangodb/internal/ArangoCollectionImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java index 750d7311e..690e8f43f 100644 --- a/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java +++ b/src/main/java/com/arangodb/internal/ArangoCollectionImpl.java @@ -118,10 +118,12 @@ public Collection importDocuments(Collection values, Do try { documentImportEntity = completableFuture.get(); } catch (InterruptedException | ExecutionException e) { + executorService.shutdown(); throw new ArangoDBException(e); } documentImportEntityList.add(documentImportEntity); } + executorService.shutdown(); return documentImportEntityList; } From fd3f3292621e157edbd2aec307a1ac1b48c8cf1a Mon Sep 17 00:00:00 2001 From: hkernbach Date: Mon, 5 Aug 2019 11:12:50 +0200 Subject: [PATCH 09/10] use different db name in tests to prevent races between tests --- src/test/java/com/arangodb/ArangoDBTest.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/arangodb/ArangoDBTest.java b/src/test/java/com/arangodb/ArangoDBTest.java index 0a243656c..49cfbf906 100644 --- a/src/test/java/com/arangodb/ArangoDBTest.java +++ b/src/test/java/com/arangodb/ArangoDBTest.java @@ -441,17 +441,20 @@ public void loadproperties2() { @Test public void accessMultipleDatabases() { + String db1 = "multipledb1"; + String db2 = "multipledb2"; + try { - arangoDB.createDatabase("db1"); - arangoDB.createDatabase("db2"); + arangoDB.createDatabase(db1); + arangoDB.createDatabase(db2); - final ArangoDBVersion version1 = arangoDB.db("db1").getVersion(); + final ArangoDBVersion version1 = arangoDB.db(db1).getVersion(); assertThat(version1, is(notNullValue())); - final ArangoDBVersion version2 = arangoDB.db("db2").getVersion(); + final ArangoDBVersion version2 = arangoDB.db(db2).getVersion(); assertThat(version2, is(notNullValue())); } finally { - arangoDB.db("db1").drop(); - arangoDB.db("db2").drop(); + arangoDB.db(db1).drop(); + arangoDB.db(db2).drop(); } } From 21d135d31af7df0b616ee92c656251ff6ca6efc1 Mon Sep 17 00:00:00 2001 From: michele Date: Tue, 6 Aug 2019 12:08:17 +0200 Subject: [PATCH 10/10] TtlIndexOptions extends IndexOptions --- .../com/arangodb/model/TtlIndexOptions.java | 82 ++++++++----------- 1 file changed, 32 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/arangodb/model/TtlIndexOptions.java b/src/main/java/com/arangodb/model/TtlIndexOptions.java index 9342b1f58..45a8ff3e9 100644 --- a/src/main/java/com/arangodb/model/TtlIndexOptions.java +++ b/src/main/java/com/arangodb/model/TtlIndexOptions.java @@ -24,64 +24,46 @@ /** * @author Heiko Kernbach - * * @see API Documentation */ -public class TtlIndexOptions { - - private Iterable fields; - private final IndexType type = IndexType.ttl; - private Integer expireAfter; - private String name; - - public TtlIndexOptions() { - super(); - } +public class TtlIndexOptions extends IndexOptions { - protected Iterable getFields() { - return fields; - } + private Iterable fields; + private final IndexType type = IndexType.ttl; + private Integer expireAfter; - /** - * @param fields - * A list of attribute paths - * @return options - */ - protected TtlIndexOptions fields(final Iterable fields) { - this.fields = fields; - return this; - } + public TtlIndexOptions() { + super(); + } - protected IndexType getType() { - return type; - } + protected Iterable getFields() { + return fields; + } - /** - * @param expireAfter - * The time (in seconds) after a document’s creation after which the documents count as “expired”. - * @return options - */ - public TtlIndexOptions expireAfter(final Integer expireAfter) { - this.expireAfter = expireAfter; - return this; - } + /** + * @param fields A list of attribute paths + * @return options + */ + protected TtlIndexOptions fields(final Iterable fields) { + this.fields = fields; + return this; + } - protected Integer getExpireAfter() { - return expireAfter; - } + protected IndexType getType() { + return type; + } - /** - * @param name - * the name of the index - * @return options - */ - public TtlIndexOptions name(final String name) { - this.name = name; - return this; - } + /** + * @param expireAfter The time (in seconds) after a document’s creation after which the documents count as “expired”. + * @return options + */ + public TtlIndexOptions expireAfter(final Integer expireAfter) { + this.expireAfter = expireAfter; + return this; + } - protected String getName() { - return name; - } + protected Integer getExpireAfter() { + return expireAfter; + } }