Commit 5ba64a8b by Sarath Subramanian Committed by Madhan Neethiraj

ATLAS-2308: Remove 'titan1' graph provider from atlas

parent acb34ca7
......@@ -31,17 +31,13 @@
<name>Apache Atlas Graph Database Projects</name>
<packaging>pom</packaging>
<!-- Build all modules including all the possible graph providers although only one will be used -->
<modules>
<module>api</module>
<module>common</module>
<module>graphdb-impls</module>
<module>titan0</module>
<module>titan1</module>
<module>janus</module>
</modules>
</project>
......@@ -2,30 +2,26 @@
Building with a chosen graph database
=====================================
The Atlas build is currently set up to include one of the graph backends in the Atlas war file.
The choice of graph backend is determined by the setting of the GRAPH-PROVIDER system variable.
If GRAPH-PROVIDER is not set, the default graph backend is adopted. This is currently Titan 0.5.4.
If GRAPH-PROVIDER is not set, the default graph backend is adopted. This is currently JanusGraph 0.2.0
In order to build with a specific (non-default) graph backend set the GRAPH-PROVDER system variable.
If GRAPH-PROVIDER is set to titan0, the build will contain Titan 0.5.4 (i.e. the default above)
If GRAPH-PROVIDER is set to titan1, the build will contain Titan 1.0.0
If GRAPH-PROVIDER is set to janus, the build will contain JanusGraph 0.1.1
If GRAPH-PROVIDER is set to titan0, the build will contain Titan 0.5.4
If GRAPH-PROVIDER is set to janus, the build will contain JanusGraph 0.2.0 (i.e. the default above)
For example, to build Atlas with the janus graph-provider:
mvn install [-P dist] -DGRAPH-PROVIDER=janus
Titan 0.5.4 supports Gremlin2 only, whereas Titan 1.0.0 and JanusGraph support Gremlin3 only (and NOT Gremlin2).
Titan 0.5.4 supports Gremlin2 only, whereas JanusGraph support Gremlin3 only (and NOT Gremlin2).
Gremlin2 and Gremlin3 are not compatible. The gremlin used by Atlas is translated into either Gremlin2 or
Gremlin3 depending on which graph backend is used in the build. This is implemented in GremlinExpressionFactory.
REQUIREMENTS
------------
Titan 1.0.0 and JanusGraph 0.1.1 require Java 8 to be used both when building and running Atlas.
JanusGraph 0.2.0 require Java 8 to be used both when building and running Atlas.
Unless Java 8 is used, the janus module will not be built - this is checked by the maven-enforcer-plugin.
==================
Titan 1.0.0 README
==================
IMPORTANT: Titan 1 support in Atlas is currently a work in progress.
ARCHITECTURE NOTES
------------------
The build is currently set up to include only one of the graph backends in the Atlas war file. The configured graph
backend is determined by maven profile. The default profile is titan0. To build Atlas configured to run against Titan 1,
the titan1 profile must be enabled. Titan1 project has support for Gremlin3. Gremlin Translator translates the DSL to
gremlin3 compliant syntax when titan1 is configured as backend graph db.
REQUIREMENTS
--------------
Titan 1 requires Java 8 to be used both when building and running Atlas. While building on Java7, the java classes in
the Titan 1 project are not compiled. But an empty jar is produced. If java 8 is used, then titan 1 classes are compiled
but tests are only executed if titan1 profile is explicitly enabled.
USING ATLAS WITH TITAN 1
------------------------
1) Build Atlas with the titan1 maven profile enabled:
mvn install -P dist -P titan1
Note that there are some tests in repository and webapp project which are skipped when running with the titan1 profile.
Please refer to known issues section below.
This will build Atlas and run all of the tests against Titan 1. Only Atlas builds that were generated with the titan1
maven profile enabled can be used to use Atlas with Titan 1.
2) Configure the Atlas runtime to use Titan 1 by setting the atlas.graphdb.backend property in
ATLAS_HOME/conf/atlas-application.properties, as follows:
atlas.graphdb.backend=org.apache.atlas.repository.graphdb.titan1.Titan1GraphDatabase
3) Attempt to start the Atlas server. NOTE: As of this writing, Atlas fails to start (see issue 2 below).
KNOWN ISSUES
------------
1) EntityLineageService is hard-coded to generate Gremlin that is specific to Tinker Pop 2. It needs to be updated to
use GremlinExpressionFactory to generate Gremlin that is appropriate for the version of Titan being used. Currently
these tests are skipped when the titan1 profile is enabled.
https://issues.apache.org/jira/browse/ATLAS-1579
2) Catalog project is hard-coded to generate Gremlin that is specific to Tinker Pop 2. It needs to be updated to use
GremlinExpressionFactory to generate Gremlin that is appropriate for the version of Titan being used. In addition, it
has direct dependencies on titan 0 / Tinker Pop 2 classes.
https://issues.apache.org/jira/browse/ATLAS-1580
3) The Atlas war file startup is currently failing when Titan1 is being used. Due to the titan 0 dependencies in
catalog, the catalog jar is currently being excluded from webapp when titan1 is being used. However, Atlas appears to
have runtime dependencies on the stuff in Catalog. The war startup currently fails with the following exception:
Caused by: java.lang.ClassNotFoundException: org.apache.atlas.catalog.exception.CatalogException
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
https://issues.apache.org/jira/browse/ATLAS-1581
4) There are some known test failures in webapp project. Those need to be addressed. There is work needed to refactor
webapp so that it can function without catalog until issue #2 above is resolved.
https://issues.apache.org/jira/browse/ATLAS-1582
5) We cannot bundle both titan0 and titan1 in the Atlas war file because titan1 and titan0 require different versions of
the same libraries. We cannot have multiple versions of the same library on the classpath. Another issue there is that
Gremin queries are executed via the java services mechanism. Specifically, the titan 1 implemention bundles a file
called javax.script.ScriptingEngineFactory, which tells Java to
use org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineFactory. We cannot have this file on the
classpath when using titan 0 since it would cause the Titan 0 implemention to try to execute queries using TP 3. There
may be ways of working around this, such as making Titan1Graph and Titan0Graph explicitly instantiate the
GremlinGroovyScriptEngineFactory. This was not investigated very much, though. If we combine that with shading
Titan0/1 and all of their dependencies, we might be able to bundle both the Titan 1 and Titan 0 implementations in the
Atlas war file and have things work correctly for both versions. Another possibility would be to use a custom
classloader to load the correct atlas-graphdb-titan0/1 jar during Atlas startup based on the configuration.
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import com.thinkaurelius.titan.core.EdgeLabel;
import org.apache.atlas.repository.graphdb.AtlasCardinality;
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
import org.apache.atlas.repository.graphdb.titan1.query.Titan1GraphQuery;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import com.thinkaurelius.titan.core.Cardinality;
import com.thinkaurelius.titan.core.PropertyKey;
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
/**
* Factory that serves up instances of graph database abstraction layer classes
* that correspond to Titan/Tinkerpop3 classes.
*/
public final class GraphDbObjectFactory {
private GraphDbObjectFactory() {
}
/**
* Creates a Titan1Edge that corresponds to the given Gremlin Edge.
*
* @param graph The graph the edge should be created in
* @param source The gremlin edge
*/
public static Titan1Edge createEdge(Titan1Graph graph, Edge source) {
if (source == null) {
return null;
}
return new Titan1Edge(graph, source);
}
/**
* Creates a Titan1GraphQuery that corresponds to the given GraphQuery.
*
* @param graph the graph that is being quried
*/
public static Titan1GraphQuery createQuery(Titan1Graph graph, boolean isChildQuery) {
return new Titan1GraphQuery(graph, isChildQuery);
}
/**
* Creates a Titan1Vertex that corresponds to the given Gremlin Vertex.
*
* @param graph The graph that contains the vertex
* @param source the Gremlin vertex
*/
public static Titan1Vertex createVertex(Titan1Graph graph, Vertex source) {
if (source == null) {
return null;
}
return new Titan1Vertex(graph, source);
}
/**
* @param propertyKey The Gremlin propertyKey.
*
*/
public static Titan1PropertyKey createPropertyKey(PropertyKey propertyKey) {
if (propertyKey == null) {
return null;
}
return new Titan1PropertyKey(propertyKey);
}
/**
* @param label The Gremlin propertyKey.
*
*/
public static Titan1EdgeLabel createEdgeLabel(EdgeLabel label) {
if (label == null) {
return null;
}
return new Titan1EdgeLabel(label);
}
/**
* @param index The gremlin index.
* @return
*/
public static AtlasGraphIndex createGraphIndex(TitanGraphIndex index) {
if (index == null) {
return null;
}
return new Titan1GraphIndex(index);
}
/**
* Converts a Multiplicity to a Cardinality.
*
* @param cardinality
* @return
*/
public static AtlasCardinality createCardinality(Cardinality cardinality) {
if (cardinality == Cardinality.SINGLE) {
return AtlasCardinality.SINGLE;
} else if (cardinality == Cardinality.LIST) {
return AtlasCardinality.LIST;
}
return AtlasCardinality.SET;
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.tinkerpop.gremlin.structure.Edge;
/**
* Titan 1.0.0 implementation of AtlasEdge.
*/
public class Titan1Edge extends Titan1Element<Edge> implements AtlasEdge<Titan1Vertex, Titan1Edge> {
public Titan1Edge(Titan1Graph graph, Edge edge) {
super(graph, edge);
}
@Override
public String getLabel() {
return getWrappedElement().label();
}
@Override
public Titan1Edge getE() {
return this;
}
@Override
public AtlasVertex<Titan1Vertex, Titan1Edge> getInVertex() {
return GraphDbObjectFactory.createVertex(graph, getWrappedElement().inVertex());
}
@Override
public AtlasVertex<Titan1Vertex, Titan1Edge> getOutVertex() {
return GraphDbObjectFactory.createVertex(graph, getWrappedElement().outVertex());
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import com.thinkaurelius.titan.core.EdgeLabel;
import org.apache.atlas.repository.graphdb.AtlasEdgeLabel;
/**
*
*/
public class Titan1EdgeLabel implements AtlasEdgeLabel {
private final EdgeLabel wrapped;
public Titan1EdgeLabel(EdgeLabel toWrap) {
wrapped = toWrap;
}
/* (non-Javadoc)
* @see org.apache.atlas.repository.graphdb.AtlasPropertyKey#getName()
*/
@Override
public String getName() {
return wrapped.name();
}
@Override
public int hashCode() {
int result = 17;
result = 37*result + wrapped.hashCode();
return result;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Titan1EdgeLabel)) {
return false;
}
Titan1EdgeLabel otherKey = (Titan1EdgeLabel)other;
return otherKey.wrapped.equals(wrapped);
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasElement;
import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.graphdb.titan1.graphson.AtlasGraphSONMode;
import org.apache.atlas.repository.graphdb.titan1.graphson.AtlasGraphSONUtility;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Property;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.thinkaurelius.titan.core.SchemaViolationException;
import com.thinkaurelius.titan.core.TitanElement;
/**
* Titan 1.0.0 implementation of AtlasElement.
*
* @param <T> the implementation class of the wrapped Titan 1 element
* that is stored.
*/
public class Titan1Element<T extends Element> implements AtlasElement {
private T element;
protected Titan1Graph graph;
public Titan1Element(Titan1Graph graph, T element) {
this.element = element;
this.graph = graph;
}
@Override
public <T> T getProperty(String propertyName, Class<T> clazz) {
//add explicit logic to return null if the property does not exist
//This is the behavior Atlas expects. Titan 1 throws an exception
//in this scenario.
Property p = getWrappedElement().property(propertyName);
if (p.isPresent()) {
Object propertyValue= p.value();
if (propertyValue == null) {
return null;
}
if (AtlasEdge.class == clazz) {
return (T)graph.getEdge(propertyValue.toString());
}
if (AtlasVertex.class == clazz) {
return (T)graph.getVertex(propertyValue.toString());
}
return (T)propertyValue;
}
return null;
}
/**
* Gets all of the values of the given property.
* @param propertyName
* @return
*/
@Override
public <T> Collection<T> getPropertyValues(String propertyName, Class<T> type) {
return Collections.singleton(getProperty(propertyName, type));
}
@Override
public Set<String> getPropertyKeys() {
return getWrappedElement().keys();
}
@Override
public void removeProperty(String propertyName) {
Iterator<? extends Property<String>> it = getWrappedElement().properties(propertyName);
while(it.hasNext()) {
Property<String> property = it.next();
property.remove();
}
}
@Override
public void setProperty(String propertyName, Object value) {
try {
getWrappedElement().property(propertyName, value);
} catch(SchemaViolationException e) {
throw new AtlasSchemaViolationException(e);
}
}
@Override
public Object getId() {
return element.id();
}
@Override
public T getWrappedElement() {
return element;
}
@Override
public JSONObject toJson(Set<String> propertyKeys) throws JSONException {
return AtlasGraphSONUtility.jsonFromElement(this, propertyKeys, AtlasGraphSONMode.NORMAL);
}
@Override
public int hashCode() {
int result = 37;
result = 17*result + getClass().hashCode();
result = 17*result + getWrappedElement().hashCode();
return result;
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (other.getClass() != getClass()) {
return false;
}
Titan1Element otherElement = (Titan1Element) other;
return getWrappedElement().equals(otherElement.getWrappedElement());
}
@Override
public List<String> getListProperty(String propertyName) {
List<String> value = getProperty(propertyName, List.class);
if (value == null) {
return Collections.emptyList();
}
return value;
}
@Override
public void setListProperty(String propertyName, List<String> values) {
setProperty(propertyName, values);
}
@Override
public boolean exists() {
try {
return !((TitanElement)element).isRemoved();
} catch(IllegalStateException e) {
return false;
}
}
@Override
public <T> void setJsonProperty(String propertyName, T value) {
setProperty(propertyName, value);
}
@Override
public <T> T getJsonProperty(String propertyName) {
return (T)getProperty(propertyName, String.class);
}
@Override
public String getIdForDisplay() {
return getId().toString();
}
@Override
public <V> List<V> getListProperty(String propertyName, Class<V> elementType) {
List<String> value = getListProperty(propertyName);
if (value.isEmpty()) {
return (List<V>)value;
}
if (AtlasEdge.class.isAssignableFrom(elementType)) {
return (List<V>)Lists.transform(value, new Function<String, AtlasEdge>(){
@Override
public AtlasEdge apply(String input) {
return graph.getEdge(input);
}
});
}
if (AtlasVertex.class.isAssignableFrom(elementType)) {
return (List<V>)Lists.transform(value, new Function<String, AtlasVertex>(){
@Override
public AtlasVertex apply(String input) {
return graph.getVertex(input);
}
});
}
return (List<V>)value;
}
@Override
public void setPropertyFromElementsIds(String propertyName, List<AtlasElement> values) {
List<String> propertyValue = new ArrayList<>(values.size());
for(AtlasElement value: values) {
propertyValue.add(value.getId().toString());
}
setProperty(propertyName, propertyValue);
}
@Override
public void setPropertyFromElementId(String propertyName, AtlasElement value) {
setProperty(propertyName, value.getId().toString());
}
@Override
public boolean isIdAssigned() {
return true;
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.GraphDatabase;
import org.apache.atlas.repository.graphdb.titan1.serializer.BigDecimalSerializer;
import org.apache.atlas.repository.graphdb.titan1.serializer.BigIntegerSerializer;
import org.apache.atlas.repository.graphdb.titan1.serializer.StringListSerializer;
import org.apache.atlas.repository.graphdb.titan1.serializer.TypeCategorySerializer;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.commons.configuration.Configuration;
import org.apache.tinkerpop.gremlin.groovy.loaders.SugarLoader;
import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.thinkaurelius.titan.core.schema.TitanManagement;
import com.thinkaurelius.titan.core.util.TitanCleanup;
import com.thinkaurelius.titan.graphdb.tinkerpop.TitanIoRegistry;
/**
* Default implementation for Graph Provider that doles out Titan Graph.
*/
public class Titan1GraphDatabase implements GraphDatabase<Titan1Vertex, Titan1Edge> {
private static final Logger LOG = LoggerFactory.getLogger(Titan1GraphDatabase.class);
/**
* Constant for the configuration property that indicates the prefix.
*/
public static final String GRAPH_PREFIX = "atlas.graph";
public static final String INDEX_BACKEND_CONF = "index.search.backend";
public static final String INDEX_BACKEND_LUCENE = "lucene";
public static final String INDEX_BACKEND_ES = "elasticsearch";
private static volatile Titan1Graph atlasGraphInstance = null;
private static volatile TitanGraph graphInstance;
public Titan1GraphDatabase() {
//update registry
GraphSONMapper.build().addRegistry(TitanIoRegistry.INSTANCE).create();
}
public static Configuration getConfiguration() throws AtlasException {
Configuration configProperties = ApplicationProperties.get();
Configuration titanConfig = ApplicationProperties.getSubsetConfiguration(configProperties, GRAPH_PREFIX);
//add serializers for non-standard property value types that Atlas uses
titanConfig.addProperty("attributes.custom.attribute1.attribute-class", TypeCategory.class.getName());
titanConfig.addProperty("attributes.custom.attribute1.serializer-class",
TypeCategorySerializer.class.getName());
//not ideal, but avoids making large changes to Atlas
titanConfig.addProperty("attributes.custom.attribute2.attribute-class", ArrayList.class.getName());
titanConfig.addProperty("attributes.custom.attribute2.serializer-class", StringListSerializer.class.getName());
titanConfig.addProperty("attributes.custom.attribute3.attribute-class", BigInteger.class.getName());
titanConfig.addProperty("attributes.custom.attribute3.serializer-class", BigIntegerSerializer.class.getName());
titanConfig.addProperty("attributes.custom.attribute4.attribute-class", BigDecimal.class.getName());
titanConfig.addProperty("attributes.custom.attribute4.serializer-class", BigDecimalSerializer.class.getName());
return titanConfig;
}
public static TitanGraph getGraphInstance() {
if (graphInstance == null) {
synchronized (Titan1GraphDatabase.class) {
if (graphInstance == null) {
Configuration config;
try {
config = getConfiguration();
} catch (AtlasException e) {
throw new RuntimeException(e);
}
graphInstance = TitanFactory.open(config);
atlasGraphInstance = new Titan1Graph();
validateIndexBackend(config);
}
}
}
return graphInstance;
}
public static void unload() {
synchronized (Titan1GraphDatabase.class) {
if (graphInstance == null) {
return;
}
graphInstance.tx().commit();
graphInstance.close();
graphInstance = null;
}
}
static void validateIndexBackend(Configuration config) {
String configuredIndexBackend = config.getString(INDEX_BACKEND_CONF);
TitanManagement managementSystem = getGraphInstance().openManagement();
String currentIndexBackend = managementSystem.get(INDEX_BACKEND_CONF);
managementSystem.commit();
if (!configuredIndexBackend.equals(currentIndexBackend)) {
throw new RuntimeException("Configured Index Backend " + configuredIndexBackend
+ " differs from earlier configured Index Backend " + currentIndexBackend + ". Aborting!");
}
}
@Override
public boolean isGraphLoaded() {
return graphInstance != null;
}
@Override
public void initializeTestGraph() {
//nothing to do
}
@Override
public void cleanup() {
try {
getGraphInstance().close();
} catch (Throwable t) {
LOG.warn("Could not close test TitanGraph", t);
t.printStackTrace();
}
try {
TitanCleanup.clear(getGraphInstance());
} catch (Throwable t) {
LOG.warn("Could not clear test TitanGraph", t);
t.printStackTrace();
}
}
@Override
public AtlasGraph<Titan1Vertex, Titan1Edge> getGraph() {
getGraphInstance();
return atlasGraphInstance;
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import java.util.HashSet;
import java.util.Set;
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import com.thinkaurelius.titan.core.PropertyKey;
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
/**
* Represents an Index in Titan 1.
*/
public class Titan1GraphIndex implements AtlasGraphIndex {
private TitanGraphIndex wrapped;
public Titan1GraphIndex(TitanGraphIndex toWrap) {
this.wrapped = toWrap;
}
@Override
public boolean isEdgeIndex() {
return Edge.class.isAssignableFrom(wrapped.getIndexedElement());
}
@Override
public boolean isVertexIndex() {
return Vertex.class.isAssignableFrom(wrapped.getIndexedElement());
}
@Override
public boolean isUnique() {
return wrapped.isUnique();
}
@Override
public Set<AtlasPropertyKey> getFieldKeys() {
PropertyKey[] keys = wrapped.getFieldKeys();
Set<AtlasPropertyKey> result = new HashSet<AtlasPropertyKey>();
for(PropertyKey key : keys) {
result.add(GraphDbObjectFactory.createPropertyKey(key));
}
return result;
}
@Override
public int hashCode() {
int result = 17;
result = 37*result + wrapped.hashCode();
return result;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Titan1GraphIndex)) {
return false;
}
Titan1GraphIndex otherKey = (Titan1GraphIndex)other;
return otherKey.wrapped.equals(wrapped);
}
@Override
public boolean isMixedIndex() {
return wrapped.isMixedIndex();
}
@Override
public boolean isCompositeIndex() {
return wrapped.isCompositeIndex();
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import com.google.common.base.Preconditions;
import com.thinkaurelius.titan.core.Cardinality;
import com.thinkaurelius.titan.core.EdgeLabel;
import com.thinkaurelius.titan.core.PropertyKey;
import com.thinkaurelius.titan.core.schema.Mapping;
import com.thinkaurelius.titan.core.schema.PropertyKeyMaker;
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
import com.thinkaurelius.titan.core.schema.TitanManagement;
import com.thinkaurelius.titan.graphdb.internal.Token;
import org.apache.atlas.repository.graphdb.AtlasCardinality;
import org.apache.atlas.repository.graphdb.AtlasEdgeLabel;
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
import org.apache.commons.lang.StringUtils;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Titan 1.0.0 implementation of AtlasGraphManagement.
*/
public class Titan1GraphManagement implements AtlasGraphManagement {
private static final Logger LOG = LoggerFactory.getLogger(Titan1GraphManagement.class);
private static final char[] RESERVED_CHARS = { '{', '}', '"', '$', Token.SEPARATOR_CHAR };
private Titan1Graph graph;
private TitanManagement management;
private Set<String> newMultProperties = new HashSet<>();
public Titan1GraphManagement(Titan1Graph graph, TitanManagement managementSystem) {
this.management = managementSystem;
this.graph = graph;
}
@Override
public void createVertexIndex(String propertyName, String backingIndex, List<AtlasPropertyKey> propertyKeys) {
TitanManagement.IndexBuilder indexBuilder = management.buildIndex(propertyName, Vertex.class);
for (AtlasPropertyKey key : propertyKeys) {
PropertyKey titanKey = TitanObjectFactory.createPropertyKey(key);
indexBuilder.addKey(titanKey);
}
indexBuilder.buildMixedIndex(backingIndex);
}
@Override
public void createEdgeIndex(String index, String backingIndex) {
buildMixedIndex(index, Edge.class, backingIndex);
}
private void buildMixedIndex(String index, Class<? extends Element> titanClass, String backingIndex) {
management.buildIndex(index, titanClass).buildMixedIndex(backingIndex);
}
@Override
public void createFullTextIndex(String indexName, AtlasPropertyKey propertyKey, String backingIndex) {
PropertyKey fullText = TitanObjectFactory.createPropertyKey(propertyKey);
management.buildIndex(indexName, Vertex.class)
.addKey(fullText, com.thinkaurelius.titan.core.schema.Parameter.of("mapping", Mapping.TEXT))
.buildMixedIndex(backingIndex);
}
@Override
public boolean containsPropertyKey(String propertyName) {
return management.containsPropertyKey(propertyName);
}
@Override
public void rollback() {
management.rollback();
}
@Override
public void commit() {
graph.addMultiProperties(newMultProperties);
newMultProperties.clear();
management.commit();
}
private static void checkName(String name) {
//for some reason, name checking was removed from StandardPropertyKeyMaker.make()
//in titan 1. For consistency, do the check here.
Preconditions.checkArgument(StringUtils.isNotBlank(name), "Need to specify name");
for (char c : RESERVED_CHARS) {
Preconditions.checkArgument(name.indexOf(c) < 0, "Name can not contains reserved character %s: %s", c,
name);
}
}
@Override
public AtlasPropertyKey makePropertyKey(String propertyName, Class propertyClass, AtlasCardinality cardinality) {
if (cardinality.isMany()) {
newMultProperties.add(propertyName);
}
PropertyKeyMaker propertyKeyBuilder = management.makePropertyKey(propertyName).dataType(propertyClass);
if (cardinality != null) {
Cardinality titanCardinality = TitanObjectFactory.createCardinality(cardinality);
propertyKeyBuilder.cardinality(titanCardinality);
}
PropertyKey propertyKey = propertyKeyBuilder.make();
return GraphDbObjectFactory.createPropertyKey(propertyKey);
}
@Override
public AtlasEdgeLabel makeEdgeLabel(String label) {
EdgeLabel edgeLabel = management.makeEdgeLabel(label).make();
return GraphDbObjectFactory.createEdgeLabel(edgeLabel);
}
@Override
public void deletePropertyKey(String propertyKey) {
PropertyKey titanPropertyKey = management.getPropertyKey(propertyKey);
if (null == titanPropertyKey) return;
for (int i = 0;; i++) {
String deletedKeyName = titanPropertyKey + "_deleted_" + i;
if (null == management.getPropertyKey(deletedKeyName)) {
management.changeName(titanPropertyKey, deletedKeyName);
break;
}
}
}
@Override
public AtlasPropertyKey getPropertyKey(String propertyName) {
checkName(propertyName);
return GraphDbObjectFactory.createPropertyKey(management.getPropertyKey(propertyName));
}
@Override
public AtlasEdgeLabel getEdgeLabel(String label) {
return GraphDbObjectFactory.createEdgeLabel(management.getEdgeLabel(label));
}
public void createExactMatchVertexIndex(String propertyName, boolean enforceUniqueness,
List<AtlasPropertyKey> propertyKeys) {
TitanManagement.IndexBuilder indexBuilder = management.buildIndex(propertyName, Vertex.class);
for (AtlasPropertyKey key : propertyKeys) {
PropertyKey titanKey = TitanObjectFactory.createPropertyKey(key);
indexBuilder.addKey(titanKey);
}
if (enforceUniqueness) {
indexBuilder.unique();
}
indexBuilder.buildCompositeIndex();
}
@Override
public void addVertexIndexKey(String indexName, AtlasPropertyKey propertyKey) {
PropertyKey titanKey = TitanObjectFactory.createPropertyKey(propertyKey);
TitanGraphIndex vertexIndex = management.getGraphIndex(indexName);
management.addIndexKey(vertexIndex, titanKey);
}
@Override
public AtlasGraphIndex getGraphIndex(String indexName) {
TitanGraphIndex index = management.getGraphIndex(indexName);
return GraphDbObjectFactory.createGraphIndex(index);
}
@Override
public void createExactMatchIndex(String propertyName, boolean isUnique,
List<AtlasPropertyKey> propertyKeys) {
createExactMatchVertexIndex(propertyName, isUnique, propertyKeys);
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import java.util.Iterator;
import com.google.common.base.Preconditions;
import org.apache.atlas.repository.graphdb.AtlasIndexQuery;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import com.thinkaurelius.titan.core.TitanIndexQuery;
import com.thinkaurelius.titan.core.TitanVertex;
/**
* Titan 1.0.0 implementation of AtlasIndexQuery.
*/
public class Titan1IndexQuery implements AtlasIndexQuery<Titan1Vertex, Titan1Edge> {
private Titan1Graph graph;
private TitanIndexQuery query;
public Titan1IndexQuery(Titan1Graph graph, TitanIndexQuery query) {
this.query = query;
this.graph = graph;
}
@Override
public Iterator<Result<Titan1Vertex, Titan1Edge>> vertices() {
Iterator<TitanIndexQuery.Result<TitanVertex>> results = query.vertices().iterator();
Function<TitanIndexQuery.Result<TitanVertex>, Result<Titan1Vertex, Titan1Edge>> function =
new Function<TitanIndexQuery.Result<TitanVertex>, Result<Titan1Vertex, Titan1Edge>>() {
@Override
public Result<Titan1Vertex, Titan1Edge> apply(TitanIndexQuery.Result<TitanVertex> source) {
return new ResultImpl(source);
}
};
return Iterators.transform(results, function);
}
@Override
public Iterator<Result<Titan1Vertex, Titan1Edge>> vertices(int offset, int limit) {
Preconditions.checkArgument(offset >=0, "Index offset should be greater than or equals to 0");
Preconditions.checkArgument(limit >=0, "Index limit should be greater than or equals to 0");
Iterator<TitanIndexQuery.Result<TitanVertex>> results = query
.offset(offset)
.limit(limit)
.vertices().iterator();
Function<TitanIndexQuery.Result<TitanVertex>, Result<Titan1Vertex, Titan1Edge>> function =
new Function<TitanIndexQuery.Result<TitanVertex>, Result<Titan1Vertex, Titan1Edge>>() {
@Override
public Result<Titan1Vertex, Titan1Edge> apply(TitanIndexQuery.Result<TitanVertex> source) {
return new ResultImpl(source);
}
};
return Iterators.transform(results, function);
}
/**
* Titan 1.0.0 implementation of AtlasIndexQuery.Result.
*/
public final class ResultImpl implements AtlasIndexQuery.Result<Titan1Vertex, Titan1Edge> {
private TitanIndexQuery.Result<TitanVertex> source;
public ResultImpl(TitanIndexQuery.Result<TitanVertex> source) {
this.source = source;
}
@Override
public AtlasVertex<Titan1Vertex, Titan1Edge> getVertex() {
return GraphDbObjectFactory.createVertex(graph, source.getElement());
}
@Override
public double getScore() {
return source.getScore();
}
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import org.apache.atlas.repository.graphdb.AtlasCardinality;
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
import com.thinkaurelius.titan.core.PropertyKey;
/**
*
*/
public class Titan1PropertyKey implements AtlasPropertyKey {
private PropertyKey wrapped;
public Titan1PropertyKey(PropertyKey toWrap) {
wrapped = toWrap;
}
/* (non-Javadoc)
* @see org.apache.atlas.repository.graphdb.AtlasPropertyKey#getName()
*/
@Override
public String getName() {
return wrapped.name();
}
/**
* @return
*/
public PropertyKey getWrappedPropertyKey() {
return wrapped;
}
@Override
public int hashCode() {
int result = 17;
result = 37*result + wrapped.hashCode();
return result;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Titan1PropertyKey)) {
return false;
}
Titan1PropertyKey otherKey = (Titan1PropertyKey)other;
return otherKey.getWrappedPropertyKey().equals(getWrappedPropertyKey());
}
/* (non-Javadoc)
* @see org.apache.atlas.repository.graphdb.AtlasPropertyKey#getCardinality()
*/
@Override
public AtlasCardinality getCardinality() {
return GraphDbObjectFactory.createCardinality(wrapped.cardinality());
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.graphdb.AtlasVertexQuery;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import com.thinkaurelius.titan.core.SchemaViolationException;
import com.thinkaurelius.titan.core.TitanVertex;
/**
* Titan 1.0.0 implementation of AtlasVertex.
*/
public class Titan1Vertex extends Titan1Element<Vertex> implements AtlasVertex<Titan1Vertex, Titan1Edge> {
public Titan1Vertex(Titan1Graph graph, Vertex source) {
super(graph, source);
}
@Override
public <T> void addProperty(String propertyName, T value) {
try {
getWrappedElement().property(VertexProperty.Cardinality.set, propertyName, value);
} catch(SchemaViolationException e) {
throw new AtlasSchemaViolationException(e);
}
}
@Override
public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> getEdges(AtlasEdgeDirection dir, String edgeLabel) {
Direction d = TitanObjectFactory.createDirection(dir);
Iterator<Edge> edges = getWrappedElement().edges(d, edgeLabel);
return graph.wrapEdges(edges);
}
private TitanVertex getAsTitanVertex() {
return (TitanVertex)getWrappedElement();
}
@Override
public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> getEdges(AtlasEdgeDirection in) {
Direction d = TitanObjectFactory.createDirection(in);
Iterator<Edge> edges = getWrappedElement().edges(d);
return graph.wrapEdges(edges);
}
@Override
public <T> Collection<T> getPropertyValues(String propertyName, Class<T> clazz) {
Collection<T> result = new ArrayList<T>();
Iterator<VertexProperty<T>> it = getWrappedElement().properties(propertyName);
while(it.hasNext()) {
result.add(it.next().value());
}
return result;
}
@Override
public AtlasVertexQuery<Titan1Vertex, Titan1Edge> query() {
return new Titan1VertexQuery(graph, getAsTitanVertex().query());
}
@Override
public Titan1Vertex getV() {
return this;
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import com.google.common.base.Preconditions;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.graphdb.AtlasVertexQuery;
import com.thinkaurelius.titan.core.TitanVertexQuery;
/**
* Titan 1.0.0 implementation of AtlasVertexQuery.
*/
public class Titan1VertexQuery implements AtlasVertexQuery<Titan1Vertex, Titan1Edge> {
private Titan1Graph graph;
private TitanVertexQuery<?> query;
public Titan1VertexQuery(Titan1Graph graph, TitanVertexQuery<?> query) {
this.query = query;
this.graph = graph;
}
@Override
public AtlasVertexQuery<Titan1Vertex, Titan1Edge> direction(AtlasEdgeDirection queryDirection) {
query.direction(TitanObjectFactory.createDirection(queryDirection));
return this;
}
@Override
public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> vertices() {
Iterable vertices = query.vertices();
return graph.wrapVertices(vertices);
}
@Override
public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> vertices(int limit) {
Preconditions.checkArgument(limit >=0, "Limit should be greater than or equals to 0");
Iterable vertices = query.limit(limit).vertices();
return graph.wrapVertices(vertices);
}
@Override
public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> edges() {
Iterable edges = query.edges();
return graph.wrapEdges(edges);
}
@Override
public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> edges(int limit) {
Preconditions.checkArgument(limit >=0, "Limit should be greater than or equals to 0");
Iterable edges = query.limit(limit).edges();
return graph.wrapEdges(edges);
}
@Override
public long count() {
return query.count();
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import org.apache.atlas.repository.graphdb.AtlasCardinality;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
import org.apache.tinkerpop.gremlin.structure.Direction;
import com.thinkaurelius.titan.core.Cardinality;
import com.thinkaurelius.titan.core.PropertyKey;
/**
* Factory that serves up instances of Titan/Tinkerpop classes that correspond to
* graph database abstraction layer/Atlas classes.
*/
public final class TitanObjectFactory {
private TitanObjectFactory() {
}
/**
* Retrieves the titan direction corresponding to the given
* AtlasEdgeDirection.
*
* @param dir
* @return
*/
public static Direction createDirection(AtlasEdgeDirection dir) {
switch(dir) {
case IN:
return Direction.IN;
case OUT:
return Direction.OUT;
case BOTH:
return Direction.BOTH;
default:
throw new RuntimeException("Unrecognized direction: " + dir);
}
}
/**
* Converts a Multiplicity to a Cardinality.
*
* @param multiplicity
* @return
*/
public static Cardinality createCardinality(AtlasCardinality cardinality) {
switch(cardinality) {
case SINGLE:
return Cardinality.SINGLE;
case LIST:
return Cardinality.LIST;
case SET:
return Cardinality.SET;
default:
throw new IllegalStateException("Unrecognized cardinality: " + cardinality);
}
}
public static PropertyKey createPropertyKey(AtlasPropertyKey key) {
return ((Titan1PropertyKey)key).getWrappedPropertyKey();
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.graphson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Configure how the GraphSON utility treats edge and vertex properties.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public class AtlasElementPropertyConfig {
/**
* Rules for element properties.
*/
public enum ElementPropertiesRule {
INCLUDE, EXCLUDE
}
private final List<String> vertexPropertyKeys;
private final List<String> edgePropertyKeys;
private final ElementPropertiesRule vertexPropertiesRule;
private final ElementPropertiesRule edgePropertiesRule;
private final boolean normalized;
/**
* A configuration that includes all properties of vertices and edges.
*/
public static final AtlasElementPropertyConfig ALL_PROPERTIES = new AtlasElementPropertyConfig(null, null,
ElementPropertiesRule.INCLUDE, ElementPropertiesRule.INCLUDE, false);
public AtlasElementPropertyConfig(final Set<String> vertexPropertyKeys, final Set<String> edgePropertyKeys,
final ElementPropertiesRule vertexPropertiesRule, final ElementPropertiesRule edgePropertiesRule) {
this(vertexPropertyKeys, edgePropertyKeys, vertexPropertiesRule, edgePropertiesRule, false);
}
public AtlasElementPropertyConfig(final Set<String> vertexPropertyKeys, final Set<String> edgePropertyKeys,
final ElementPropertiesRule vertexPropertiesRule, final ElementPropertiesRule edgePropertiesRule,
final boolean normalized) {
this.vertexPropertiesRule = vertexPropertiesRule;
this.vertexPropertyKeys = sortKeys(vertexPropertyKeys, normalized);
this.edgePropertiesRule = edgePropertiesRule;
this.edgePropertyKeys = sortKeys(edgePropertyKeys, normalized);
this.normalized = normalized;
}
/**
* Construct a configuration that includes the specified properties from
* both vertices and edges.
*/
public static AtlasElementPropertyConfig includeProperties(final Set<String> vertexPropertyKeys,
final Set<String> edgePropertyKeys) {
return new AtlasElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.INCLUDE,
ElementPropertiesRule.INCLUDE);
}
public static AtlasElementPropertyConfig includeProperties(final Set<String> vertexPropertyKeys,
final Set<String> edgePropertyKeys,
final boolean normalized) {
return new AtlasElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.INCLUDE,
ElementPropertiesRule.INCLUDE, normalized);
}
/**
* Construct a configuration that excludes the specified properties from
* both vertices and edges.
*/
public static AtlasElementPropertyConfig excludeProperties(final Set<String> vertexPropertyKeys,
final Set<String> edgePropertyKeys) {
return new AtlasElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.EXCLUDE,
ElementPropertiesRule.EXCLUDE);
}
public static AtlasElementPropertyConfig excludeProperties(final Set<String> vertexPropertyKeys,
final Set<String> edgePropertyKeys,
final boolean normalized) {
return new AtlasElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.EXCLUDE,
ElementPropertiesRule.EXCLUDE, normalized);
}
public List<String> getVertexPropertyKeys() {
return vertexPropertyKeys;
}
public List<String> getEdgePropertyKeys() {
return edgePropertyKeys;
}
public ElementPropertiesRule getVertexPropertiesRule() {
return vertexPropertiesRule;
}
public ElementPropertiesRule getEdgePropertiesRule() {
return edgePropertiesRule;
}
public boolean isNormalized() {
return normalized;
}
private static List<String> sortKeys(final Set<String> keys, final boolean normalized) {
final List<String> propertyKeyList;
if (keys != null) {
if (normalized) {
final List<String> sorted = new ArrayList<String>(keys);
Collections.sort(sorted);
propertyKeyList = sorted;
} else {
propertyKeyList = new ArrayList<String>(keys);
}
} else {
propertyKeyList = null;
}
return propertyKeyList;
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.graphson;
/**
* Modes of operation of the GraphSONUtility.
*
* @author Stephen Mallette
*/
public enum AtlasGraphSONMode {
/**
* COMPACT constructs GraphSON on the assumption that all property keys
* are fair game for exclusion including _type, _inV, _outV, _label and _id.
* It is possible to write GraphSON that cannot be read back into Graph,
* if some or all of these keys are excluded.
*/
COMPACT,
/**
* NORMAL includes the _type field and JSON data typing.
*/
NORMAL,
/**
* EXTENDED includes the _type field and explicit data typing.
*/
EXTENDED
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.graphson;
/**
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
public final class AtlasGraphSONTokens {
private AtlasGraphSONTokens() {}
public static final String VERTEX = "vertex";
public static final String EDGE = "edge";
public static final String INTERNAL_ID = "_id";
public static final String INTERNAL_LABEL = "_label";
public static final String INTERNAL_TYPE = "_type";
public static final String INTERNAL_OUT_V = "_outV";
public static final String INTERNAL_IN_V = "_inV";
public static final String VALUE = "value";
public static final String TYPE = "type";
public static final String TYPE_LIST = "list";
public static final String TYPE_STRING = "string";
public static final String TYPE_DOUBLE = "double";
public static final String TYPE_INTEGER = "integer";
public static final String TYPE_FLOAT = "float";
public static final String TYPE_MAP = "map";
public static final String TYPE_BOOLEAN = "boolean";
public static final String TYPE_LONG = "long";
public static final String TYPE_SHORT = "short";
public static final String TYPE_BYTE = "byte";
public static final String TYPE_UNKNOWN = "unknown";
public static final String VERTICES = "vertices";
public static final String EDGES = "edges";
public static final String MODE = "mode";
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.query;
import com.thinkaurelius.titan.core.TitanEdge;
import com.thinkaurelius.titan.core.TitanGraphQuery;
import com.thinkaurelius.titan.core.TitanVertex;
import com.thinkaurelius.titan.core.attribute.Contain;
import com.thinkaurelius.titan.core.attribute.Text;
import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.MatchingOperator;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.QueryOperator;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.graphdb.tinkerpop.query.NativeTinkerpopGraphQuery;
import org.apache.atlas.repository.graphdb.titan1.Titan1Edge;
import org.apache.atlas.repository.graphdb.titan1.Titan1Graph;
import org.apache.atlas.repository.graphdb.titan1.Titan1GraphDatabase;
import org.apache.atlas.repository.graphdb.titan1.Titan1Vertex;
import org.apache.tinkerpop.gremlin.process.traversal.Compare;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import java.util.*;
/**
* Titan 1.0.0 implementation of NativeTinkerpopGraphQuery.
*/
public class NativeTitan1GraphQuery implements NativeTinkerpopGraphQuery<Titan1Vertex, Titan1Edge> {
private Titan1Graph graph;
private TitanGraphQuery<?> query;
public NativeTitan1GraphQuery(Titan1Graph graph) {
this.query = Titan1GraphDatabase.getGraphInstance().query();
this.graph = graph;
}
@Override
public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> vertices() {
Iterable<TitanVertex> it = query.vertices();
return graph.wrapVertices(it);
}
@Override
public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> edges() {
Iterable<TitanEdge> it = query.edges();
return graph.wrapEdges(it);
}
@Override
public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> vertices(int limit) {
Iterable<TitanVertex> it = query.limit(limit).vertices();
return graph.wrapVertices(it);
}
@Override
public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> vertices(int offset, int limit) {
List<Vertex> result = new ArrayList<>(limit);
Iterator<? extends Vertex> iter = query.limit(offset + limit).vertices().iterator();
for (long resultIdx = 0; iter.hasNext() && result.size() < limit; resultIdx++) {
if (resultIdx < offset) {
continue;
}
result.add(iter.next());
}
return graph.wrapVertices(result);
}
@Override
public void in(String propertyName, Collection<? extends Object> values) {
query.has(propertyName, Contain.IN, values);
}
@Override
public void has(String propertyName, QueryOperator op, Object value) {
TitanPredicate pred;
if (op instanceof ComparisionOperator) {
Compare c = getGremlinPredicate((ComparisionOperator) op);
pred = TitanPredicate.Converter.convert(c);
} else {
pred = getGremlinPredicate((MatchingOperator)op);
}
query.has(propertyName, pred, value);
}
private Text getGremlinPredicate(MatchingOperator op) {
switch (op) {
case CONTAINS:
return Text.CONTAINS;
case PREFIX:
return Text.PREFIX;
case SUFFIX:
return Text.CONTAINS_REGEX;
case REGEX:
return Text.REGEX;
default:
throw new RuntimeException("Unsupported matching operator:" + op);
}
}
private Compare getGremlinPredicate(ComparisionOperator op) {
switch (op) {
case EQUAL:
return Compare.eq;
case GREATER_THAN:
return Compare.gt;
case GREATER_THAN_EQUAL:
return Compare.gte;
case LESS_THAN:
return Compare.lt;
case LESS_THAN_EQUAL:
return Compare.lte;
case NOT_EQUAL:
return Compare.neq;
default:
throw new RuntimeException("Unsupported comparison operator:" + op);
}
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.query;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
import org.apache.atlas.repository.graphdb.tinkerpop.query.TinkerpopGraphQuery;
import org.apache.atlas.repository.graphdb.tinkerpop.query.NativeTinkerpopGraphQuery;
import org.apache.atlas.repository.graphdb.tinkerpop.query.NativeTinkerpopQueryFactory;
import org.apache.atlas.repository.graphdb.titan1.Titan1Edge;
import org.apache.atlas.repository.graphdb.titan1.Titan1Graph;
import org.apache.atlas.repository.graphdb.titan1.Titan1Vertex;
/**
* Titan 1.0.0 implementation of TitanGraphQuery.
*/
public class Titan1GraphQuery extends TinkerpopGraphQuery<Titan1Vertex, Titan1Edge>
implements NativeTinkerpopQueryFactory<Titan1Vertex, Titan1Edge> {
public Titan1GraphQuery(Titan1Graph graph, boolean isChildQuery) {
super(graph, isChildQuery);
}
public Titan1GraphQuery(Titan1Graph graph) {
super(graph);
}
@Override
public AtlasGraphQuery<Titan1Vertex, Titan1Edge> createChildQuery() {
return new Titan1GraphQuery((Titan1Graph) graph, true);
}
@Override
protected NativeTinkerpopQueryFactory<Titan1Vertex, Titan1Edge> getQueryFactory() {
return this;
}
@Override
public NativeTinkerpopGraphQuery<Titan1Vertex, Titan1Edge> createNativeTinkerpopQuery() {
return new NativeTitan1GraphQuery((Titan1Graph) graph);
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.serializer;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.thinkaurelius.titan.core.attribute.AttributeSerializer;
import com.thinkaurelius.titan.diskstorage.ScanBuffer;
import com.thinkaurelius.titan.diskstorage.WriteBuffer;
/**
* Serializer for BigDecimal values.
*/
public class BigDecimalSerializer implements AttributeSerializer<BigDecimal> {
private final BigIntegerSerializer bigIntegerDelegate = new BigIntegerSerializer();
@Override
public BigDecimal read(ScanBuffer buffer) {
BigInteger unscaledVal = bigIntegerDelegate.read(buffer);
int scale = buffer.getInt();
return new BigDecimal(unscaledVal, scale);
}
@Override
public void write(WriteBuffer buffer, BigDecimal attribute) {
BigInteger unscaledVal = attribute.unscaledValue();
int scale = attribute.scale();
bigIntegerDelegate.write(buffer, unscaledVal);
buffer.putInt(scale);
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.serializer;
import java.math.BigInteger;
import com.thinkaurelius.titan.core.attribute.AttributeSerializer;
import com.thinkaurelius.titan.diskstorage.ScanBuffer;
import com.thinkaurelius.titan.diskstorage.WriteBuffer;
import com.thinkaurelius.titan.graphdb.database.serialize.attribute.ByteArraySerializer;
/**
* Serializer for BigInteger values.
*/
public class BigIntegerSerializer implements AttributeSerializer<BigInteger> {
private final ByteArraySerializer delegate = new ByteArraySerializer();
@Override
public BigInteger read(ScanBuffer buffer) {
byte[] value = delegate.read(buffer);
return new BigInteger(value);
}
@Override
public void write(WriteBuffer buffer, BigInteger attribute) {
byte[] value = attribute.toByteArray();
delegate.write(buffer, value);
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.serializer;
import java.util.ArrayList;
import java.util.List;
import com.thinkaurelius.titan.core.attribute.AttributeSerializer;
import com.thinkaurelius.titan.diskstorage.ScanBuffer;
import com.thinkaurelius.titan.diskstorage.WriteBuffer;
import com.thinkaurelius.titan.graphdb.database.idhandling.VariableLong;
import com.thinkaurelius.titan.graphdb.database.serialize.attribute.StringSerializer;
/**
* Serializer for String lists.
*/
public class StringListSerializer implements AttributeSerializer<List<String>> {
private final StringSerializer stringSerializer = new StringSerializer();
@Override
public List<String> read(ScanBuffer buffer) {
int length = (int)VariableLong.readPositive(buffer);
List<String> result = new ArrayList<String>(length);
for(int i = 0; i < length; i++) {
result.add(stringSerializer.read(buffer));
}
return result;
}
@Override
public void write(WriteBuffer buffer, List<String> attributes) {
VariableLong.writePositive(buffer, attributes.size());
for(String attr : attributes) {
stringSerializer.write(buffer, attr);
}
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1.serializer;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import com.thinkaurelius.titan.graphdb.database.serialize.attribute.EnumSerializer;
/**
* Serializer for TypeCategory value.
*/
public class TypeCategorySerializer extends EnumSerializer<TypeCategory> {
public TypeCategorySerializer() {
super(TypeCategory.class);
}
}
org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineFactory
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import org.apache.atlas.graph.GraphSandboxUtil;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graphdb.AtlasCardinality;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
*/
public abstract class AbstractGraphDatabaseTest {
protected static final String WEIGHT_PROPERTY = "weight";
protected static final String TRAIT_NAMES = Constants.TRAIT_NAMES_PROPERTY_KEY;
protected static final String TYPE_PROPERTY_NAME = "__type";
protected static final String TYPESYSTEM = "TYPESYSTEM";
private static final String BACKING_INDEX_NAME = "backing";
private AtlasGraph<?, ?> graph = null;
@BeforeClass
public static void createIndices() {
GraphSandboxUtil.create();
Titan1GraphDatabase db = new Titan1GraphDatabase();
AtlasGraphManagement mgmt = db.getGraph().getManagementSystem();
if (mgmt.getGraphIndex(BACKING_INDEX_NAME) == null) {
mgmt.createVertexIndex(BACKING_INDEX_NAME, Constants.BACKING_INDEX,
Collections.<AtlasPropertyKey>emptyList());
}
mgmt.makePropertyKey("age13", Integer.class, AtlasCardinality.SINGLE);
createIndices(mgmt, "name", String.class, false, AtlasCardinality.SINGLE);
createIndices(mgmt, WEIGHT_PROPERTY, Integer.class, false, AtlasCardinality.SINGLE);
createIndices(mgmt, "size15", String.class, false, AtlasCardinality.SINGLE);
createIndices(mgmt, "typeName", String.class, false, AtlasCardinality.SINGLE);
createIndices(mgmt, "__type", String.class, false, AtlasCardinality.SINGLE);
createIndices(mgmt, Constants.GUID_PROPERTY_KEY, String.class, true, AtlasCardinality.SINGLE);
createIndices(mgmt, Constants.TRAIT_NAMES_PROPERTY_KEY, String.class, false, AtlasCardinality.SET);
createIndices(mgmt, Constants.SUPER_TYPES_PROPERTY_KEY, String.class, false, AtlasCardinality.SET);
mgmt.commit();
}
@AfterMethod
public void commitGraph() {
//force any pending actions to be committed so we can be sure they don't cause errors.
pushChangesAndFlushCache();
getGraph().commit();
}
@AfterClass
public static void cleanUp() {
Titan1Graph graph = new Titan1Graph();
graph.clear();
}
protected <V, E> void pushChangesAndFlushCache() {
getGraph().commit();
}
private static void createIndices(AtlasGraphManagement management, String propertyName, Class propertyClass,
boolean isUnique, AtlasCardinality cardinality) {
if (management.containsPropertyKey(propertyName)) {
//index was already created
return;
}
AtlasPropertyKey key = management.makePropertyKey(propertyName, propertyClass, cardinality);
try {
if (propertyClass != Integer.class) {
management.addVertexIndexKey(BACKING_INDEX_NAME, key);
}
} catch(Throwable t) {
//ok
t.printStackTrace();
}
try {
management.createExactMatchIndex(propertyName, isUnique, Collections.singletonList(key));
} catch(Throwable t) {
//ok
t.printStackTrace();
}
}
protected final <V, E> AtlasGraph<V, E> getGraph() {
if (graph == null) {
graph = new Titan1Graph();
}
return (AtlasGraph<V, E>)graph;
}
protected Titan1Graph getTitan1Graph() {
AtlasGraph g = getGraph();
return (Titan1Graph)g;
}
protected List<AtlasVertex> newVertices = new ArrayList<>();
protected final <V, E> AtlasVertex<V, E> createVertex(AtlasGraph<V, E> theGraph) {
AtlasVertex<V, E> vertex = theGraph.addVertex();
newVertices.add(vertex);
return vertex;
}
@AfterMethod
public void removeVertices() {
for(AtlasVertex vertex : newVertices) {
if (vertex.exists()) {
getGraph().removeVertex(vertex);
}
}
getGraph().commit();
newVertices.clear();
}
protected void runSynchronouslyInNewThread(final Runnable r) throws Throwable {
RunnableWrapper wrapper = new RunnableWrapper(r);
Thread th = new Thread(wrapper);
th.start();
th.join();
Throwable ex = wrapper.getExceptionThrown();
if (ex != null) {
throw ex;
}
}
private static final class RunnableWrapper implements Runnable {
private final Runnable r;
private Throwable exceptionThrown = null;
private RunnableWrapper(Runnable r) {
this.r = r;
}
@Override
public void run() {
try {
r.run();
} catch(Throwable e) {
exceptionThrown = e;
}
}
public Throwable getExceptionThrown() {
return exceptionThrown;
}
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.atlas.repository.graphdb.titan1;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasException;
import org.apache.atlas.graph.GraphSandboxUtil;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.commons.configuration.Configuration;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@Test
public class TitanGraphProviderTest {
private Configuration configuration;
private AtlasGraph<?, ?> graph;
@BeforeTest
public void setUp() throws AtlasException {
GraphSandboxUtil.create();
//First get Instance
graph = new Titan1Graph();
configuration = ApplicationProperties.getSubsetConfiguration(ApplicationProperties.get(),
Titan1GraphDatabase.GRAPH_PREFIX);
}
@AfterClass
public void tearDown() throws Exception {
try {
graph.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
try {
graph.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testValidate() throws AtlasException {
try {
Titan1GraphDatabase.validateIndexBackend(configuration);
} catch (Exception e) {
Assert.fail("Unexpected exception ", e);
}
//Change backend
configuration.setProperty(Titan1GraphDatabase.INDEX_BACKEND_CONF, Titan1GraphDatabase.INDEX_BACKEND_LUCENE);
try {
Titan1GraphDatabase.validateIndexBackend(configuration);
Assert.fail("Expected exception");
} catch (Exception e) {
Assert.assertEquals(e.getMessage(),
"Configured Index Backend lucene differs from earlier configured "
+ "Index Backend elasticsearch. Aborting!");
}
}
}
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#
######### Graph Database to Use #########
atlas.graphdb.backend=org.apache.atlas.repository.graphdb.titan1.Titan1Database
######### Atlas Server Configs #########
atlas.rest.address=http://localhost:31000
######### Graph Database Configs #########
# Graph Storage
atlas.graph.storage.backend=${graph.storage.backend}
# Graph Search Index Backend
atlas.graph.index.search.backend=${graph.index.backend}
#Berkeley storage directory
atlas.graph.storage.directory=${sys:atlas.data}/berkeley
#hbase
#For standalone mode , specify localhost
#for distributed mode, specify zookeeper quorum here - For more information refer http://s3.thinkaurelius.com/docs/titan/current/hbase.html#_remote_server_mode_2
atlas.graph.storage.hostname=${graph.storage.hostname}
atlas.graph.storage.hbase.regions-per-server=1
atlas.graph.storage.lock.wait-time=10000
#ElasticSearch
atlas.graph.index.search.directory=${sys:atlas.data}/es
atlas.graph.index.search.elasticsearch.client-only=false
atlas.graph.index.search.elasticsearch.local-mode=true
atlas.graph.index.search.elasticsearch.create.sleep=2000
# Solr cloud mode properties
atlas.graph.index.search.solr.mode=cloud
atlas.graph.index.search.solr.zookeeper-url=${solr.zk.address}
######### Hive Lineage Configs #########
# This models reflects the base super types for Data and Process
#atlas.lineage.hive.table.type.name=DataSet
#atlas.lineage.hive.process.type.name=Process
#atlas.lineage.hive.process.inputs.name=inputs
#atlas.lineage.hive.process.outputs.name=outputs
## Schema
atlas.lineage.hive.table.schema.query.hive_table=hive_table where name='%s'\, columns
######### Notification Configs #########
atlas.notification.embedded=true
atlas.kafka.zookeeper.connect=localhost:19026
atlas.kafka.bootstrap.servers=localhost:19027
atlas.kafka.data=${sys:atlas.data}/kafka
atlas.kafka.zookeeper.session.timeout.ms=4000
atlas.kafka.zookeeper.sync.time.ms=20
atlas.kafka.consumer.timeout.ms=100
atlas.kafka.auto.commit.interval.ms=100
atlas.kafka.hook.group.id=atlas
atlas.kafka.entities.group.id=atlas_entities
######### Entity Audit Configs #########
atlas.audit.hbase.tablename=ATLAS_ENTITY_AUDIT_EVENTS
atlas.audit.zookeeper.session.timeout.ms=1000
atlas.audit.hbase.zookeeper.quorum=localhost
atlas.audit.hbase.zookeeper.property.clientPort=19026
######### Security Properties #########
# SSL config
atlas.enableTLS=false
atlas.server.https.port=31443
######### Security Properties #########
hbase.security.authentication=simple
atlas.hook.falcon.synchronous=true
######### High Availability Configuration ########
atlas.server.ha.enabled=false
#atlas.server.ids=id1
#atlas.server.address.id1=localhost:21000
......@@ -660,44 +660,42 @@
</profile>
<profile>
<!-- Activated by setting -DGRAPH-PROVIDER=titan0 -->
<id>graph-provider-titan0</id>
<id>graph-provider-janus</id>
<activation>
<property>
<name>GRAPH-PROVIDER</name>
<value>titan0</value>
<value>janus</value>
</property>
</activation>
<properties>
<!-- Define graph dependency type/version -->
<graphGroup>org.apache.atlas</graphGroup>
<graphArtifact>atlas-graphdb-titan0</graphArtifact>
<graphArtifact>atlas-graphdb-janus</graphArtifact>
<skipDocs>false</skipDocs>
<graphdb.backend.impl>org.apache.atlas.repository.graphdb.titan0.Titan0GraphDatabase</graphdb.backend.impl>
<graph.index.backend>elasticsearch</graph.index.backend>
<tests.solr.embedded>false</tests.solr.embedded>
<distro.exclude.packages>WEB-INF/lib/titan-*.jar,WEB-INF/lib/je-*.jar,WEB-INF/lib/elasticsearch-*.jar,WEB-INF/lib/lucene-*.jar</distro.exclude.packages>
<graphdb.backend.impl>org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase</graphdb.backend.impl>
<graph.index.backend>solr</graph.index.backend>
<tests.solr.embedded>true</tests.solr.embedded>
<distro.exclude.packages>WEB-INF/lib/je-*.jar,WEB-INF/lib/elasticsearch-*.jar</distro.exclude.packages>
</properties>
</profile>
<profile>
<!-- Explicitly activate by setting -DGRAPH-PROVIDER=janus -->
<id>graph-provider-janus</id>
<id>graph-provider-titan0</id>
<activation>
<property>
<name>GRAPH-PROVIDER</name>
<value>janus</value>
<value>titan0</value>
</property>
</activation>
<properties>
<!-- Define graph dependency type/version -->
<graphGroup>org.apache.atlas</graphGroup>
<graphArtifact>atlas-graphdb-janus</graphArtifact>
<graphArtifact>atlas-graphdb-titan0</graphArtifact>
<skipDocs>false</skipDocs>
<graphdb.backend.impl>org.apache.atlas.repository.graphdb.janus.AtlasJanusGraphDatabase</graphdb.backend.impl>
<graph.index.backend>solr</graph.index.backend>
<tests.solr.embedded>true</tests.solr.embedded>
<distro.exclude.packages>WEB-INF/lib/je-*.jar,WEB-INF/lib/elasticsearch-*.jar</distro.exclude.packages>
<graphdb.backend.impl>org.apache.atlas.repository.graphdb.titan0.Titan0GraphDatabase</graphdb.backend.impl>
<graph.index.backend>elasticsearch</graph.index.backend>
<tests.solr.embedded>false</tests.solr.embedded>
<distro.exclude.packages>WEB-INF/lib/titan-*.jar,WEB-INF/lib/je-*.jar,WEB-INF/lib/elasticsearch-*.jar,WEB-INF/lib/lucene-*.jar</distro.exclude.packages>
</properties>
</profile>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment