use of com.thinkaurelius.titan.core.schema.TitanManagement in project titan by thinkaurelius.
the class ManagementUtil method awaitIndexUpdate.
private static void awaitIndexUpdate(TitanGraph 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");
StandardTitanGraph graph = (StandardTitanGraph) g;
TimestampProvider times = graph.getConfiguration().getTimestampProvider();
Instant end = times.getTime().plus(Duration.of(time, unit));
boolean isStable = false;
while (times.getTime().isBefore(end)) {
TitanManagement mgmt = graph.openManagement();
try {
if (StringUtils.isNotBlank(relationTypeName)) {
RelationTypeIndex idx = mgmt.getRelationIndex(mgmt.getRelationType(relationTypeName), indexName);
Preconditions.checkArgument(idx != null, "Index could not be found: %s @ %s", indexName, relationTypeName);
isStable = idx.getIndexStatus().isStable();
} else {
TitanGraphIndex idx = mgmt.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 {
mgmt.rollback();
}
if (isStable)
break;
try {
times.sleepFor(Duration.ofMillis(500));
} catch (InterruptedException e) {
}
}
if (!isStable)
throw new TitanException("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 Titan instance or a lingering transaction.");
}
use of com.thinkaurelius.titan.core.schema.TitanManagement in project titan by thinkaurelius.
the class AbstractIndexManagementIT method testRemoveGraphIndex.
@Test
public void testRemoveGraphIndex() throws InterruptedException, BackendException, ExecutionException {
tx.commit();
mgmt.commit();
// Load the "Graph of the Gods" sample data
GraphOfTheGodsFactory.loadWithoutMixedIndex(graph, true);
// Disable the "name" composite index
TitanManagement m = graph.openManagement();
TitanGraphIndex nameIndex = m.getGraphIndex("name");
m.updateIndex(nameIndex, SchemaAction.DISABLE_INDEX);
m.commit();
graph.tx().commit();
// Block until the SchemaStatus transitions to DISABLED
assertTrue(ManagementSystem.awaitGraphIndexStatus(graph, "name").status(SchemaStatus.DISABLED).call().getSucceeded());
// Remove index
MapReduceIndexManagement mri = new MapReduceIndexManagement(graph);
m = graph.openManagement();
TitanGraphIndex index = m.getGraphIndex("name");
ScanMetrics metrics = mri.updateIndex(index, SchemaAction.REMOVE_INDEX).get();
assertEquals(12, metrics.getCustom(IndexRemoveJob.DELETED_RECORDS_COUNT));
}
use of com.thinkaurelius.titan.core.schema.TitanManagement in project titan by thinkaurelius.
the class FulgoraGraphComputer method submit.
@Override
public Future<ComputerResult> submit() {
if (executed)
throw Exceptions.computerHasAlreadyBeenSubmittedAVertexProgram();
else
executed = true;
// it is not possible execute a computer if it has no vertex program nor mapreducers
if (null == vertexProgram && mapReduces.isEmpty())
throw GraphComputer.Exceptions.computerHasNoVertexProgramNorMapReducers();
// it is possible to run mapreducers without a vertex program
if (null != vertexProgram) {
GraphComputerHelper.validateProgramOnComputer(this, vertexProgram);
this.mapReduces.addAll(this.vertexProgram.getMapReducers());
}
// if the user didn't set desired persistence/resultgraph, then get from vertex program or else, no persistence
this.persistMode = GraphComputerHelper.getPersistState(Optional.ofNullable(this.vertexProgram), Optional.ofNullable(this.persistMode));
this.resultGraphMode = GraphComputerHelper.getResultGraphState(Optional.ofNullable(this.vertexProgram), Optional.ofNullable(this.resultGraphMode));
// determine the legality persistence and result graph options
if (!this.features().supportsResultGraphPersistCombination(this.resultGraphMode, this.persistMode))
throw GraphComputer.Exceptions.resultGraphPersistCombinationNotSupported(this.resultGraphMode, this.persistMode);
memory = new FulgoraMemory(vertexProgram, mapReduces);
return CompletableFuture.<ComputerResult>supplyAsync(() -> {
final long time = System.currentTimeMillis();
if (null != vertexProgram) {
// ##### Execute vertex program
vertexMemory = new FulgoraVertexMemory(expectedNumVertices, graph.getIDManager(), vertexProgram);
// execute the vertex program
vertexProgram.setup(memory);
memory.completeSubRound();
for (int iteration = 1; ; iteration++) {
vertexMemory.nextIteration(vertexProgram.getMessageScopes(memory));
jobId = name + "#" + iteration;
VertexProgramScanJob.Executor job = VertexProgramScanJob.getVertexProgramScanJob(graph, memory, vertexMemory, vertexProgram);
StandardScanner.Builder scanBuilder = graph.getBackend().buildEdgeScanJob();
scanBuilder.setJobId(jobId);
scanBuilder.setNumProcessingThreads(numThreads);
scanBuilder.setWorkBlockSize(readBatchSize);
scanBuilder.setJob(job);
PartitionedVertexProgramExecutor pvpe = new PartitionedVertexProgramExecutor(graph, memory, vertexMemory, vertexProgram);
try {
//Iterates over all vertices and computes the vertex program on all non-partitioned vertices. For partitioned ones, the data is aggregated
ScanMetrics jobResult = scanBuilder.execute().get();
long failures = jobResult.get(ScanMetrics.Metric.FAILURE);
if (failures > 0) {
throw new TitanException("Failed to process [" + failures + "] vertices in vertex program iteration [" + iteration + "]. Computer is aborting.");
}
//Runs the vertex program on all aggregated, partitioned vertices.
pvpe.run(numThreads, jobResult);
failures = jobResult.getCustom(PartitionedVertexProgramExecutor.PARTITION_VERTEX_POSTFAIL);
if (failures > 0) {
throw new TitanException("Failed to process [" + failures + "] partitioned vertices in vertex program iteration [" + iteration + "]. Computer is aborting.");
}
} catch (Exception e) {
throw new TitanException(e);
}
vertexMemory.completeIteration();
memory.completeSubRound();
try {
if (this.vertexProgram.terminate(this.memory)) {
break;
}
} finally {
memory.incrIteration();
memory.completeSubRound();
}
}
}
// ##### Execute mapreduce jobs
// Collect map jobs
Map<MapReduce, FulgoraMapEmitter> mapJobs = new HashMap<>(mapReduces.size());
for (MapReduce mapReduce : mapReduces) {
if (mapReduce.doStage(MapReduce.Stage.MAP)) {
FulgoraMapEmitter mapEmitter = new FulgoraMapEmitter<>(mapReduce.doStage(MapReduce.Stage.REDUCE));
mapJobs.put(mapReduce, mapEmitter);
}
}
// Execute map jobs
jobId = name + "#map";
VertexMapJob.Executor job = VertexMapJob.getVertexMapJob(graph, vertexMemory, mapJobs);
StandardScanner.Builder scanBuilder = graph.getBackend().buildEdgeScanJob();
scanBuilder.setJobId(jobId);
scanBuilder.setNumProcessingThreads(numThreads);
scanBuilder.setWorkBlockSize(readBatchSize);
scanBuilder.setJob(job);
try {
ScanMetrics jobResult = scanBuilder.execute().get();
long failures = jobResult.get(ScanMetrics.Metric.FAILURE);
if (failures > 0) {
throw new TitanException("Failed to process [" + failures + "] vertices in map phase. Computer is aborting.");
}
failures = jobResult.getCustom(VertexMapJob.MAP_JOB_FAILURE);
if (failures > 0) {
throw new TitanException("Failed to process [" + failures + "] individual map jobs. Computer is aborting.");
}
} catch (Exception e) {
throw new TitanException(e);
}
// Execute reduce phase and add to memory
for (Map.Entry<MapReduce, FulgoraMapEmitter> mapJob : mapJobs.entrySet()) {
FulgoraMapEmitter<?, ?> mapEmitter = mapJob.getValue();
MapReduce mapReduce = mapJob.getKey();
// sort results if a map output sort is defined
mapEmitter.complete(mapReduce);
if (mapReduce.doStage(MapReduce.Stage.REDUCE)) {
final FulgoraReduceEmitter<?, ?> reduceEmitter = new FulgoraReduceEmitter<>();
try (WorkerPool workers = new WorkerPool(numThreads)) {
workers.submit(() -> mapReduce.workerStart(MapReduce.Stage.REDUCE));
for (final Map.Entry queueEntry : mapEmitter.reduceMap.entrySet()) {
workers.submit(() -> mapReduce.reduce(queueEntry.getKey(), ((Iterable) queueEntry.getValue()).iterator(), reduceEmitter));
}
workers.submit(() -> mapReduce.workerEnd(MapReduce.Stage.REDUCE));
} catch (Exception e) {
throw new TitanException("Exception while executing reduce phase", e);
}
// mapEmitter.reduceMap.entrySet().parallelStream().forEach(entry -> mapReduce.reduce(entry.getKey(), entry.getValue().iterator(), reduceEmitter));
// sort results if a reduce output sort is defined
reduceEmitter.complete(mapReduce);
mapReduce.addResultToMemory(this.memory, reduceEmitter.reduceQueue.iterator());
} else {
mapReduce.addResultToMemory(this.memory, mapEmitter.mapQueue.iterator());
}
}
// #### Write mutated properties back into graph
Graph resultgraph = graph;
if (persistMode == Persist.NOTHING && resultGraphMode == ResultGraph.NEW) {
resultgraph = EmptyGraph.instance();
} else if (persistMode != Persist.NOTHING && vertexProgram != null && !vertexProgram.getElementComputeKeys().isEmpty()) {
//First, create property keys in graph if they don't already exist
TitanManagement mgmt = graph.openManagement();
try {
for (String key : vertexProgram.getElementComputeKeys()) {
if (!mgmt.containsPropertyKey(key))
log.warn("Property key [{}] is not part of the schema and will be created. It is advised to initialize all keys.", key);
mgmt.getOrCreatePropertyKey(key);
}
mgmt.commit();
} finally {
if (mgmt != null && mgmt.isOpen())
mgmt.rollback();
}
//TODO: Filter based on VertexProgram
Map<Long, Map<String, Object>> mutatedProperties = Maps.transformValues(vertexMemory.getMutableVertexProperties(), new Function<Map<String, Object>, Map<String, Object>>() {
@Nullable
@Override
public Map<String, Object> apply(@Nullable Map<String, Object> o) {
return Maps.filterKeys(o, s -> !NON_PERSISTING_KEYS.contains(s));
}
});
if (resultGraphMode == ResultGraph.ORIGINAL) {
AtomicInteger failures = new AtomicInteger(0);
try (WorkerPool workers = new WorkerPool(numThreads)) {
List<Map.Entry<Long, Map<String, Object>>> subset = new ArrayList<>(writeBatchSize / vertexProgram.getElementComputeKeys().size());
int currentSize = 0;
for (Map.Entry<Long, Map<String, Object>> entry : mutatedProperties.entrySet()) {
subset.add(entry);
currentSize += entry.getValue().size();
if (currentSize >= writeBatchSize) {
workers.submit(new VertexPropertyWriter(subset, failures));
subset = new ArrayList<>(subset.size());
currentSize = 0;
}
}
if (!subset.isEmpty())
workers.submit(new VertexPropertyWriter(subset, failures));
} catch (Exception e) {
throw new TitanException("Exception while attempting to persist result into graph", e);
}
if (failures.get() > 0)
throw new TitanException("Could not persist program results to graph. Check log for details.");
} else if (resultGraphMode == ResultGraph.NEW) {
resultgraph = graph.newTransaction();
for (Map.Entry<Long, Map<String, Object>> vprop : mutatedProperties.entrySet()) {
Vertex v = resultgraph.vertices(vprop.getKey()).next();
for (Map.Entry<String, Object> prop : vprop.getValue().entrySet()) {
v.property(VertexProperty.Cardinality.single, prop.getKey(), prop.getValue());
}
}
}
}
// update runtime and return the newly computed graph
this.memory.setRuntime(System.currentTimeMillis() - time);
this.memory.complete();
return new DefaultComputerResult(resultgraph, this.memory);
});
}
use of com.thinkaurelius.titan.core.schema.TitanManagement in project titan by thinkaurelius.
the class SerializerGraphConfiguration method testOnlyRegisteredSerialization.
@Test
public void testOnlyRegisteredSerialization() {
TitanManagement mgmt = graph.openManagement();
PropertyKey time = mgmt.makePropertyKey("time").dataType(Integer.class).make();
PropertyKey any = mgmt.makePropertyKey("any").cardinality(Cardinality.LIST).dataType(Object.class).make();
mgmt.buildIndex("byTime", Vertex.class).addKey(time).buildCompositeIndex();
EdgeLabel knows = mgmt.makeEdgeLabel("knows").make();
VertexLabel person = mgmt.makeVertexLabel("person").make();
mgmt.commit();
TitanTransaction tx = graph.newTransaction();
TitanVertex v = tx.addVertex("person");
v.property("time", 5);
v.property("any", new Double(5.0));
v.property("any", new TClass1(5, 1.5f));
v.property("any", TEnum.THREE);
tx.commit();
tx = graph.newTransaction();
v = tx.query().has("time", 5).vertices().iterator().next();
assertEquals(5, (int) v.value("time"));
assertEquals(3, Iterators.size(v.properties("any")));
tx.rollback();
//Verify that non-registered objects aren't allowed
for (Object o : new Object[] { new TClass2("abc", 5) }) {
tx = graph.newTransaction();
v = tx.addVertex("person");
try {
//Should not be allowed
v.property("any", o);
tx.commit();
fail();
} catch (IllegalArgumentException e) {
} finally {
if (tx.isOpen())
tx.rollback();
}
}
}
use of com.thinkaurelius.titan.core.schema.TitanManagement in project titan by thinkaurelius.
the class TitanGraphTest method setAndCheckGraphOption.
private <T> void setAndCheckGraphOption(ConfigOption<T> opt, ConfigOption.Type requiredType, T firstValue, T secondValue) {
// Sanity check: make sure the Type of the configoption is what we expect
Preconditions.checkState(opt.getType().equals(requiredType));
final EnumSet<ConfigOption.Type> allowedTypes = EnumSet.of(ConfigOption.Type.GLOBAL, ConfigOption.Type.GLOBAL_OFFLINE, ConfigOption.Type.MASKABLE);
Preconditions.checkState(allowedTypes.contains(opt.getType()));
// Sanity check: it's kind of pointless for the first and second values to be identical
Preconditions.checkArgument(!firstValue.equals(secondValue));
// Get full string path of config option
final String path = ConfigElement.getPath(opt);
// Set and check initial value before and after database restart
mgmt.set(path, firstValue);
assertEquals(firstValue.toString(), mgmt.get(path));
// Close open tx first. This is specific to BDB + GLOBAL_OFFLINE.
// Basically: the BDB store manager throws a fit if shutdown is called
// with one or more transactions still open, and GLOBAL_OFFLINE calls
// shutdown on our behalf when we commit this change.
tx.rollback();
mgmt.commit();
clopen();
// Close tx again following clopen
tx.rollback();
assertEquals(firstValue.toString(), mgmt.get(path));
// Set and check updated value before and after database restart
mgmt.set(path, secondValue);
assertEquals(secondValue.toString(), mgmt.get(path));
mgmt.commit();
clopen();
tx.rollback();
assertEquals(secondValue.toString(), mgmt.get(path));
// Open a separate graph "g2"
TitanGraph g2 = TitanFactory.open(config);
TitanManagement m2 = g2.openManagement();
assertEquals(secondValue.toString(), m2.get(path));
// GLOBAL_OFFLINE options should be unmodifiable with g2 open
if (opt.getType().equals(ConfigOption.Type.GLOBAL_OFFLINE)) {
try {
mgmt.set(path, firstValue);
mgmt.commit();
fail("Option " + path + " with type " + ConfigOption.Type.GLOBAL_OFFLINE + " should not be modifiable with concurrent instances");
} catch (RuntimeException e) {
log.debug("Caught expected exception", e);
}
assertEquals(secondValue.toString(), mgmt.get(path));
// GLOBAL and MASKABLE should be modifiable even with g2 open
} else {
mgmt.set(path, firstValue);
assertEquals(firstValue.toString(), mgmt.get(path));
mgmt.commit();
clopen();
assertEquals(firstValue.toString(), mgmt.get(path));
}
m2.rollback();
g2.close();
}
Aggregations