// Copyright 2017 JanusGraph 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.janusgraph.core.schema;
import org.janusgraph.core.EdgeLabel;
import org.janusgraph.core.PropertyKey;
import org.janusgraph.core.RelationType;
import org.janusgraph.core.JanusGraphTransaction;
import org.janusgraph.core.VertexLabel;
import org.janusgraph.diskstorage.keycolumnvalue.scan.ScanMetrics;
import org.apache.tinkerpop.gremlin.process.traversal.Order;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Element;
import java.time.Duration;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* The JanusGraphManagement interface provides methods to define, update, and inspect the schema of a JanusGraph graph.
* It wraps a {@link JanusGraphTransaction} and therefore copies many of its methods as they relate to schema inspection
* and definition.
* <p/>
* JanusGraphManagement behaves like a transaction in that it opens a transactional scope for reading the schema and making
* changes to it. As such, it needs to be explicitly closed via its {@link #commit()} or {@link #rollback()} methods.
* A JanusGraphManagement transaction is opened on a graph via {@link org.janusgraph.core.JanusGraph#openManagement()}.
* <p/>
* JanusGraphManagement provides methods to:
* <ul>
* <li>Schema Types: View, update, and create vertex labels, edge labels, and property keys</li>
* <li>Relation Type Index: View and create vertex-centric indexes on edge labels and property keys</li>
* <li>Graph Index: View and create graph-wide indexes for efficient element retrieval</li>
* <li>Consistency Management: Set the consistency level of individual schema elements</li>
* </ul>
*
* @author Matthias Broecheler (me@matthiasb.com)
*/
public interface JanusGraphManagement extends JanusGraphConfiguration, SchemaManager {
/*
##################### RELATION TYPE INDEX ##########################
*/
/**
* Identical to {@link #buildEdgeIndex(org.janusgraph.core.EdgeLabel, String, org.apache.tinkerpop.gremlin.structure.Direction, org.apache.tinkerpop.gremlin.process.traversal.Order, org.janusgraph.core.PropertyKey...)}
* with default sort order {@link org.apache.tinkerpop.gremlin.process.traversal.Order#incr}.
*
* @param label
* @param name
* @param direction
* @param sortKeys
* @return the created {@link RelationTypeIndex}
*/
public RelationTypeIndex buildEdgeIndex(EdgeLabel label, String name, Direction direction, PropertyKey... sortKeys);
/**
* Creates a {@link RelationTypeIndex} for the provided edge label. That means, that all edges of that label will be
* indexed according to this index definition which will speed up certain vertex-centric queries.
* <p/>
* An indexed is defined by its name, the direction in which the index should be created (can be restricted to one
* direction or both), the sort order and - most importantly - the sort keys which define the index key.
*
* @param label
* @param name
* @param direction
* @param sortOrder
* @param sortKeys
* @return the created {@link RelationTypeIndex}
*/
public RelationTypeIndex buildEdgeIndex(EdgeLabel label, String name, Direction direction, Order sortOrder, PropertyKey... sortKeys);
/**
* Identical to {@link #buildPropertyIndex(org.janusgraph.core.PropertyKey, String, org.apache.tinkerpop.gremlin.process.traversal.Order, org.janusgraph.core.PropertyKey...)}
* with default sort order {@link org.apache.tinkerpop.gremlin.process.traversal.Order#incr}.
*
* @param key
* @param name
* @param sortKeys
* @return the created {@link RelationTypeIndex}
*/
public RelationTypeIndex buildPropertyIndex(PropertyKey key, String name, PropertyKey... sortKeys);
/**
* Creates a {@link RelationTypeIndex} for the provided property key. That means, that all properties of that key will be
* indexed according to this index definition which will speed up certain vertex-centric queries.
* <p/>
* An indexed is defined by its name, the sort order and - most importantly - the sort keys which define the index key.
*
* @param key
* @param name
* @param sortOrder
* @param sortKeys
* @return the created {@link RelationTypeIndex}
*/
public RelationTypeIndex buildPropertyIndex(PropertyKey key, String name, Order sortOrder, PropertyKey... sortKeys);
/**
* Whether a {@link RelationTypeIndex} with the given name has been defined for the provided {@link RelationType}
*
* @param type
* @param name
* @return
*/
public boolean containsRelationIndex(RelationType type, String name);
/**
* Returns the {@link RelationTypeIndex} with the given name for the provided {@link RelationType} or null
* if it does not exist
*
* @param type
* @param name
* @return
*/
public RelationTypeIndex getRelationIndex(RelationType type, String name);
/**
* Returns an {@link Iterable} over all {@link RelationTypeIndex}es defined for the provided {@link RelationType}
*
* @param type
* @return
*/
public Iterable<RelationTypeIndex> getRelationIndexes(RelationType type);
/*
##################### GRAPH INDEX ##########################
*/
/**
* Whether the graph has a graph index defined with the given name.
*
* @param name
* @return
*/
public boolean containsGraphIndex(String name);
/**
* Returns the graph index with the given name or null if it does not exist
*
* @param name
* @return
*/
public JanusGraphIndex getGraphIndex(String name);
/**
* Returns all graph indexes that index the given element type.
*
* @param elementType
* @return
*/
public Iterable<JanusGraphIndex> getGraphIndexes(final Class<? extends Element> elementType);
/**
* Returns an {@link IndexBuilder} to add a graph index to this JanusGraph graph. The index to-be-created
* has the provided name and indexes elements of the given type.
*
* @param indexName
* @param elementType
* @return
*/
public IndexBuilder buildIndex(String indexName, Class<? extends Element> elementType);
public void addIndexKey(final JanusGraphIndex index, final PropertyKey key, Parameter... parameters);
/**
* Builder for {@link JanusGraphIndex}. Allows for the configuration of a graph index prior to its construction.
*/
public interface IndexBuilder {
/**
* Adds the given key to the composite key of this index
*
* @param key
* @return this IndexBuilder
*/
public IndexBuilder addKey(PropertyKey key);
/**
* Adds the given key and associated parameters to the composite key of this index
*
* @param key
* @param parameters
* @return this IndexBuilder
*/
public IndexBuilder addKey(PropertyKey key, Parameter... parameters);
/**
* Restricts this index to only those elements that have the provided schemaType. If this graph index indexes
* vertices, then the argument is expected to be a vertex label and only vertices with that label will be indexed.
* Likewise, for edges and properties only those with the matching relation type will be indexed.
*
* @param schemaType
* @return this IndexBuilder
*/
public IndexBuilder indexOnly(JanusGraphSchemaType schemaType);
/**
* Makes this a unique index for the configured element type,
* i.e. an index key can be associated with at most one element in the graph.
*
* @return this IndexBuilder
*/
public IndexBuilder unique();
/**
* Builds a composite index according to the specification
*
* @return the created composite {@link JanusGraphIndex}
*/
public JanusGraphIndex buildCompositeIndex();
/**
* Builds a mixed index according to the specification against the backend index with the given name (i.e.
* the name under which that index is configured in the graph configuration)
*
* @param backingIndex the name of the mixed index
* @return the created mixed {@link JanusGraphIndex}
*/
public JanusGraphIndex buildMixedIndex(String backingIndex);
}
public interface IndexJobFuture extends Future<ScanMetrics> {
/**
* Returns a set of potentially incomplete and still-changing metrics
* for this job. This is not guaranteed to be the same object as the
* one returned by {@link #get()}, nor will the metrics visible through
* the object returned by this method necessarily eventually converge
* on the same values in the object returned by {@link #get()}, though
* the implementation should attempt to provide both properties when
* practical.
* <p/>
* The metrics visible through the object returned by this method may
* also change their values between reads. In other words, this is not
* necessarily an immutable snapshot.
* <p/>
* If the index job has failed and the implementation is capable of
* quickly detecting that, then the implementation should throw an
* {@code ExecutionException}. Returning metrics in case of failure is
* acceptable, but throwing an exception is preferred.
*
* @return metrics for a potentially still-running job
* @throws ExecutionException if the index job threw an exception
*/
public ScanMetrics getIntermediateResult() throws ExecutionException;
}
/*
##################### CONSISTENCY SETTING ##########################
*/
/**
* Retrieves the consistency modifier for the given {@link JanusGraphSchemaElement}. If none has been explicitly
* defined, {@link ConsistencyModifier#DEFAULT} is returned.
*
* @param element
* @return
*/
public ConsistencyModifier getConsistency(JanusGraphSchemaElement element);
/**
* Sets the consistency modifier for the given {@link JanusGraphSchemaElement}. Note, that only {@link RelationType}s
* and composite graph indexes allow changing of the consistency level.
*
* @param element
* @param consistency
*/
public void setConsistency(JanusGraphSchemaElement element, ConsistencyModifier consistency);
/**
* Retrieves the time-to-live for the given {@link JanusGraphSchemaType} as a {@link Duration}.
* If no TTL has been defined, the returned Duration will be zero-length ("lives forever").
*
* @param type
* @return
*/
public Duration getTTL(JanusGraphSchemaType type);
/**
* Sets the time-to-live for the given {@link JanusGraphSchemaType}. The most granular time unit used for TTL values
* is seconds. Any argument will be rounded to seconds if it is more granular than that.
* The {@code ttl} must be nonnegative. When {@code ttl} is zero, any existing TTL on {@code type} is removed
* ("lives forever"). Positive {@code ttl} values are interpreted literally.
*
* @param type the affected type
* @param duration time-to-live
*/
public void setTTL(JanusGraphSchemaType type, Duration duration);
/*
##################### SCHEMA UPDATE ##########################
*/
/**
* Changes the name of a {@link JanusGraphSchemaElement} to the provided new name.
* The new name must be valid and not already in use, otherwise an {@link IllegalArgumentException} is thrown.
*
* @param element
* @param newName
*/
public void changeName(JanusGraphSchemaElement element, String newName);
/**
* Updates the provided index according to the given {@link SchemaAction}
*
* @param index
* @param updateAction
* @return a future that completes when the index action is done
*/
public IndexJobFuture updateIndex(Index index, SchemaAction updateAction);
/**
* If an index update job was triggered through {@link #updateIndex(Index, SchemaAction)} with schema actions
* {@link org.janusgraph.core.schema.SchemaAction#REINDEX} or {@link org.janusgraph.core.schema.SchemaAction#REMOVE_INDEX}
* then this method can be used to track the status of this asynchronous process.
*
* @param index
* @return A message that reflects the status of the index job
*/
public IndexJobFuture getIndexJobStatus(Index index);
/*
##################### CLUSTER MANAGEMENT ##########################
*/
/**
* Returns a set of unique instance ids for all JanusGraph instances that are currently
* part of this graph cluster.
*
* @return
*/
public Set<String> getOpenInstances();
/**
* Forcefully removes a JanusGraph instance from this graph cluster as identified by its name.
* <p/>
* This method should be used with great care and only in cases where a JanusGraph instance
* has been abnormally terminated (i.e. killed instead of properly shut-down). If this happens, the instance
* will continue to be listed as an open instance which means that 1) a new instance with the same id cannot
* be started and 2) schema updates will fail because the killed instance cannot acknowledge the schema update.
* <p/>
* <p/>
* Throws an exception if the instance is not part of this cluster or if the instance has
* been started after the start of this management transaction which is indicative of the instance
* having been restarted successfully.
*
* @param instanceId
*/
public void forceCloseInstance(String instanceId);
/**
* Returns an iterable over all defined types that have the given clazz (either {@link EdgeLabel} which returns all labels,
* {@link PropertyKey} which returns all keys, or {@link RelationType} which returns all types).
*
* @param clazz {@link RelationType} or sub-interface
* @param <T>
* @return Iterable over all types for the given category (label, key, or both)
*/
public <T extends RelationType> Iterable<T> getRelationTypes(Class<T> clazz);
/**
* Returns an {@link Iterable} over all defined {@link VertexLabel}s.
*
* @return
*/
public Iterable<VertexLabel> getVertexLabels();
/**
* Whether this management transaction is open or has been closed (i.e. committed or rolled-back)
*
* @return
*/
public boolean isOpen();
/**
* Commits this management transaction and persists all schema changes. Closes this transaction.
*
* @see org.janusgraph.core.JanusGraphTransaction#commit()
*/
public void commit();
/**
* Closes this management transaction and discards all changes.
*
* @see org.janusgraph.core.JanusGraphTransaction#rollback()
*/
public void rollback();
}