use of org.janusgraph.core.schema.RelationTypeIndex in project janusgraph by JanusGraph.
the class ManagementUtil method awaitIndexUpdate.
private static void awaitIndexUpdate(JanusGraph g, String indexName, String relationTypeName, long time, TemporalUnit unit) {
Preconditions.checkArgument(g != null && g.isOpen(), "Need to provide valid, open graph instance");
Preconditions.checkArgument(time > 0 && unit != null, "Need to provide valid time interval");
Preconditions.checkArgument(StringUtils.isNotBlank(indexName), "Need to provide an index name");
StandardJanusGraph graph = (StandardJanusGraph) g;
TimestampProvider times = graph.getConfiguration().getTimestampProvider();
Instant end = times.getTime().plus(Duration.of(time, unit));
boolean isStable = false;
while (times.getTime().isBefore(end)) {
JanusGraphManagement management = graph.openManagement();
try {
if (StringUtils.isNotBlank(relationTypeName)) {
RelationTypeIndex idx = management.getRelationIndex(management.getRelationType(relationTypeName), indexName);
Preconditions.checkArgument(idx != null, "Index could not be found: %s @ %s", indexName, relationTypeName);
isStable = idx.getIndexStatus().isStable();
} else {
JanusGraphIndex idx = management.getGraphIndex(indexName);
Preconditions.checkArgument(idx != null, "Index could not be found: %s", indexName);
isStable = true;
for (PropertyKey key : idx.getFieldKeys()) {
if (!idx.getIndexStatus(key).isStable())
isStable = false;
}
}
} finally {
management.rollback();
}
if (isStable)
break;
try {
times.sleepFor(Duration.ofMillis(500));
} catch (InterruptedException ignored) {
}
}
if (!isStable)
throw new JanusGraphException("Index did not stabilize within the given amount of time. For sufficiently long " + "wait periods this is most likely caused by a failed/incorrectly shut down JanusGraph instance or a lingering transaction.");
}
use of org.janusgraph.core.schema.RelationTypeIndex in project janusgraph by JanusGraph.
the class ManagementSystem method changeName.
@Override
public void changeName(JanusGraphSchemaElement element, String newName) {
Preconditions.checkArgument(StringUtils.isNotBlank(newName), "Invalid name: %s", newName);
JanusGraphSchemaVertex schemaVertex = getSchemaVertex(element);
if (schemaVertex.name().equals(newName))
return;
JanusGraphSchemaCategory schemaCategory = schemaVertex.valueOrNull(BaseKey.SchemaCategory);
Preconditions.checkArgument(schemaCategory.hasName(), "Invalid schema element: %s", element);
if (schemaVertex instanceof RelationType) {
InternalRelationType relType = (InternalRelationType) schemaVertex;
if (relType.getBaseType() != null) {
newName = composeRelationTypeIndexName(relType.getBaseType(), newName);
} else
assert !(element instanceof RelationTypeIndex);
JanusGraphSchemaCategory cat = relType.isEdgeLabel() ? JanusGraphSchemaCategory.EDGELABEL : JanusGraphSchemaCategory.PROPERTYKEY;
SystemTypeManager.throwIfSystemName(cat, newName);
} else if (element instanceof VertexLabel) {
SystemTypeManager.throwIfSystemName(JanusGraphSchemaCategory.VERTEXLABEL, newName);
} else if (element instanceof JanusGraphIndex) {
checkIndexName(newName);
}
transaction.addProperty(schemaVertex, BaseKey.SchemaName, schemaCategory.getSchemaName(newName));
updateSchemaVertex(schemaVertex);
schemaVertex.resetCache();
updatedTypes.add(schemaVertex);
}
use of org.janusgraph.core.schema.RelationTypeIndex in project janusgraph by JanusGraph.
the class ManagementSystem method updateIndex.
/* --------------
Schema Update
--------------- */
@Override
public IndexJobFuture updateIndex(Index index, SchemaAction updateAction) {
Preconditions.checkArgument(index != null, "Need to provide an index");
Preconditions.checkArgument(updateAction != null, "Need to provide update action");
JanusGraphSchemaVertex schemaVertex = getSchemaVertex(index);
Set<JanusGraphSchemaVertex> dependentTypes;
Set<PropertyKeyVertex> keySubset = ImmutableSet.of();
if (index instanceof RelationTypeIndex) {
dependentTypes = ImmutableSet.of((JanusGraphSchemaVertex) ((InternalRelationType) schemaVertex).getBaseType());
if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
return null;
} else if (index instanceof JanusGraphIndex) {
IndexType indexType = schemaVertex.asIndexType();
dependentTypes = Sets.newHashSet();
if (indexType.isCompositeIndex()) {
if (!updateAction.isApplicableStatus(schemaVertex.getStatus()))
return null;
for (PropertyKey key : ((JanusGraphIndex) index).getFieldKeys()) {
dependentTypes.add((PropertyKeyVertex) key);
}
} else {
keySubset = Sets.newHashSet();
MixedIndexType mixedIndexType = (MixedIndexType) indexType;
Set<SchemaStatus> applicableStatus = updateAction.getApplicableStatus();
for (ParameterIndexField field : mixedIndexType.getFieldKeys()) {
if (applicableStatus.contains(field.getStatus()))
keySubset.add((PropertyKeyVertex) field.getFieldKey());
}
if (keySubset.isEmpty())
return null;
dependentTypes.addAll(keySubset);
}
} else
throw new UnsupportedOperationException("Updates not supported for index: " + index);
IndexIdentifier indexId = new IndexIdentifier(index);
StandardScanner.Builder builder;
IndexJobFuture future;
switch(updateAction) {
case REGISTER_INDEX:
setStatus(schemaVertex, SchemaStatus.INSTALLED, keySubset);
updatedTypes.add(schemaVertex);
updatedTypes.addAll(dependentTypes);
setUpdateTrigger(new UpdateStatusTrigger(graph, schemaVertex, SchemaStatus.REGISTERED, keySubset));
future = new EmptyIndexJobFuture();
break;
case REINDEX:
builder = graph.getBackend().buildEdgeScanJob();
builder.setFinishJob(indexId.getIndexJobFinisher(graph, SchemaAction.ENABLE_INDEX));
builder.setJobId(indexId);
builder.setJob(VertexJobConverter.convert(graph, new IndexRepairJob(indexId.indexName, indexId.relationTypeName)));
try {
future = builder.execute();
} catch (BackendException e) {
throw new JanusGraphException(e);
}
break;
case ENABLE_INDEX:
setStatus(schemaVertex, SchemaStatus.ENABLED, keySubset);
updatedTypes.add(schemaVertex);
if (!keySubset.isEmpty())
updatedTypes.addAll(dependentTypes);
future = new EmptyIndexJobFuture();
break;
case DISABLE_INDEX:
setStatus(schemaVertex, SchemaStatus.INSTALLED, keySubset);
updatedTypes.add(schemaVertex);
if (!keySubset.isEmpty())
updatedTypes.addAll(dependentTypes);
setUpdateTrigger(new UpdateStatusTrigger(graph, schemaVertex, SchemaStatus.DISABLED, keySubset));
future = new EmptyIndexJobFuture();
break;
case REMOVE_INDEX:
if (index instanceof RelationTypeIndex) {
builder = graph.getBackend().buildEdgeScanJob();
} else {
JanusGraphIndex graphIndex = (JanusGraphIndex) index;
if (graphIndex.isMixedIndex())
throw new UnsupportedOperationException("External mixed indexes must be removed in the indexing system directly.");
builder = graph.getBackend().buildGraphIndexScanJob();
}
builder.setFinishJob(indexId.getIndexJobFinisher());
builder.setJobId(indexId);
builder.setJob(new IndexRemoveJob(graph, indexId.indexName, indexId.relationTypeName));
try {
future = builder.execute();
} catch (BackendException e) {
throw new JanusGraphException(e);
}
break;
default:
throw new UnsupportedOperationException("Update action not supported: " + updateAction);
}
return future;
}
use of org.janusgraph.core.schema.RelationTypeIndex in project janusgraph by JanusGraph.
the class RelationIndexStatusWatcher method call.
/**
* Poll a relation index until it has a certain {@link SchemaStatus},
* or until a configurable timeout is exceeded.
*
* @return a report with information about schema state, execution duration, and the index
*/
@Override
public RelationIndexStatusReport call() throws InterruptedException {
Preconditions.checkNotNull(g, "Graph instance must not be null");
Preconditions.checkNotNull(relationIndexName, "Index name must not be null");
Preconditions.checkNotNull(statuses, "Target statuses must not be null");
Preconditions.checkArgument(statuses.size() > 0, "Target statuses must include at least one status");
RelationTypeIndex idx;
Timer t = new Timer(TimestampProviders.MILLI).start();
boolean timedOut;
while (true) {
final SchemaStatus actualStatus;
JanusGraphManagement management = null;
try {
management = g.openManagement();
idx = management.getRelationIndex(management.getRelationType(relationTypeName), relationIndexName);
actualStatus = idx.getIndexStatus();
LOGGER.info("Index {} (relation type {}) has status {}", relationIndexName, relationTypeName, actualStatus);
if (statuses.contains(actualStatus)) {
return new RelationIndexStatusReport(true, relationIndexName, relationTypeName, actualStatus, statuses, t.elapsed());
}
} finally {
if (null != management)
// Let an exception here propagate up the stack
management.rollback();
}
timedOut = null != timeout && 0 < t.elapsed().compareTo(timeout);
if (timedOut) {
LOGGER.info("Timed out ({}) while waiting for index {} (relation type {}) to reach status(es) {}", timeout, relationIndexName, relationTypeName, statuses);
return new RelationIndexStatusReport(false, relationIndexName, relationTypeName, actualStatus, statuses, t.elapsed());
}
Thread.sleep(poll.toMillis());
}
}
use of org.janusgraph.core.schema.RelationTypeIndex in project janusgraph by JanusGraph.
the class MapReduceIndexManagement method updateIndex.
/**
* Updates the provided index according to the given {@link SchemaAction}.
* Only {@link SchemaAction#REINDEX} and {@link SchemaAction#REMOVE_INDEX} are supported.
*
* @param index the index to process
* @param updateAction either {@code REINDEX} or {@code REMOVE_INDEX}
* @return a future that returns immediately;
* this method blocks until the Hadoop MapReduce job completes
*/
// TODO make this future actually async and update javadoc @return accordingly
public JanusGraphManagement.IndexJobFuture updateIndex(Index index, SchemaAction updateAction) throws BackendException {
Preconditions.checkNotNull(index, "Index parameter must not be null", index);
Preconditions.checkNotNull(updateAction, "%s parameter must not be null", SchemaAction.class.getSimpleName());
Preconditions.checkArgument(SUPPORTED_ACTIONS.contains(updateAction), "Only these %s parameters are supported: %s (was given %s)", SchemaAction.class.getSimpleName(), SUPPORTED_ACTIONS_STRING, updateAction);
Preconditions.checkArgument(RelationTypeIndex.class.isAssignableFrom(index.getClass()) || JanusGraphIndex.class.isAssignableFrom(index.getClass()), "Index %s has class %s: must be a %s or %s (or subtype)", index.getClass(), RelationTypeIndex.class.getSimpleName(), JanusGraphIndex.class.getSimpleName());
org.apache.hadoop.conf.Configuration hadoopConf = new org.apache.hadoop.conf.Configuration();
ModifiableHadoopConfiguration janusGraphMapReduceConfiguration = ModifiableHadoopConfiguration.of(JanusGraphHadoopConfiguration.MAPRED_NS, hadoopConf);
// The job we'll execute to either REINDEX or REMOVE_INDEX
final Class<? extends IndexUpdateJob> indexJobClass;
final Class<? extends Mapper> mapperClass;
// The class of the IndexUpdateJob and the Mapper that will be used to run it (VertexScanJob vs ScanJob)
if (updateAction.equals(SchemaAction.REINDEX)) {
indexJobClass = IndexRepairJob.class;
mapperClass = HadoopVertexScanMapper.class;
} else if (updateAction.equals(SchemaAction.REMOVE_INDEX)) {
indexJobClass = IndexRemoveJob.class;
mapperClass = HadoopScanMapper.class;
} else {
// Shouldn't get here -- if this exception is ever thrown, update SUPPORTED_ACTIONS
throw new IllegalStateException("Unrecognized " + SchemaAction.class.getSimpleName() + ": " + updateAction);
}
// The column family that serves as input to the IndexUpdateJob
final String readCF;
if (RelationTypeIndex.class.isAssignableFrom(index.getClass())) {
readCF = Backend.EDGESTORE_NAME;
} else {
JanusGraphIndex graphIndex = (JanusGraphIndex) index;
if (graphIndex.isMixedIndex() && !updateAction.equals(SchemaAction.REINDEX))
throw new UnsupportedOperationException("External mixed indexes must be removed in the indexing system directly.");
Preconditions.checkState(JanusGraphIndex.class.isAssignableFrom(index.getClass()));
if (updateAction.equals(SchemaAction.REMOVE_INDEX))
readCF = Backend.INDEXSTORE_NAME;
else
readCF = Backend.EDGESTORE_NAME;
}
janusGraphMapReduceConfiguration.set(JanusGraphHadoopConfiguration.COLUMN_FAMILY_NAME, readCF);
// The MapReduce InputFormat class based on the open graph's store manager
final Class<? extends InputFormat> inputFormat;
final Class<? extends KeyColumnValueStoreManager> storeManagerClass = graph.getBackend().getStoreManagerClass();
if (CASSANDRA_STORE_MANAGER_CLASSES.contains(storeManagerClass)) {
inputFormat = CassandraBinaryInputFormat.class;
// Set the partitioner
IPartitioner part = ((AbstractCassandraStoreManager) graph.getBackend().getStoreManager()).getCassandraPartitioner();
hadoopConf.set("cassandra.input.partitioner.class", part.getClass().getName());
} else if (HBASE_STORE_MANAGER_CLASSES.contains(storeManagerClass)) {
inputFormat = HBaseBinaryInputFormat.class;
} else {
throw new IllegalArgumentException("Store manager class " + storeManagerClass + "is not supported");
}
// The index name and relation type name (if the latter is applicable)
final String indexName = index.name();
final RelationType relationType = RelationTypeIndex.class.isAssignableFrom(index.getClass()) ? ((RelationTypeIndex) index).getType() : null;
final String relationTypeName = relationType == null ? StringUtils.EMPTY : relationType.name();
Preconditions.checkNotNull(indexName);
// Set the class of the IndexUpdateJob
janusGraphMapReduceConfiguration.set(JanusGraphHadoopConfiguration.SCAN_JOB_CLASS, indexJobClass.getName());
// Set the configuration of the IndexUpdateJob
copyIndexJobKeys(hadoopConf, indexName, relationTypeName);
janusGraphMapReduceConfiguration.set(JanusGraphHadoopConfiguration.SCAN_JOB_CONFIG_ROOT, GraphDatabaseConfiguration.class.getName() + "#JOB_NS");
// Copy the StandardJanusGraph configuration under JanusGraphHadoopConfiguration.GRAPH_CONFIG_KEYS
org.apache.commons.configuration.Configuration localConfiguration = graph.getConfiguration().getLocalConfiguration();
localConfiguration.clearProperty(Graph.GRAPH);
copyInputKeys(hadoopConf, localConfiguration);
String jobName = HadoopScanMapper.class.getSimpleName() + "[" + indexJobClass.getSimpleName() + "]";
try {
return new CompletedJobFuture(HadoopScanRunner.runJob(hadoopConf, inputFormat, jobName, mapperClass));
} catch (Exception e) {
return new FailedJobFuture(e);
}
}
Aggregations