/* * Copyright 2015-2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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.hawkular.inventory.impl.tinkerpop.provider; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import org.apache.commons.configuration.MapConfiguration; import org.apache.tinkerpop.gremlin.process.computer.GraphComputer; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Element; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Transaction; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.io.Io; import org.apache.tinkerpop.gremlin.structure.util.AbstractTransaction; import org.apache.tinkerpop.gremlin.structure.util.wrapped.WrappedGraph; import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph; import org.hawkular.inventory.api.Configuration; import org.hawkular.inventory.impl.tinkerpop.spi.GraphProvider; import org.hawkular.inventory.impl.tinkerpop.spi.IndexSpec; /** * @author Lukas Krejci * @since 0.0.1 */ public final class TinkerGraphProvider implements GraphProvider { private final boolean prefersBigTxs; public TinkerGraphProvider() { String val = System.getProperty("TinkerGraphProvider.prefersBigTxs"); prefersBigTxs = val == null || Boolean.parseBoolean(val); } @Override public boolean isUniqueIndexSupported() { return false; } @Override public boolean needsDraining() { return false; } @Override public boolean isPreferringBigTransactions() { //just for testing purposes... Otherwise tinkergraph doesn't actually care about this because it doesn't //support transactions anyway. return prefersBigTxs; } @Override public WrappedTinkerGraph instantiateGraph(Configuration configuration) { return new WrappedTinkerGraph(new MapConfiguration( configuration.getImplementationConfiguration( Collections.singleton(PropertyKey.DIRECTORY_NAME)))); } @Override public void ensureIndices(Graph graph, IndexSpec... indexSpecs) { //don't bother with this for a demo graph } private static final class WrappedTinkerGraph implements Graph, WrappedGraph<TinkerGraph> { private final TinkerGraph graph; private final AtomicBoolean inTx = new AtomicBoolean(false); WrappedTinkerGraph(org.apache.commons.configuration.Configuration configuration) { graph = TinkerGraph.open(configuration); } @Override public TinkerGraph getBaseGraph() { return graph; } public <E extends Element> void createIndex(String key, Class<E> elementClass) { graph.createIndex(key, elementClass); } public <E extends Element> void dropIndex(String key, Class<E> elementClass) { graph.dropIndex(key, elementClass); } public static TinkerGraph open() { return TinkerGraph.open(); } public void clear() { graph.clear(); } public static TinkerGraph open(org.apache.commons.configuration.Configuration configuration) { return TinkerGraph.open(configuration); } public <E extends Element> Set<String> getIndexedKeys( Class<E> elementClass) { return graph.getIndexedKeys(elementClass); } @Override public Vertex addVertex(Object... keyValues) { return graph.addVertex(keyValues); } @Override public void close() { graph.close(); } @Override public GraphComputer compute() { return graph.compute(); } @Override public <C extends GraphComputer> C compute( Class<C> graphComputerClass) { return graph.compute(graphComputerClass); } @Override public org.apache.commons.configuration.Configuration configuration() { return graph.configuration(); } @Override public Iterator<Edge> edges(Object... edgeIds) { return graph.edges(edgeIds); } @Override public Features features() { return graph.features(); } @Override public String toString() { return graph.toString(); } @Override public Transaction tx() { return new AbstractTransaction(this) { @Override protected void doOpen() { if (!inTx.compareAndSet(false, true)) { throw new IllegalStateException("Nested transaction detected"); } } @Override protected void doCommit() throws TransactionException { if (!inTx.compareAndSet(true, false)) { throw new IllegalStateException("No transaction active"); } } @Override protected void doRollback() throws TransactionException { if (!inTx.compareAndSet(true, false)) { throw new IllegalStateException("No transaction active"); } } @Override protected void doClose() { inTx.set(false); } @Override protected void doReadWrite() { } @Override protected void fireOnCommit() { } @Override protected void fireOnRollback() { } @Override public Transaction onReadWrite(Consumer<Transaction> consumer) { return this; } @Override public Transaction onClose(Consumer<Transaction> consumer) { return this; } @Override public void addTransactionListener(Consumer<Status> listener) { } @Override public void removeTransactionListener(Consumer<Status> listener) { } @Override public void clearTransactionListeners() { } @Override public boolean isOpen() { return inTx.get(); } }; } @Override public Variables variables() { return graph.variables(); } @Override public Iterator<Vertex> vertices(Object... vertexIds) { return graph.vertices(vertexIds); } @Override public Vertex addVertex(String label) { return graph.addVertex(label); } @Override public <I extends Io> I io( Io.Builder<I> builder) { return graph.io(builder); } @Override public GraphTraversalSource traversal() { return graph.traversal(); } @Override public <C extends TraversalSource> C traversal( TraversalSource.Builder<C> sourceBuilder) { return graph.traversal(sourceBuilder); } } private enum PropertyKey implements Configuration.Property { DIRECTORY_NAME("blueprints.tg.directory", "blueprints.tg.directory", null); private final String propertyName; private final List<String> sysPropName; private final List<String> envVarName; PropertyKey(String propertyName, String sysPropName, String envVarName) { this.envVarName = envVarName == null ? Collections.emptyList() : Collections.singletonList(envVarName); this.propertyName = propertyName; this.sysPropName = sysPropName == null ? Collections.emptyList() : Collections.singletonList(sysPropName); } @Override public String getPropertyName() { return propertyName; } @Override public List<String> getSystemPropertyNames() { return sysPropName; } @Override public List<String> getEnvironmentVariableNames() { return envVarName; } } }