/** * Returns true if the parameter supports at least one of the following: * * <ul> * <li>cell-level TTL {@link StoreFeatures#hasCellTTL()}</li> * <li>store-level TTL {@link StoreFeatures#hasStoreTTL()}</li> * </ul> * * @param features an arbitrary {@code StoreFeatures} instance * @return true if and only if at least one TTL mode is supported */ public static boolean supportsAnyTTL(StoreFeatures features) { return features.hasCellTTL() || features.hasStoreTTL(); }
@Test(expected = IllegalArgumentException.class) public void testSettingTTLOnUnsupportedType() { if (!features.hasCellTTL()) { throw new IllegalArgumentException(); } JanusGraphSchemaType type = ImplicitKey.ID; mgmt.setTTL(type, Duration.ZERO); }
@Test(expected = IllegalArgumentException.class) public void testGetTTLFromUnsupportedType() { if (!features.hasCellTTL()) { throw new IllegalArgumentException(); } JanusGraphSchemaType type = ImplicitKey.ID; mgmt.getTTL(type); }
public EntryMetaData[] getMetaDataSchema(String storeName) { List<EntryMetaData> schemaBuilder = Lists.newArrayList(); StoreFeatures features = getFeatures(); if (features.hasTimestamps() && storageConfig.get(STORE_META_TIMESTAMPS,storeName)) schemaBuilder.add(EntryMetaData.TIMESTAMP); if (features.hasCellTTL() && storageConfig.get(STORE_META_TTL,storeName)) schemaBuilder.add(EntryMetaData.TTL); if (features.hasVisibility() && storageConfig.get(STORE_META_VISIBILITY,storeName)) schemaBuilder.add(EntryMetaData.VISIBILITY); if (schemaBuilder.isEmpty()) return StaticArrayEntry.EMPTY_SCHEMA; return schemaBuilder.toArray(new EntryMetaData[schemaBuilder.size()]); }
@Test(expected = IllegalArgumentException.class) public void testSettingTTLOnNonStaticVertexLabel() { if (!features.hasCellTTL()) { throw new IllegalArgumentException(); } VertexLabel label1 = mgmt.makeVertexLabel("event").make(); mgmt.setTTL(label1, Duration.ofSeconds(42)); }
/** * Sets time-to-live for those schema types that support it * * @param type * @param duration Note that only 'seconds' granularity is supported */ @Override public void setTTL(final JanusGraphSchemaType type, final Duration duration) { if (!graph.getBackend().getStoreFeatures().hasCellTTL()) throw new UnsupportedOperationException("The storage engine does not support TTL"); if (type instanceof VertexLabelVertex) { Preconditions.checkArgument(((VertexLabelVertex) type).isStatic(), "must define vertex label as static to allow setting TTL"); } else { Preconditions.checkArgument(type instanceof EdgeLabelVertex || type instanceof PropertyKeyVertex, "TTL is not supported for type " + type.getClass().getSimpleName()); } Preconditions.checkArgument(type instanceof JanusGraphSchemaVertex); Integer ttlSeconds = (duration.isZero()) ? null : (int) duration.getSeconds(); setTypeModifier(type, ModifierType.TTL, ttlSeconds); }
@Override public void mutateMany(Map<String, Map<StaticBuffer, KCVMutation>> mutations, StoreTransaction txh) throws BackendException { if (!manager.getFeatures().hasStoreTTL()) { assert manager.getFeatures().hasCellTTL(); for (Map.Entry<String,Map<StaticBuffer, KCVMutation>> sentry : mutations.entrySet()) { Integer ttl = ttlEnabledStores.get(sentry.getKey()); if (null != ttl && 0 < ttl) { for (KCVMutation mut : sentry.getValue().values()) { if (mut.hasAdditions()) applyTTL(mut.getAdditions(), ttl); } } } } manager.mutateMany(mutations,txh); }
public TTLKCVSManager(KeyColumnValueStoreManager manager) { super(manager); Preconditions.checkArgument(manager.getFeatures().hasCellTTL()); Preconditions.checkArgument(!manager.getFeatures().hasStoreTTL(), "Using TTLKCVSManager with %s is redundant: underlying implementation already supports store-level ttl", manager); this.features = new StandardStoreFeatures.Builder(manager.getFeatures()).storeTTL(true).build(); }
@Test public void testGettingUndefinedEdgeLabelTTL() { if (!features.hasCellTTL()) { return; } // getTTL should return a null duration on an extant type without a TTL mgmt.makeEdgeLabel("likes").make(); mgmt.commit(); graph.tx().rollback(); // Check getTTL on edge label mgmt = graph.openManagement(); assertEquals(Duration.ZERO, mgmt.getTTL(mgmt.getEdgeLabel("likes"))); mgmt.rollback(); }
@Test public void testGettingUndefinedVertexLabelTTL() { if (!features.hasCellTTL()) { return; } // getTTL should return a null duration on an extant type without a TTL mgmt.makeVertexLabel("foo").make(); mgmt.commit(); graph.tx().rollback(); // Check getTTL on vertex label mgmt = graph.openManagement(); assertEquals(Duration.ZERO, mgmt.getTTL(mgmt.getVertexLabel("foo"))); mgmt.rollback(); }
@Test public void testVertexTTLImplicitKey() throws Exception { Duration d; if (!features.hasCellTTL()) { return; } clopen(option(GraphDatabaseConfiguration.STORE_META_TTL, "edgestore"), true); int ttl1 = 1; VertexLabel label1 = mgmt.makeVertexLabel("event").setStatic().make(); mgmt.setTTL(label1, Duration.ofSeconds(ttl1)); assertEquals(Duration.ofSeconds(ttl1), mgmt.getTTL(label1)); mgmt.commit(); JanusGraphVertex v1 = tx.addVertex("event"); JanusGraphVertex v2 = tx.addVertex(); tx.commit(); /* TODO: this fails d = v1.getProperty("~ttl"); assertEquals(1, d); d = v2.getProperty("~ttl"); assertEquals(0, d); */ Object v1id = v1.id(); Object v2id = v2.id(); v1 = getV(graph, v1id); v2 = getV(graph, v2id); d = v1.value("~ttl"); assertEquals(Duration.ofSeconds(1), d); d = v2.value("~ttl"); assertEquals(Duration.ZERO, d); }
@Category({BrittleTests.class}) @Test public void testEdgeTTLWithIndex() throws Exception { if (!features.hasCellTTL()) { return;
@Test public void testEdgeTTLWithTransactions() throws Exception { if (!features.hasCellTTL()) { return; } EdgeLabel label1 = mgmt.makeEdgeLabel("likes").make(); mgmt.setTTL(label1, Duration.ofSeconds(1)); assertEquals(Duration.ofSeconds(1), mgmt.getTTL(label1)); mgmt.commit(); JanusGraphVertex v1 = graph.addVertex(), v2 = graph.addVertex(); v1.addEdge("likes", v2); // pre-commit state of the edge. It is not yet subject to TTL assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); Thread.sleep(1001); // the edge should have expired by now, but only if it had been committed assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); graph.tx().commit(); // still here, because we have just committed the edge. Its countdown starts at the commit assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); Thread.sleep(1001); // the edge has expired in Cassandra, but still appears alive in this transaction assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); // syncing with the data store, we see that the edge has expired graph.tx().rollback(); assertEmpty(v1.query().direction(Direction.OUT).vertices()); }
@Test public void testUnsettingTTL() throws InterruptedException { if (!features.hasCellTTL()) { return;
Duration d; if (!features.hasCellTTL()) { return;
@Test public void testVertexTTLWithCompositeIndex() throws Exception { if (!features.hasCellTTL()) { return; } PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make(); PropertyKey time = mgmt.makePropertyKey("time").dataType(Long.class).make(); final JanusGraphIndex index1 = mgmt.buildIndex("index1", Vertex.class).addKey(name) .buildCompositeIndex(); final JanusGraphIndex index2 = mgmt.buildIndex("index2", Vertex.class).addKey(name).addKey(time) .buildCompositeIndex(); VertexLabel label1 = mgmt.makeVertexLabel("event").setStatic().make(); mgmt.setTTL(label1, Duration.ofSeconds(1)); assertEquals(Duration.ZERO, mgmt.getTTL(name)); assertEquals(Duration.ZERO, mgmt.getTTL(time)); assertEquals(Duration.ofSeconds(1), mgmt.getTTL(label1)); mgmt.commit(); JanusGraphVertex v1 = tx.addVertex(T.label, "event", "name", "some event", "time", System.currentTimeMillis()); tx.commit(); Object id = v1.id(); v1 = getV(graph, id); assertNotNull(v1); assertNotEmpty(graph.query().has("name", "some event").vertices()); Thread.sleep(1001); graph.tx().rollback(); v1 = getV(graph, id); assertNull(v1); assertEmpty(graph.query().has("name", "some event").vertices()); }
if (storeManager.getFeatures().hasCellTTL() && !storeManager.getFeatures().hasStoreTTL()) { storeManager = new TTLKCVSManager(storeManager); } else if (!storeManager.getFeatures().hasStoreTTL()) {
@Category({BrittleTests.class}) @Test public void testPropertyTTLTiming() throws Exception { if (!features.hasCellTTL()) { return;
@Test public void testEdgeTTLTiming() throws Exception { if (!features.hasCellTTL()) { return;
/** * Construct a Builder whose default values exactly match the values on * the supplied {@code template}. */ public Builder(StoreFeatures template) { unorderedScan(template.hasUnorderedScan()); orderedScan(template.hasOrderedScan()); multiQuery(template.hasMultiQuery()); locking(template.hasLocking()); batchMutation(template.hasBatchMutation()); localKeyPartition(template.hasLocalKeyPartition()); keyOrdered(template.isKeyOrdered()); distributed(template.isDistributed()); transactional(template.hasTxIsolation()); timestamps(template.hasTimestamps()); preferredTimestamps(template.getPreferredTimestamps()); cellTTL(template.hasCellTTL()); storeTTL(template.hasStoreTTL()); visibility(template.hasVisibility()); persists(template.supportsPersistence()); if (template.isKeyConsistent()) { keyConsistent(template.getKeyConsistentTxConfig(), template.getLocalKeyConsistentTxConfig()); } scanTxConfig(template.getScanTxConfig()); supportsInterruption(template.supportsInterruption()); optimisticLocking(template.hasOptimisticLocking()); }