ATLAS-693 Titan 0.5.4 implementation of graph db abstraction. (jnhagelb via dkantor)
This commit is contained in:
parent
2ef0fc46d0
commit
4fa10b6aec
|
|
@ -30,6 +30,7 @@ core*.dmp
|
|||
.cache
|
||||
.classpath
|
||||
.project
|
||||
.checkstyle
|
||||
|
||||
.settings
|
||||
.externalToolBuilders
|
||||
|
|
|
|||
|
|
@ -30,7 +30,12 @@
|
|||
<description>Apache Atlas Business Catalog Module</description>
|
||||
<name>Apache Atlas Business Catalog</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
<properties>
|
||||
<tinkerpop.version>2.6.0</tinkerpop.version>
|
||||
<titan.version>0.5.4</titan.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
|
|
@ -82,11 +87,13 @@
|
|||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.gremlin</groupId>
|
||||
<artifactId>gremlin-java</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- testing -->
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@
|
|||
|
||||
package org.apache.atlas.repository;
|
||||
|
||||
import org.apache.atlas.typesystem.types.AttributeInfo;
|
||||
import org.apache.atlas.typesystem.types.DataTypes;
|
||||
import org.apache.atlas.typesystem.types.utils.TypesUtil;
|
||||
|
||||
/**
|
||||
* Repository Constants.
|
||||
*
|
||||
*/
|
||||
public final class Constants {
|
||||
|
||||
/**
|
||||
|
|
@ -48,7 +48,7 @@ public final class Constants {
|
|||
public static final String ENTITY_TEXT_PROPERTY_KEY = "entityText";
|
||||
|
||||
/**
|
||||
* Properties for type store graph
|
||||
* Properties for type store graph.
|
||||
*/
|
||||
public static final String TYPE_CATEGORY_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.category";
|
||||
public static final String VERTEX_TYPE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type";
|
||||
|
|
@ -64,20 +64,9 @@ public final class Constants {
|
|||
public static final String STATE_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "state";
|
||||
|
||||
public static final String TIMESTAMP_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "timestamp";
|
||||
public static final String MODIFICATION_TIMESTAMP_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "modificationTimestamp";
|
||||
|
||||
public static AttributeInfo getAttributeInfoForSystemAttributes(String field) {
|
||||
switch (field) {
|
||||
case STATE_PROPERTY_KEY:
|
||||
case GUID_PROPERTY_KEY:
|
||||
return TypesUtil.newAttributeInfo(field, DataTypes.STRING_TYPE);
|
||||
|
||||
case TIMESTAMP_PROPERTY_KEY:
|
||||
case MODIFICATION_TIMESTAMP_PROPERTY_KEY:
|
||||
return TypesUtil.newAttributeInfo(field, DataTypes.LONG_TYPE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static final String MODIFICATION_TIMESTAMP_PROPERTY_KEY =
|
||||
INTERNAL_PROPERTY_KEY_PREFIX + "modificationTimestamp";
|
||||
|
||||
/**
|
||||
* search backing index name.
|
||||
|
|
@ -75,7 +75,6 @@ def main():
|
|||
p = os.pathsep
|
||||
atlas_classpath = confdir + p \
|
||||
+ os.path.join(web_app_dir, "atlas", "WEB-INF", "classes" ) + p \
|
||||
+ os.path.join(web_app_dir, "atlas", "WEB-INF", "lib", "atlas-titan-${project.version}.jar" ) + p \
|
||||
+ os.path.join(web_app_dir, "atlas", "WEB-INF", "lib", "*" ) + p \
|
||||
+ os.path.join(atlas_home, "libext", "*")
|
||||
|
||||
|
|
|
|||
|
|
@ -86,14 +86,14 @@ class TestMetadata(unittest.TestCase):
|
|||
java_mock.assert_called_with(
|
||||
'org.apache.atlas.Atlas',
|
||||
['-app', 'atlas_home\\server\\webapp\\atlas'],
|
||||
'atlas_home\\conf;atlas_home\\server\\webapp\\atlas\\WEB-INF\\classes;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\atlas-titan-${project.version}.jar;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\*;atlas_home\\libext\\*;atlas_home\\hbase\\conf',
|
||||
'atlas_home\\conf;atlas_home\\server\\webapp\\atlas\\WEB-INF\\classes;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\*;atlas_home\\libext\\*;atlas_home\\hbase\\conf',
|
||||
['-Datlas.log.dir=atlas_home\\logs', '-Datlas.log.file=application.log', '-Datlas.home=atlas_home', '-Datlas.conf=atlas_home\\conf', '-Xmx1024m', '-XX:MaxPermSize=512m', '-Dlog4j.configuration=atlas-log4j.xml', '-Djava.net.preferIPv4Stack=true'], 'atlas_home\\logs')
|
||||
|
||||
else:
|
||||
java_mock.assert_called_with(
|
||||
'org.apache.atlas.Atlas',
|
||||
['-app', 'atlas_home/server/webapp/atlas'],
|
||||
'atlas_home/conf:atlas_home/server/webapp/atlas/WEB-INF/classes:atlas_home/server/webapp/atlas/WEB-INF/lib/atlas-titan-${project.version}.jar:atlas_home/server/webapp/atlas/WEB-INF/lib/*:atlas_home/libext/*:atlas_home/hbase/conf',
|
||||
'atlas_home/conf:atlas_home/server/webapp/atlas/WEB-INF/classes:atlas_home/server/webapp/atlas/WEB-INF/lib/*:atlas_home/libext/*:atlas_home/hbase/conf',
|
||||
['-Datlas.log.dir=atlas_home/logs', '-Datlas.log.file=application.log', '-Datlas.home=atlas_home', '-Datlas.conf=atlas_home/conf', '-Xmx1024m', '-XX:MaxPermSize=512m', '-Dlog4j.configuration=atlas-log4j.xml', '-Djava.net.preferIPv4Stack=true'], 'atlas_home/logs')
|
||||
|
||||
pass
|
||||
|
|
@ -152,14 +152,14 @@ class TestMetadata(unittest.TestCase):
|
|||
java_mock.assert_called_with(
|
||||
'org.apache.atlas.Atlas',
|
||||
['-app', 'atlas_home\\server\\webapp\\atlas'],
|
||||
'atlas_home\\conf;atlas_home\\server\\webapp\\atlas\\WEB-INF\\classes;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\atlas-titan-${project.version}.jar;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\*;atlas_home\\libext\\*;atlas_home\\hbase\\conf',
|
||||
'atlas_home\\conf;atlas_home\\server\\webapp\\atlas\\WEB-INF\\classes;atlas_home\\server\\webapp\\atlas\\WEB-INF\\lib\\*;atlas_home\\libext\\*;atlas_home\\hbase\\conf',
|
||||
['-Datlas.log.dir=atlas_home\\logs', '-Datlas.log.file=application.log', '-Datlas.home=atlas_home', '-Datlas.conf=atlas_home\\conf', '-Xmx1024m', '-XX:MaxPermSize=512m', '-Dlog4j.configuration=atlas-log4j.xml', '-Djava.net.preferIPv4Stack=true'], 'atlas_home\\logs')
|
||||
|
||||
else:
|
||||
java_mock.assert_called_with(
|
||||
'org.apache.atlas.Atlas',
|
||||
['-app', 'atlas_home/server/webapp/atlas'],
|
||||
'atlas_home/conf:atlas_home/server/webapp/atlas/WEB-INF/classes:atlas_home/server/webapp/atlas/WEB-INF/lib/atlas-titan-${project.version}.jar:atlas_home/server/webapp/atlas/WEB-INF/lib/*:atlas_home/libext/*:atlas_home/hbase/conf',
|
||||
'atlas_home/conf:atlas_home/server/webapp/atlas/WEB-INF/classes:atlas_home/server/webapp/atlas/WEB-INF/lib/*:atlas_home/libext/*:atlas_home/hbase/conf',
|
||||
['-Datlas.log.dir=atlas_home/logs', '-Datlas.log.file=application.log', '-Datlas.home=atlas_home', '-Datlas.conf=atlas_home/conf', '-Xmx1024m', '-XX:MaxPermSize=512m', '-Dlog4j.configuration=atlas-log4j.xml', '-Djava.net.preferIPv4Stack=true'], 'atlas_home/logs')
|
||||
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -24,37 +24,37 @@ package org.apache.atlas.repository.graphdb;
|
|||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
*/
|
||||
public interface AtlasEdge<V,E> extends AtlasElement {
|
||||
public interface AtlasEdge<V, E> extends AtlasElement {
|
||||
|
||||
/**
|
||||
* Gets the incoming vertex for this edge
|
||||
* @param in
|
||||
* @return
|
||||
*/
|
||||
AtlasVertex<V,E> getInVertex();
|
||||
AtlasVertex<V, E> getInVertex();
|
||||
|
||||
/**
|
||||
* Gets the outgoing vertex for this edge
|
||||
*
|
||||
*
|
||||
* @param in
|
||||
* @return
|
||||
*/
|
||||
AtlasVertex<V,E> getOutVertex();
|
||||
|
||||
AtlasVertex<V, E> getOutVertex();
|
||||
|
||||
/**
|
||||
* Gets the label associated with this edge.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getLabel();
|
||||
|
||||
|
||||
/**
|
||||
* Converts the edge to an instance of the underlying implementation class. This
|
||||
* is syntactic sugar that allows the graph database implementation code to be strongly typed. This
|
||||
* should not be called in other places.
|
||||
*
|
||||
* should not be called in other places.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public E getE();
|
||||
public E getE();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@ package org.apache.atlas.repository.graphdb;
|
|||
*/
|
||||
public enum AtlasEdgeDirection {
|
||||
IN,
|
||||
OUT,
|
||||
OUT,
|
||||
BOTH
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,23 @@
|
|||
package org.apache.atlas.repository.graphdb;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Represents a graph element.
|
||||
* Represents a graph element.
|
||||
*
|
||||
*/
|
||||
public interface AtlasElement {
|
||||
|
||||
/**
|
||||
* Gets the id of this element
|
||||
* Gets the id of this element. If the object has not been physically created in the underlying graph,
|
||||
* calling this method will force the element to be created so that a valid Id can be returned.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Object getId();
|
||||
|
|
@ -43,32 +47,122 @@ public interface AtlasElement {
|
|||
Collection<? extends String> getPropertyKeys();
|
||||
|
||||
/**
|
||||
* Gets the value of the element property with the given name
|
||||
*
|
||||
* Gets the value of the element property with the given name. The value
|
||||
* returned is guaranteed to be an instance of the specified class (or
|
||||
* an exception will be thrown).
|
||||
*
|
||||
* @param propertyName
|
||||
* @return
|
||||
* @throws IllegalStateException if the property is multi-valued in the graph schema.
|
||||
*/
|
||||
<T> T getProperty(String propertyName, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Gets all of the values of the given property.
|
||||
* @param propertyName
|
||||
* @return
|
||||
*/
|
||||
<T> T getProperty(String propertyName);
|
||||
|
||||
<T> Collection<T> getPropertyValues(String propertyName, Class<T> type);
|
||||
|
||||
/**
|
||||
* Gets the value of a multiplicity one property whose value is a String list.
|
||||
* The lists of super types and traits are stored this way. A separate method
|
||||
* is needed for this because special logic is required to handle this situation
|
||||
* in some implementations.
|
||||
*/
|
||||
List<String> getListProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Gets the value of a multiplicity one property whose value is a list. It
|
||||
* attempts to convert the elements in the list to the specified type. Currently
|
||||
* conversion is only supported for subclasses of AtlasElement and String.
|
||||
*/
|
||||
<V> List<V> getListProperty(String propertyName, Class<V> elementType);
|
||||
|
||||
/**
|
||||
* Sets a multiplicity one property whose value is a String list.
|
||||
* The lists of super types and traits are stored this way. A separate method
|
||||
* is needed for this because special logic is required to handle this situation
|
||||
* in some implementations.
|
||||
*/
|
||||
void setListProperty(String propertyName, List<String> values) throws AtlasException;
|
||||
|
||||
|
||||
/**
|
||||
* Sets a multiplicity one property whose effective value is a String list whose
|
||||
* values consist of the ids of the supplied elements. This is implemented efficiently
|
||||
* so that in many cases the property can be set without requiring new elements
|
||||
* to be immediately created in the graph database. It allows the actual underlying element
|
||||
* creation to be deferred until commit time.
|
||||
*/
|
||||
void setPropertyFromElementsIds(String propertyName, List<AtlasElement> values);
|
||||
|
||||
/**
|
||||
* Sets a multiplicity one property whose effective value is a String whose value is the id of the supplied
|
||||
* element. This is implemented efficiently so that in many cases the property can be set without requiring
|
||||
* new elements to be immediately created in the graph database. It allows the actual underlying element
|
||||
* creation to be deferred until commit time.
|
||||
*/
|
||||
void setPropertyFromElementId(String propertyName, AtlasElement value);
|
||||
|
||||
|
||||
/**
|
||||
* Removes a property from the vertex.
|
||||
*/
|
||||
void removeProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Sets a single-valued property to the given value.
|
||||
*
|
||||
* Sets a single-valued property to the given value. For
|
||||
* properties defined as multiplicty many in the graph schema, the value is added instead
|
||||
* (following set semantics)
|
||||
*
|
||||
* @param propertyName
|
||||
* @param value
|
||||
*/
|
||||
<T> void setProperty(String propertyName, T value);
|
||||
|
||||
|
||||
<T> void setProperty(String propertyName, T value);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Jettison JSONObject from this Element
|
||||
*
|
||||
* @param propertyKeys The property keys at the root of the element to serialize. If null, then all keys are serialized.
|
||||
*/
|
||||
JSONObject toJson(Set<String> propertyKeys) throws JSONException;
|
||||
|
||||
JSONObject toJson(Set<String> propertyKeys) throws JSONException;
|
||||
|
||||
/**
|
||||
* Determines if this element exists in the graph database. If the element has not
|
||||
* actually been loaded from the underlying graph, this will cause it to be loaded
|
||||
* so that the result is correct.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean exists();
|
||||
|
||||
/**
|
||||
* @param propertyName
|
||||
* @param value
|
||||
*/
|
||||
<T> void setJsonProperty(String propertyName, T value);
|
||||
|
||||
/**
|
||||
* @param propertyName
|
||||
* @return
|
||||
*/
|
||||
<T> T getJsonProperty(String propertyName);
|
||||
|
||||
/**
|
||||
* Gets a human-readable id without forcing the element to
|
||||
* be created if it does not exist in the graph yet.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getIdForDisplay();
|
||||
|
||||
/**
|
||||
* Whether or not an id has been assigned yet for this Element. This can happen if the element has been created
|
||||
* in memory but has not been actually pushed into the underlying graph yet.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isIdAssigned();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,70 +22,82 @@ import java.io.OutputStream;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.apache.atlas.typesystem.types.IDataType;
|
||||
|
||||
/**
|
||||
* Represents a graph
|
||||
*
|
||||
*
|
||||
* @param <V> vertex implementation class
|
||||
* @param <E> edge implementation class
|
||||
*/
|
||||
public interface AtlasGraph<V,E> {
|
||||
public interface AtlasGraph<V, E> {
|
||||
|
||||
/**
|
||||
* Adds an edge to the graph
|
||||
*
|
||||
*
|
||||
* @param outVertex
|
||||
* @param inVertex
|
||||
* @param label
|
||||
* @return
|
||||
*/
|
||||
AtlasEdge<V,E> addEdge(AtlasVertex<V,E> outVertex, AtlasVertex<V,E> inVertex, String label);
|
||||
AtlasEdge<V, E> addEdge(AtlasVertex<V, E> outVertex, AtlasVertex<V, E> inVertex, String label);
|
||||
|
||||
/**
|
||||
* Adds a vertex to the graph
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AtlasVertex<V,E> addVertex();
|
||||
AtlasVertex<V, E> addVertex();
|
||||
|
||||
/**
|
||||
* Removes the specified edge from the graph
|
||||
*
|
||||
*
|
||||
* @param edge
|
||||
*/
|
||||
void removeEdge(AtlasEdge<V,E> edge);
|
||||
void removeEdge(AtlasEdge<V, E> edge);
|
||||
|
||||
/**
|
||||
* Removes the specified vertex from the graph.
|
||||
*
|
||||
*
|
||||
* @param vertex
|
||||
*/
|
||||
void removeVertex(AtlasVertex<V,E> vertex);
|
||||
void removeVertex(AtlasVertex<V, E> vertex);
|
||||
|
||||
/**
|
||||
* Retrieves the edge with the specified id
|
||||
* Retrieves the edge with the specified id. As an optimization, a non-null Edge may be
|
||||
* returned by some implementations if the Edge does not exist. In that case,
|
||||
* you can call {@link AtlasElement#exists()} to determine whether the vertex
|
||||
* exists. This allows the retrieval of the Edge information to be deferred
|
||||
* or in come cases avoided altogether in implementations where that might
|
||||
* be an expensive operation.
|
||||
*
|
||||
* @param edgeId
|
||||
* @return
|
||||
*/
|
||||
AtlasEdge<V,E> getEdge(String edgeId);
|
||||
AtlasEdge<V, E> getEdge(String edgeId);
|
||||
|
||||
/**
|
||||
* Gets all the edges in the graph.
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasEdge<V,E>> getEdges();
|
||||
Iterable<AtlasEdge<V, E>> getEdges();
|
||||
|
||||
/**
|
||||
* Gets all the vertices in the graph.
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasVertex<V,E>> getVertices();
|
||||
Iterable<AtlasVertex<V, E>> getVertices();
|
||||
|
||||
/**
|
||||
* Gets the vertex with the specified id
|
||||
*
|
||||
* Gets the vertex with the specified id. As an optimization, a non-null vertex may be
|
||||
* returned by some implementations if the Vertex does not exist. In that case,
|
||||
* you can call {@link AtlasElement#exists()} to determine whether the vertex
|
||||
* exists. This allows the retrieval of the Vertex information to be deferred
|
||||
* or in come cases avoided altogether in implementations where that might
|
||||
* be an expensive operation.
|
||||
*
|
||||
* @param vertexId
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -94,7 +106,7 @@ public interface AtlasGraph<V,E> {
|
|||
/**
|
||||
* Gets the names of the indexes on edges
|
||||
* type.
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -104,40 +116,40 @@ public interface AtlasGraph<V,E> {
|
|||
/**
|
||||
* Gets the names of the indexes on vertices.
|
||||
* type.
|
||||
*
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
Set<String> getVertexIndexKeys();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Finds the vertices where the given property key
|
||||
* has the specified value. For multi-valued properties,
|
||||
* finds the vertices where the value list contains
|
||||
* the specified value.
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasVertex<V,E>> getVertices(String key, Object value);
|
||||
Iterable<AtlasVertex<V, E>> getVertices(String key, Object value);
|
||||
|
||||
/**
|
||||
* Creates a graph query
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V,E> query();
|
||||
AtlasGraphQuery<V, E> query();
|
||||
|
||||
/**
|
||||
* Creates an index query
|
||||
*
|
||||
*
|
||||
* @param indexName index name
|
||||
* @param queryString the query
|
||||
*
|
||||
*
|
||||
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html">Elastic Search Reference</a> for query syntax
|
||||
*/
|
||||
AtlasIndexQuery<V,E> indexQuery(String indexName, String queryString);
|
||||
AtlasIndexQuery<V, E> indexQuery(String indexName, String queryString);
|
||||
|
||||
/**
|
||||
* Gets the management object associated with this graph and opens a transaction
|
||||
|
|
@ -160,26 +172,30 @@ public interface AtlasGraph<V,E> {
|
|||
* Unloads and releases any resources associated with the graph.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
|
||||
/**
|
||||
* deletes everything in the graph. For testing only
|
||||
* Deletes all data in the graph. May or may not delete
|
||||
* the indices, depending on the what the underlying graph supports.
|
||||
*
|
||||
* For testing only.
|
||||
*
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Converts the graph to gson and writes it to the specified stream
|
||||
*
|
||||
*
|
||||
* @param os
|
||||
* @throws IOException
|
||||
*/
|
||||
void exportToGson(OutputStream os) throws IOException;
|
||||
|
||||
|
||||
//the following methods insulate Atlas from the details
|
||||
//of the interaction with Gremlin
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* When we construct Gremlin select queries, the information we request
|
||||
* is grouped by the vertex the information is coming from. Each vertex
|
||||
* is assigned a column name which uniquely identifies it. The queries
|
||||
|
|
@ -197,26 +213,26 @@ public interface AtlasGraph<V,E> {
|
|||
* <p/>
|
||||
* If the value found is a vertex or edge, it is automatically converted
|
||||
* to an AtlasVertex/AtlasEdge.
|
||||
*
|
||||
*
|
||||
* @param rowValue the raw row value that was returned by Gremin
|
||||
* @param colName the column name to use
|
||||
* @param idx the index of the value within the column to retrieve.
|
||||
*
|
||||
* @param idx the index of the value within the column to retrieve.
|
||||
*
|
||||
*/
|
||||
Object getGremlinColumnValue(Object rowValue, String colName, int idx);
|
||||
|
||||
/**
|
||||
* When Gremlin queries are executed, they return
|
||||
* When Gremlin queries are executed, they return
|
||||
* Vertex and Edge objects that are specific to the underlying
|
||||
* graph database. This method provides a way to convert these
|
||||
* objects back into the AtlasVertex/AtlasEdge objects that
|
||||
* Atlas requires.
|
||||
*
|
||||
* Atlas requires.
|
||||
*
|
||||
* @param rawValue the value that was obtained from Gremlin
|
||||
* @return either an AtlasEdge, an AtlasVertex, or the original
|
||||
* value depending on whether the rawValue represents an edge,
|
||||
* vertex, or something else.
|
||||
*
|
||||
*
|
||||
*/
|
||||
Object convertGremlinValue(Object rawValue);
|
||||
|
||||
|
|
@ -224,27 +240,75 @@ public interface AtlasGraph<V,E> {
|
|||
* Gremlin 2 and Gremlin 3 represent the results of "path"
|
||||
* queries differently. This method takes as input the
|
||||
* path from Gremlin and returns the list of objects in the path.
|
||||
*
|
||||
*
|
||||
* @param rawValue
|
||||
* @return
|
||||
*/
|
||||
List<Object> convertPathQueryResultToList(Object rawValue);
|
||||
|
||||
/**
|
||||
* This method is used in the generation of queries. It is used to
|
||||
* convert property values from the value that is stored in the graph
|
||||
* to the value/type that the user expects to get back.
|
||||
*
|
||||
* @param expr - gremlin expr that represents the persistent property value
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
String generatePersisentToLogicalConversionExpression(String valueExpr, IDataType<?> type);
|
||||
|
||||
/**
|
||||
* Indicates whether or not stored values with the specified type need to be converted
|
||||
* within generated gremlin queries before they can be compared with literal values.
|
||||
* As an example, a graph database might choose to store Long values as Strings or
|
||||
* List values as a delimited list. In this case, the generated gremlin needs to
|
||||
* convert the stored property value prior to comparing it a literal. In this returns
|
||||
* true, @code{generatePersisentToLogicalConversionExpression} is used to generate a
|
||||
* gremlin expression with the converted value. In addition, this cause the gremlin
|
||||
* 'filter' step to be used to compare the values instead of a 'has' step.
|
||||
*/
|
||||
boolean isPropertyValueConversionNeeded(IDataType<?> type);
|
||||
|
||||
/**
|
||||
* Gets the version of Gremlin that this graph uses.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
GremlinVersion getSupportedGremlinVersion();
|
||||
|
||||
/**
|
||||
* Whether or not an initial predicate needs to be added to gremlin queries
|
||||
* in order for them to run successfully. This is needed for some graph database where
|
||||
* graph scans are disabled.
|
||||
* @return
|
||||
*/
|
||||
boolean requiresInitialIndexedPredicate();
|
||||
|
||||
/**
|
||||
* Some graph database backends have graph scans disabled. In order to execute some queries there,
|
||||
* an initial 'dummy' predicate needs to be added to gremlin queries so that the first
|
||||
* condition uses an index.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getInitialIndexedPredicate();
|
||||
|
||||
/**
|
||||
* As an optimization, a graph database implementation may want to retrieve additional
|
||||
* information about the query results. For example, in the IBM Graph implementation,
|
||||
* this changes the query to return both matching vertices and their outgoing edges to
|
||||
* avoid the need to make an extra REST API call to look up those edges. For implementations
|
||||
* that do not require any kind of transform, an empty String should be returned.
|
||||
*/
|
||||
String getOutputTransformationPredicate(boolean isSelect, boolean isPath);
|
||||
|
||||
/**
|
||||
* Executes a gremlin query, returns an object with the raw
|
||||
* result.
|
||||
*
|
||||
*
|
||||
* @param gremlinQuery
|
||||
* @return
|
||||
*/
|
||||
Object executeGremlinScript(String gremlinQuery) throws ScriptException;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents a graph index on the database
|
||||
*/
|
||||
public interface AtlasGraphIndex {
|
||||
|
||||
/**
|
||||
* Indicates if the index is a mixed index.
|
||||
* @return
|
||||
*/
|
||||
boolean isMixedIndex();
|
||||
|
||||
|
||||
/**
|
||||
* Indicates if the index is a composite index.
|
||||
* @return
|
||||
*/
|
||||
boolean isCompositeIndex();
|
||||
|
||||
/**
|
||||
* Indicates if the index applies to edges
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isEdgeIndex();
|
||||
|
||||
/**
|
||||
* Indicates if the index applies to vertices
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isVertexIndex();
|
||||
|
||||
|
||||
|
||||
boolean isUnique();
|
||||
|
||||
Set<AtlasPropertyKey> getFieldKeys();
|
||||
|
||||
}
|
||||
|
|
@ -18,48 +18,62 @@
|
|||
|
||||
package org.apache.atlas.repository.graphdb;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
import org.apache.atlas.typesystem.types.Multiplicity;
|
||||
|
||||
/**
|
||||
* Management interface for a graph
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface AtlasGraphManagement {
|
||||
|
||||
public static final Set<String> MULTIPLICITY_MANY_PROPERTY_KEYS =
|
||||
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
|
||||
Constants.SUPER_TYPES_PROPERTY_KEY,
|
||||
Constants.TRAIT_NAMES_PROPERTY_KEY )));
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether a property with the given key has been defined in the graph schema.
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
boolean containsPropertyKey(String key);
|
||||
|
||||
/**
|
||||
* Creates a mixed Vertex index for the graph
|
||||
*
|
||||
* Creates a mixed Vertex index for the graph
|
||||
*
|
||||
* @param index the name of the index to create
|
||||
* @param backingIndex the name of the backing index to use
|
||||
*/
|
||||
void buildMixedVertexIndex(String index, String backingIndex);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a mixed Edge index for the graph
|
||||
*
|
||||
* Creates a mixed Edge index for the graph
|
||||
*
|
||||
* @param index the name of the index to create
|
||||
* @param backingIndex the name of the backing index to use
|
||||
*/
|
||||
void buildMixedEdgeIndex(String index, String backingIndex);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a full text index for the given property
|
||||
*
|
||||
* Creates a full text index for the given property
|
||||
*
|
||||
* @param indexName the name of the index to create
|
||||
* @param propertyKey the name of the property
|
||||
* @param propertyKey full text property to index
|
||||
* @param backingIndex the name of the backing index to use
|
||||
*/
|
||||
void createFullTextIndex(String indexName, String propertyKey, String backingIndex);
|
||||
void createFullTextIndex(String indexName, AtlasPropertyKey propertyKey, String backingIndex);
|
||||
|
||||
/**
|
||||
* Rolls back the changes that have been made to the management system.
|
||||
|
|
@ -73,26 +87,44 @@ public interface AtlasGraphManagement {
|
|||
void commit();
|
||||
|
||||
/**
|
||||
* Creates a composite index for the given property.
|
||||
*
|
||||
* @param propertyName name of the property being indexed
|
||||
* @param propertyClass the java class of the property value(s)
|
||||
* @param multiplicity the multiplicity of the property
|
||||
* @param isUnique whether the property values must be unique
|
||||
* @param propertyName
|
||||
* @param propertyClass
|
||||
* @param cardinality
|
||||
* @return
|
||||
*/
|
||||
void createCompositeIndex(String propertyName, Class propertyClass, Multiplicity multiplicity,
|
||||
boolean isUnique);
|
||||
|
||||
AtlasPropertyKey makePropertyKey(String propertyName, Class propertyClass, Multiplicity multiplicity);
|
||||
|
||||
/**
|
||||
* Creates an index for a property.
|
||||
*
|
||||
* @param propertyName name of the property being indexed
|
||||
* @param vertexIndexName name of the index to create
|
||||
* @param propertyClass the java class of the property value(s)
|
||||
* @param multiplicity the multiplicity of the property
|
||||
* @param propertyKey
|
||||
* @return
|
||||
*/
|
||||
void createBackingIndex(String propertyName, String vertexIndexName, Class propertyClass,
|
||||
Multiplicity multiplicity);
|
||||
AtlasPropertyKey getPropertyKey(String propertyName);
|
||||
|
||||
/**
|
||||
* Creates a composite index for the graph.
|
||||
*
|
||||
* @param propertyName
|
||||
* @param propertyKey
|
||||
* @param isUnique
|
||||
*/
|
||||
void createCompositeIndex(String propertyName, AtlasPropertyKey propertyKey, boolean isUnique);
|
||||
|
||||
/**
|
||||
* Adds a property key to the given index in the graph.
|
||||
*
|
||||
* @param vertexIndex
|
||||
* @param propertyKey
|
||||
*/
|
||||
void addIndexKey(String vertexIndex, AtlasPropertyKey propertyKey);
|
||||
|
||||
/**
|
||||
* Looks up the index with the specified name in the graph. Returns null if
|
||||
* there is no index with the given name.
|
||||
*
|
||||
* @param edgeIndex
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphIndex getGraphIndex(String indexName);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,14 @@
|
|||
|
||||
package org.apache.atlas.repository.graphdb;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
|
||||
/**
|
||||
* Represents a query against the graph.
|
||||
* Represents a query against the graph within the context of the
|
||||
* current transaction.
|
||||
*
|
||||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
|
|
@ -27,10 +33,10 @@ package org.apache.atlas.repository.graphdb;
|
|||
public interface AtlasGraphQuery<V,E> {
|
||||
|
||||
/**
|
||||
* Adds a predicate that the returned elements must have the specified
|
||||
* Adds a predicate that the returned vertices must have the specified
|
||||
* property and that one of the values of the property must be the
|
||||
* given value.
|
||||
*
|
||||
*
|
||||
* @param propertyKey
|
||||
* @param value
|
||||
* @return
|
||||
|
|
@ -38,34 +44,73 @@ public interface AtlasGraphQuery<V,E> {
|
|||
AtlasGraphQuery<V,E> has(String propertyKey, Object value);
|
||||
|
||||
/**
|
||||
* Executes the query and returns the matching vertices.
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasVertex<V, E>> vertices();
|
||||
|
||||
|
||||
/**
|
||||
* Executes the query and returns the matching edges.
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasEdge<V, E>> edges();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Adds a predicate that the returned elements must have the specified
|
||||
* property and that its value matches the criterion specified.
|
||||
*
|
||||
* Adds a predicate that the returned vertices must have the specified
|
||||
* property and that one of the value of the property must be in
|
||||
* the specified list of values.
|
||||
*
|
||||
* @param propertyKey
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V,E> has(String propertyKey, ComparisionOperator compMethod, Object value);
|
||||
AtlasGraphQuery<V,E> in(String propertyKey, Collection<? extends Object> values);
|
||||
|
||||
|
||||
/**
|
||||
* Executes the query and returns the matching vertices.
|
||||
* @return
|
||||
* @throws AtlasException
|
||||
*/
|
||||
Iterable<AtlasVertex<V, E>> vertices();
|
||||
|
||||
|
||||
/**
|
||||
* Adds a predicate that the returned vertices must have the specified
|
||||
* property and that its value matches the criterion specified.
|
||||
*
|
||||
* @param propertyKey
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V,E> has(String propertyKey, ComparisionOperator compMethod, Object values);
|
||||
|
||||
/**
|
||||
* Adds a predicate that the vertices returned must satisfy the
|
||||
* conditions in at least one of the child queries provided.
|
||||
*
|
||||
* @param childQueries
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V,E> or(List<AtlasGraphQuery<V,E>> childQueries);
|
||||
|
||||
/**
|
||||
* Creates a child query that can be used to add "or" conditions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V,E> createChildQuery();
|
||||
|
||||
|
||||
public static enum ComparisionOperator {
|
||||
GREATER_THAN_EQUAL,
|
||||
EQUAL,
|
||||
LESS_THAN_EQUAL
|
||||
LESS_THAN_EQUAL,
|
||||
NOT_EQUAL
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the predicates that have been added to this query to the
|
||||
* specified query.
|
||||
* @param otherQuery
|
||||
* @return
|
||||
*/
|
||||
AtlasGraphQuery<V, E> addConditionsFrom(AtlasGraphQuery<V, E> otherQuery);
|
||||
|
||||
/**
|
||||
* Whether or not this is a child query
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isChildQuery();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,31 +26,31 @@ import java.util.Iterator;
|
|||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
*/
|
||||
public interface AtlasIndexQuery<V,E> {
|
||||
public interface AtlasIndexQuery<V, E> {
|
||||
|
||||
/**
|
||||
* Gets the query results.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Iterator<Result<V,E>> vertices();
|
||||
Iterator<Result<V, E>> vertices();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Query result from an index query.
|
||||
*
|
||||
*
|
||||
* @param <V>
|
||||
* @param <E>
|
||||
*/
|
||||
public interface Result<V,E> {
|
||||
|
||||
public interface Result<V, E> {
|
||||
|
||||
/**
|
||||
* Gets the vertex for this result
|
||||
*/
|
||||
AtlasVertex<V,E> getVertex();
|
||||
|
||||
AtlasVertex<V, E> getVertex();
|
||||
|
||||
/**
|
||||
* Gets the score for this result.
|
||||
*
|
||||
*
|
||||
*/
|
||||
double getScore();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Represent a property key
|
||||
*
|
||||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
*/
|
||||
public interface AtlasPropertyKey {
|
||||
|
||||
String getName();
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ package org.apache.atlas.repository.graphdb;
|
|||
*
|
||||
*/
|
||||
public class AtlasSchemaViolationException extends RuntimeException {
|
||||
|
||||
|
||||
public AtlasSchemaViolationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,64 +17,56 @@
|
|||
*/
|
||||
package org.apache.atlas.repository.graphdb;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents a Vertex
|
||||
* Represents a Vertex
|
||||
*
|
||||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
*/
|
||||
public interface AtlasVertex<V,E> extends AtlasElement {
|
||||
|
||||
|
||||
|
||||
public interface AtlasVertex<V, E> extends AtlasElement {
|
||||
|
||||
/**
|
||||
* Gets the edges incident to this vertex going the
|
||||
* specified direction that have the specified edgeLabel. If
|
||||
* the edgeLabel is null, it is ignored.
|
||||
*
|
||||
*
|
||||
* @param in
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasEdge<V,E>> getEdges(AtlasEdgeDirection out, String edgeLabel);
|
||||
Iterable<AtlasEdge<V, E>> getEdges(AtlasEdgeDirection out, String edgeLabel);
|
||||
|
||||
/**
|
||||
* Gets the edges associated with this vertex going the
|
||||
* specified direction.
|
||||
*
|
||||
*
|
||||
* @param in
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasEdge<V,E>> getEdges(AtlasEdgeDirection in);
|
||||
|
||||
Iterable<AtlasEdge<V, E>> getEdges(AtlasEdgeDirection in);
|
||||
|
||||
/**
|
||||
* Adds a value to a multiplicity many property.
|
||||
*
|
||||
* Adds a value to a multiplicity many property. Follows Java set
|
||||
* semantics. If the property is already present, it is not added again,
|
||||
* and no exception is thrown.
|
||||
*
|
||||
*
|
||||
* @param propertyName
|
||||
* @param value
|
||||
*/
|
||||
<T> void addProperty(String propertyName, T value);
|
||||
|
||||
/**
|
||||
* Gets all of the values of the given property.
|
||||
* @param propertyName
|
||||
* @return
|
||||
*/
|
||||
<T> Collection<T> getPropertyValues(String propertyName);
|
||||
|
||||
/**
|
||||
* Creates a vertex query.
|
||||
* @return
|
||||
*/
|
||||
AtlasVertexQuery<V,E> query();
|
||||
AtlasVertexQuery<V, E> query();
|
||||
|
||||
/**
|
||||
* Syntactic sugar to get the vertex as an instance of its
|
||||
* implementation type. This allows the graph database implementation
|
||||
* code to be strongly typed.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
V getV();
|
||||
|
|
|
|||
|
|
@ -19,33 +19,33 @@
|
|||
package org.apache.atlas.repository.graphdb;
|
||||
|
||||
/**
|
||||
* A query against a particular vertex.
|
||||
* A query against a particular vertex.
|
||||
*
|
||||
* @param <V> vertex class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
* @param <E> edge class used by the graph
|
||||
*/
|
||||
public interface AtlasVertexQuery<V,E> {
|
||||
public interface AtlasVertexQuery<V, E> {
|
||||
|
||||
/**
|
||||
* Specifies the edge direction that should be query
|
||||
*
|
||||
*
|
||||
* @param queryDirection
|
||||
* @return
|
||||
*/
|
||||
AtlasVertexQuery<V,E> direction(AtlasEdgeDirection queryDirection);
|
||||
AtlasVertexQuery<V, E> direction(AtlasEdgeDirection queryDirection);
|
||||
|
||||
/**
|
||||
* Returns the vertices that satisfy the query condition.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasVertex<V,E>> vertices();
|
||||
Iterable<AtlasVertex<V, E>> vertices();
|
||||
|
||||
/**
|
||||
* Returns the incident edges that satisfy the query condition.
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasEdge<V,E>> edges();
|
||||
Iterable<AtlasEdge<V, E>> edges();
|
||||
|
||||
/**
|
||||
* Returns the number of elements that match the query.
|
||||
|
|
|
|||
|
|
@ -23,22 +23,28 @@ package org.apache.atlas.repository.graphdb;
|
|||
* @param <V> vertex class used by the graph database
|
||||
* @param <E> edge class used by the graph database
|
||||
*/
|
||||
public interface GraphDatabase<V,E> {
|
||||
|
||||
public interface GraphDatabase<V, E> {
|
||||
|
||||
/**
|
||||
* Returns whether the graph has been loaded.
|
||||
* @return
|
||||
*/
|
||||
boolean isGraphLoaded();
|
||||
|
||||
boolean isGraphLoaded();
|
||||
|
||||
/**
|
||||
* Gets the graph, loading it if it has not been loaded already
|
||||
* @return
|
||||
*/
|
||||
AtlasGraph<V,E> getGraph();
|
||||
|
||||
AtlasGraph<V, E> getGraph();
|
||||
|
||||
/**
|
||||
* Unloads the graph (used testing)
|
||||
* Sets things up so that getGraph() will return a graph that can be used for running
|
||||
* tests.
|
||||
*/
|
||||
void unloadGraph();
|
||||
void initializeTestGraph();
|
||||
|
||||
/**
|
||||
* Removes the test graph that was created.
|
||||
*/
|
||||
void removeTestGraph();
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ package org.apache.atlas.repository.graphdb;
|
|||
|
||||
/**
|
||||
* Enumeration of the supported versions of Gremlin
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public enum GremlinVersion {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- ~ 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. -->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>atlas-graphdb</artifactId>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<version>0.8-incubator-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>atlas-graphdb-common</artifactId>
|
||||
|
||||
<description>Adds IBM Graph Database Support to Apache Atlas</description>
|
||||
<name>Graph Database Common Code</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>18.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>6.9.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* 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.titan.query;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
|
||||
/**
|
||||
* Interfaces that provides a thin wrapper around GraphQuery (used by Titan0) and
|
||||
* TitanGraphQuery (used by Titan 1).
|
||||
*
|
||||
* This abstraction allows TitanGraphQuery to work on any version of Titan.
|
||||
*
|
||||
* @param <V>
|
||||
* @param <E>
|
||||
*/
|
||||
public interface NativeTitanGraphQuery<V,E> {
|
||||
|
||||
/**
|
||||
* Executes the graph query
|
||||
* @return
|
||||
*/
|
||||
Iterable<AtlasVertex<V,E>> vertices();
|
||||
|
||||
|
||||
/**
|
||||
* Adds an in condition to the query
|
||||
*
|
||||
* @param propertyName
|
||||
* @param values
|
||||
*/
|
||||
void in(String propertyName, Collection<? extends Object> values);
|
||||
|
||||
/**
|
||||
* Adds a has condition to the query
|
||||
*
|
||||
* @param propertyName
|
||||
* @param op
|
||||
* @param value
|
||||
*/
|
||||
void has(String propertyName, ComparisionOperator op, Object value);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 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.titan.query;
|
||||
|
||||
/**
|
||||
* Interface that indicates that something can create instances of
|
||||
* NativeTitanGraphQuery.
|
||||
*
|
||||
* @param <V>
|
||||
* @param <E>
|
||||
*/
|
||||
public interface NativeTitanQueryFactory<V,E> {
|
||||
|
||||
/**
|
||||
* Creates a NativeTitanGraphQuery
|
||||
* @return
|
||||
*/
|
||||
NativeTitanGraphQuery<V,E> createNativeTitanQuery();
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/**
|
||||
* 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.titan.query;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraph;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.expr.AndCondition;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.expr.HasPredicate;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.expr.InPredicate;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.expr.OrCondition;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Abstract implementation of AtlasGraphQuery that is used by both Titan 0.5.4
|
||||
* and Titan 1.0.0.
|
||||
*
|
||||
* Represents a graph query as an OrConditions which consists of
|
||||
* 1 or more AndConditions. The query is executed by converting
|
||||
* the AndConditions to native GraphQuery instances that can be executed
|
||||
* directly against Titan. The overall result is obtained by unioning together
|
||||
* the results from those individual GraphQueries.
|
||||
*
|
||||
* Here is a pictoral view of what is going on here. Conceptually,
|
||||
* the query being executed can be though of as the where clause
|
||||
* in a query
|
||||
*
|
||||
*
|
||||
* where (a =1 and b=2) or (a=2 and b=3)
|
||||
*
|
||||
* ||
|
||||
* \||/
|
||||
* \/
|
||||
*
|
||||
* OrCondition
|
||||
* |
|
||||
* +---------+--------+
|
||||
* | |
|
||||
* AndCondition AndCondition
|
||||
* (a=1 and b=2) (a=2 and b=3)
|
||||
*
|
||||
* || ||
|
||||
* \||/ \||/
|
||||
* \/ \/
|
||||
*
|
||||
* GraphQuery GraphQuery
|
||||
*
|
||||
* || ||
|
||||
* \||/ \||/
|
||||
* \/ \/
|
||||
*
|
||||
* vertices vertices
|
||||
* \ /
|
||||
* _\/ \/_
|
||||
* (UNION)
|
||||
*
|
||||
* ||
|
||||
* \||/
|
||||
* \/
|
||||
*
|
||||
* result
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class TitanGraphQuery<V,E> implements AtlasGraphQuery<V, E> {
|
||||
|
||||
private final Logger LOG = LoggerFactory.getLogger(TitanGraphQuery.class);
|
||||
protected final AtlasGraph<V,E> graph_;
|
||||
private final OrCondition queryCondition_ = new OrCondition();
|
||||
private final boolean isChildQuery_;
|
||||
protected abstract NativeTitanQueryFactory<V, E> getQueryFactory();
|
||||
|
||||
/**
|
||||
* Creates a TitanGraphQuery
|
||||
*
|
||||
* @param graph
|
||||
*/
|
||||
public TitanGraphQuery(AtlasGraph<V,E> graph) {
|
||||
graph_ = graph;
|
||||
isChildQuery_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TitanGraphQuery
|
||||
*
|
||||
* @param graph
|
||||
* @param isChildQuery
|
||||
*/
|
||||
public TitanGraphQuery(AtlasGraph<V,E> graph, boolean isChildQuery) {
|
||||
graph_ = graph;
|
||||
isChildQuery_ = isChildQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<V, E> has(String propertyKey, Object value) {
|
||||
queryCondition_.andWith(new HasPredicate(propertyKey, ComparisionOperator.EQUAL, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasVertex<V, E>> vertices() {
|
||||
LOG.debug("Executing: " );
|
||||
LOG.debug(queryCondition_.toString());
|
||||
//compute the overall result by unioning the results from all of the
|
||||
//AndConditions together.
|
||||
Set<AtlasVertex<V, E>> result = new HashSet<>();
|
||||
for(AndCondition andExpr : queryCondition_.getAndTerms()) {
|
||||
NativeTitanGraphQuery<V,E> andQuery = andExpr.create(getQueryFactory());
|
||||
for(AtlasVertex<V,E> vertex : andQuery.vertices()) {
|
||||
result.add(vertex);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<V, E> has(String propertyKey, ComparisionOperator operator,
|
||||
Object value) {
|
||||
queryCondition_.andWith(new HasPredicate(propertyKey, operator, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<V, E> in(String propertyKey, Collection<? extends Object> values) {
|
||||
queryCondition_.andWith(new InPredicate(propertyKey, values));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<V, E> or(List<AtlasGraphQuery<V, E>> childQueries) {
|
||||
|
||||
//Construct an overall OrCondition by combining all of the children for
|
||||
//the OrConditions in all of the childQueries that we passed in. Then, "and" the current
|
||||
//query condition with this overall OrCondition.
|
||||
|
||||
OrCondition overallChildQuery = new OrCondition(false);
|
||||
|
||||
for(AtlasGraphQuery<V, E> atlasChildQuery : childQueries) {
|
||||
if(! atlasChildQuery.isChildQuery()) {
|
||||
throw new IllegalArgumentException(atlasChildQuery + " is not a child query");
|
||||
}
|
||||
TitanGraphQuery<V,E> childQuery = (TitanGraphQuery<V,E>)atlasChildQuery;
|
||||
overallChildQuery.orWith(childQuery.getOrCondition());
|
||||
}
|
||||
|
||||
queryCondition_.andWith(overallChildQuery);
|
||||
return this;
|
||||
}
|
||||
|
||||
private OrCondition getOrCondition() {
|
||||
return queryCondition_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<V, E> addConditionsFrom(AtlasGraphQuery<V, E> otherQuery) {
|
||||
|
||||
TitanGraphQuery<V, E> childQuery = (TitanGraphQuery<V, E>)otherQuery;
|
||||
queryCondition_.andWith(childQuery.getOrCondition());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildQuery() {
|
||||
return isChildQuery_;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* 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.titan.query.expr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanQueryFactory;
|
||||
|
||||
/**
|
||||
* Represents an AndCondition in a graph query. Only vertices that
|
||||
* satisfy the conditions in all of the query predicates will be returned
|
||||
*
|
||||
* Represents a query with predicates that are 'AND'ed together. These can be
|
||||
* executed natively using Titan's GraphQuery mechanism.
|
||||
*/
|
||||
public class AndCondition {
|
||||
|
||||
private List<QueryPredicate> children_ = new ArrayList<>();
|
||||
|
||||
public AndCondition() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a query predicate that must be met by vertices
|
||||
* @param predicate
|
||||
*/
|
||||
public void andWith(QueryPredicate predicate) {
|
||||
children_.add(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple predicates that much be met by the vertices
|
||||
*
|
||||
* @param predicates
|
||||
*/
|
||||
public void andWith(List<QueryPredicate> predicates) {
|
||||
children_.addAll(predicates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of this AndExpr.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public AndCondition copy() {
|
||||
AndCondition builder = new AndCondition();
|
||||
builder.children_.addAll(children_);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the query predicates
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<QueryPredicate> getTerms() {
|
||||
return children_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NativeTitanGraphQuery that can be used to evaluate this condition.
|
||||
*
|
||||
* @param graph
|
||||
* @return
|
||||
*/
|
||||
public <V,E> NativeTitanGraphQuery<V, E> create(NativeTitanQueryFactory<V,E> factory) {
|
||||
NativeTitanGraphQuery<V, E> query = factory.createNativeTitanQuery();
|
||||
for (QueryPredicate predicate : children_) {
|
||||
predicate.addTo(query);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AndExpr [predicates=" + children_ + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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.titan.query.expr;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
|
||||
/**
|
||||
* Query predicate that checks whether the given property has the specified
|
||||
* relationship with the value specified.
|
||||
*/
|
||||
public class HasPredicate implements QueryPredicate {
|
||||
|
||||
private String propertyName_;
|
||||
private ComparisionOperator op_;
|
||||
private Object value_;
|
||||
|
||||
public HasPredicate(String propertyName, ComparisionOperator op, Object value) {
|
||||
super();
|
||||
propertyName_ = propertyName;
|
||||
op_ = op;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTo(NativeTitanGraphQuery query) {
|
||||
query.has(propertyName_, op_, value_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HasTerm [propertyName_=" + propertyName_ + ", op_=" + op_ + ", value_=" + value_ + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* 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.titan.query.expr;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
|
||||
/**
|
||||
* Query predicate that checks whether the value of a given property is within the
|
||||
* provided set of allowed values.
|
||||
*/
|
||||
public class InPredicate implements QueryPredicate {
|
||||
|
||||
private String propertyName_;
|
||||
private Collection<? extends Object> values_;
|
||||
|
||||
public InPredicate(String propertyName, Collection<? extends Object> values) {
|
||||
super();
|
||||
propertyName_ = propertyName;
|
||||
values_ = values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTo(NativeTitanGraphQuery query) {
|
||||
query.in(propertyName_, values_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InPredicate [propertyName_=" + propertyName_ + ", values_=" + values_ + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* 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.titan.query.expr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents an OrCondition that has one or more AndConditions as it children. The OrCondition
|
||||
* matches vertices that meet the criteria in at least one of its children. The overall query result is
|
||||
* computed by executing the TitanGraphQuery queries that correspond to each AndCondition individually and
|
||||
* then unioning their results together. This is needed because the native Titan query mechanism does not
|
||||
* natively support 'OR' conditions. When we execute the query, we accomplish the 'OR' by executing all of the
|
||||
* individual queries and unioning the results together.
|
||||
*
|
||||
*/
|
||||
public class OrCondition {
|
||||
|
||||
private List<AndCondition> children_;
|
||||
|
||||
public OrCondition() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
private OrCondition(List<AndCondition> children) {
|
||||
children_ = children;
|
||||
}
|
||||
|
||||
public OrCondition(boolean addInitialTerm) {
|
||||
children_ = new ArrayList<AndCondition>();
|
||||
if (addInitialTerm) {
|
||||
children_.add(new AndCondition());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Updates this OrCondition in place so that it matches vertices that satisfy the current
|
||||
* OrCondition AND that match the specified predicate.
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public void andWith(QueryPredicate predicate) {
|
||||
|
||||
for (AndCondition child : children_) {
|
||||
child.andWith(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
public List<AndCondition> getAndTerms() {
|
||||
return children_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this OrCondition in place so that it matches vertices that satisfy the current
|
||||
* OrCondition AND that satisfy the provided OrCondition
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public void andWith(OrCondition other) {
|
||||
|
||||
//Because Titan does not natively support Or conditions in Graph Queries,
|
||||
//we need to expand out the condition so it is in the form of a single OrCondition
|
||||
//that contains only AndConditions. We do this by following the rules of boolean
|
||||
//algebra. As an example, suppose the current condition is ((a=1 and b=2) or (c=3 and d=4)).
|
||||
//Suppose "other" is ((e=5 and f=6) or (g=7 or h=8)). The overall condition, after applying the
|
||||
//"and" is:
|
||||
//
|
||||
//((a=1 and b=2) or (c=3 and d=4)) and ((e=5 and f=6) or (g=7 and h=8))
|
||||
//
|
||||
//This needs to be expanded out to remove the nested or clauses. The result of this expansion is:
|
||||
//
|
||||
//(a=1 and b=2 and e=5 and f=6) or
|
||||
//(a=1 and b=2 and g=7 and h=8) or
|
||||
//(c=3 and d=4 and e=5 and f=6) or
|
||||
//(c=3 and d=4 and g=7 and h=8)
|
||||
|
||||
//The logic below does this expansion, in a generalized way. It loops through the existing AndConditions
|
||||
//and, in a nested loop, through the AndConditions in "other". For each of those combinations,
|
||||
//it creates a new AndCondition that combines the two AndConditions together. These combined
|
||||
//AndConditions become the new set of AndConditions in this OrCondition.
|
||||
|
||||
List<AndCondition> expandedExpressionChildren = new ArrayList<AndCondition>();
|
||||
for (AndCondition otherExprTerm : other.getAndTerms()) {
|
||||
for (AndCondition currentExpr : children_) {
|
||||
AndCondition currentAndConditionCopy = currentExpr.copy();
|
||||
currentAndConditionCopy.andWith(otherExprTerm.getTerms());
|
||||
expandedExpressionChildren.add(currentAndConditionCopy);
|
||||
}
|
||||
}
|
||||
children_ = expandedExpressionChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this OrCondition in place so that it matches vertices that satisfy the current
|
||||
* OrCondition OR that satisfy the provided OrCondition
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public void orWith(OrCondition other) {
|
||||
children_.addAll(other.getAndTerms());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("OrCondition [andExprs=");
|
||||
Iterator<AndCondition> it = children_.iterator();
|
||||
while (it.hasNext()) {
|
||||
AndCondition andExpr = it.next();
|
||||
builder.append(andExpr.toString());
|
||||
if (it.hasNext()) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 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.titan.query.expr;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
|
||||
/**
|
||||
* Represents a predicate in an AndExpression
|
||||
*/
|
||||
public interface QueryPredicate {
|
||||
|
||||
/**
|
||||
* Adds the query term to a NativeTitanGraphQuery that is being generated.
|
||||
*
|
||||
* @param query
|
||||
*/
|
||||
void addTo(NativeTitanGraphQuery query);
|
||||
}
|
||||
|
|
@ -32,5 +32,7 @@
|
|||
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>titan0</module>
|
||||
<module>common</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,257 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>atlas-graphdb</artifactId>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<version>0.8-incubating-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>atlas-graphdb-titan0</artifactId>
|
||||
<description>Apache Atlas Titan 0.5.4 Graph DB Impl</description>
|
||||
<name>Apache Atlas Titan 0.5.4 Graph DB Impl</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<tinkerpop.version>2.6.0</tinkerpop.version>
|
||||
<titan.version>0.5.4</titan.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- for graphdb interface definitions -->
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-core</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.gremlin</groupId>
|
||||
<artifactId>gremlin-java</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hbase</groupId>
|
||||
<artifactId>hbase-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.vividsolutions</groupId>
|
||||
<artifactId>jts</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-es</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-berkeleyje</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-lucene</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!--
|
||||
Create 'uber' jar that contains all of the dependencies (except those whose scope is provided)
|
||||
Only Titan 0l5l4 and its dependencies are included. The other dependencies are bundled in the war file.
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<!-- these are bundled with Atlas -->
|
||||
<exclude>org.slf4j:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>com.thinkaurelius.titan:titan-core</artifact>
|
||||
<!-- force use of our custom LocalLockMediator implementation -->
|
||||
<excludes>
|
||||
<exclude>com/thinkaurelius/titan/diskstorage/locking/LocalLockMediator*</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
|
||||
</filters>
|
||||
<createSourcesJar>true</createSourcesJar>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/log4j.xml</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- Graph DB -->
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-core</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
<exclusions>
|
||||
<!-- rexster does not work with servlet-api -->
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop.rexster</groupId>
|
||||
<artifactId>rexster-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop.rexster</groupId>
|
||||
<artifactId>rexster-server</artifactId>
|
||||
</exclusion>
|
||||
<!-- asm 4.0 does not work with jersey asm 3.1 -->
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop</groupId>
|
||||
<artifactId>frames</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.esotericsoftware.reflectasm</groupId>
|
||||
<artifactId>reflectasm</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</exclusion>
|
||||
<exclusion> <!-- GPL license imported from ganglia -->
|
||||
<groupId>org.acplt</groupId>
|
||||
<artifactId>oncrpc</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-berkeleyje</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-hbase</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
|
||||
import org.apache.atlas.repository.graphdb.titan0.query.Titan0GraphQuery;
|
||||
|
||||
import com.thinkaurelius.titan.core.PropertyKey;
|
||||
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Factory that serves up instances of graph database abstraction layer classes
|
||||
* that correspond to Titan/Tinkerpop classes.
|
||||
*/
|
||||
public final class GraphDbObjectFactory {
|
||||
|
||||
private GraphDbObjectFactory() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Titan0Edge that corresponds to the given Gremlin Edge.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static Titan0Edge createEdge(Titan0Graph graph, Edge source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return new Titan0Edge(graph, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Titan0GraphQuery that corresponds to the given GraphQuery.
|
||||
* @param source
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Titan0GraphQuery createQuery(Titan0Graph graph) {
|
||||
|
||||
return new Titan0GraphQuery(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Titan0Vertex that corresponds to the given Gremlin Vertex.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static Titan0Vertex createVertex(Titan0Graph graph, Vertex source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return new Titan0Vertex(graph, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param propertyKey
|
||||
* @return
|
||||
*/
|
||||
public static Titan0PropertyKey createPropertyKey(PropertyKey propertyKey) {
|
||||
if (propertyKey == null) {
|
||||
return null;
|
||||
}
|
||||
return new Titan0PropertyKey(propertyKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public static AtlasGraphIndex createGraphIndex(TitanGraphIndex index) {
|
||||
if (index == null) {
|
||||
return null;
|
||||
}
|
||||
return new Titan0GraphIndex(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.commons.configuration.Configuration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
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.diskstorage.StandardIndexProvider;
|
||||
import com.thinkaurelius.titan.diskstorage.solr.Solr5Index;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of GraphDatabase.
|
||||
*/
|
||||
public class Titan0Database implements GraphDatabase<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Titan0Database.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 TitanGraph graphInstance;
|
||||
|
||||
public static Configuration getConfiguration() throws AtlasException {
|
||||
Configuration configProperties = ApplicationProperties.get();
|
||||
return ApplicationProperties.getSubsetConfiguration(configProperties, GRAPH_PREFIX);
|
||||
}
|
||||
|
||||
static {
|
||||
addSolr5Index();
|
||||
}
|
||||
|
||||
/**
|
||||
* Titan loads index backend name to implementation using
|
||||
* StandardIndexProvider.ALL_MANAGER_CLASSES But
|
||||
* StandardIndexProvider.ALL_MANAGER_CLASSES is a private static final
|
||||
* ImmutableMap Only way to inject Solr5Index is to modify this field. So,
|
||||
* using hacky reflection to add Sol5Index
|
||||
*/
|
||||
private static void addSolr5Index() {
|
||||
try {
|
||||
Field field = StandardIndexProvider.class.getDeclaredField("ALL_MANAGER_CLASSES");
|
||||
field.setAccessible(true);
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
Map<String, String> customMap = new HashMap<>(StandardIndexProvider.getAllProviderClasses());
|
||||
customMap.put("solr", Solr5Index.class.getName()); // for
|
||||
// consistency
|
||||
// with Titan
|
||||
// 1.0.0
|
||||
customMap.put("solr5", Solr5Index.class.getName()); // for backward
|
||||
// compatibility
|
||||
ImmutableMap<String, String> immap = ImmutableMap.copyOf(customMap);
|
||||
field.set(null, immap);
|
||||
|
||||
LOG.debug("Injected solr5 index - {}", Solr5Index.class.getName());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static TitanGraph getGraphInstance() {
|
||||
if (graphInstance == null) {
|
||||
synchronized (Titan0Database.class) {
|
||||
if (graphInstance == null) {
|
||||
Configuration config;
|
||||
try {
|
||||
config = getConfiguration();
|
||||
} catch (AtlasException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
graphInstance = TitanFactory.open(config);
|
||||
validateIndexBackend(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return graphInstance;
|
||||
}
|
||||
|
||||
public static void unload() {
|
||||
|
||||
synchronized (Titan0Database.class) {
|
||||
if (graphInstance == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
graphInstance.commit();
|
||||
//shutdown invalidates the graph instance
|
||||
graphInstance.shutdown();
|
||||
graphInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
static void validateIndexBackend(Configuration config) {
|
||||
String configuredIndexBackend = config.getString(INDEX_BACKEND_CONF);
|
||||
TitanManagement managementSystem = null;
|
||||
|
||||
try {
|
||||
managementSystem = getGraphInstance().getManagementSystem();
|
||||
String currentIndexBackend = managementSystem.get(INDEX_BACKEND_CONF);
|
||||
|
||||
if (!equals(configuredIndexBackend, currentIndexBackend)) {
|
||||
throw new RuntimeException("Configured Index Backend " + configuredIndexBackend
|
||||
+ " differs from earlier configured Index Backend " + currentIndexBackend + ". Aborting!");
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (managementSystem != null) {
|
||||
managementSystem.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static boolean equals(Object o1, Object o2) {
|
||||
if (o1 == null) {
|
||||
return o2 == null;
|
||||
}
|
||||
return o1.equals(o2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraph<Titan0Vertex, Titan0Edge> getGraph() {
|
||||
// force graph loading up front to avoid bootstrapping
|
||||
// issues
|
||||
getGraphInstance();
|
||||
return new Titan0Graph();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGraphLoaded() {
|
||||
return graphInstance != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initializeTestGraph() {
|
||||
|
||||
//nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTestGraph() {
|
||||
try {
|
||||
getGraphInstance().shutdown();
|
||||
}
|
||||
catch(Throwable t) {
|
||||
LOG.warn("Could not shutdown test TitanGraph", t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
TitanCleanup.clear(getGraphInstance());
|
||||
}
|
||||
catch(Throwable t) {
|
||||
LOG.warn("Could not clear test TitanGraph", t);
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
|
||||
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
|
||||
import org.apache.atlas.typesystem.types.Multiplicity;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.thinkaurelius.titan.core.Cardinality;
|
||||
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.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Element;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasGraphManagement.
|
||||
*/
|
||||
public class Titan0DatabaseManager implements AtlasGraphManagement {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Titan0DatabaseManager.class);
|
||||
|
||||
private TitanManagement management;
|
||||
|
||||
public Titan0DatabaseManager(TitanManagement managementSystem) {
|
||||
|
||||
management = managementSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildMixedVertexIndex(String index, String backingIndex) {
|
||||
buildMixedIndex(index, Vertex.class, backingIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildMixedEdgeIndex(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 propertyKey) {
|
||||
return management.containsPropertyKey(propertyKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
management.rollback();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
management.commit();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasGraphManagement#makePropertyKey(
|
||||
* java.lang.String, java.lang.Class,
|
||||
* org.apache.atlas.typesystem.types.Multiplicity)
|
||||
*/
|
||||
@Override
|
||||
public AtlasPropertyKey makePropertyKey(String propertyName, Class propertyClass, Multiplicity multiplicity) {
|
||||
|
||||
PropertyKeyMaker propertyKeyBuilder = management.makePropertyKey(propertyName).dataType(propertyClass);
|
||||
|
||||
if (multiplicity != null) {
|
||||
Cardinality cardinality = TitanObjectFactory.createCardinality(multiplicity);
|
||||
propertyKeyBuilder.cardinality(cardinality);
|
||||
}
|
||||
PropertyKey propertyKey = propertyKeyBuilder.make();
|
||||
return GraphDbObjectFactory.createPropertyKey(propertyKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasGraphManagement#getPropertyKey(
|
||||
* java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public AtlasPropertyKey getPropertyKey(String propertyName) {
|
||||
|
||||
return GraphDbObjectFactory.createPropertyKey(management.getPropertyKey(propertyName));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphManagement#
|
||||
* createCompositeIndex(java.lang.String,
|
||||
* org.apache.atlas.repository.graphdb.AtlasPropertyKey, boolean)
|
||||
*/
|
||||
@Override
|
||||
public void createCompositeIndex(String propertyName, AtlasPropertyKey propertyKey, boolean enforceUniqueness) {
|
||||
PropertyKey titanKey = TitanObjectFactory.createPropertyKey(propertyKey);
|
||||
TitanManagement.IndexBuilder indexBuilder = management.buildIndex(propertyName, Vertex.class).addKey(titanKey);
|
||||
if (enforceUniqueness) {
|
||||
indexBuilder.unique();
|
||||
}
|
||||
indexBuilder.buildCompositeIndex();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasGraphManagement#addIndexKey(java
|
||||
* .lang.String, org.apache.atlas.repository.graphdb.AtlasPropertyKey)
|
||||
*/
|
||||
@Override
|
||||
public void addIndexKey(String indexName, AtlasPropertyKey propertyKey) {
|
||||
PropertyKey titanKey = TitanObjectFactory.createPropertyKey(propertyKey);
|
||||
TitanGraphIndex vertexIndex = management.getGraphIndex(indexName);
|
||||
management.addIndexKey(vertexIndex, titanKey);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasGraphManagement#getGraphIndex(
|
||||
* java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public AtlasGraphIndex getGraphIndex(String indexName) {
|
||||
TitanGraphIndex index = management.getGraphIndex(indexName);
|
||||
return GraphDbObjectFactory.createGraphIndex(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdge;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
|
||||
import com.tinkerpop.blueprints.Direction;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasEdge.
|
||||
*/
|
||||
public class Titan0Edge extends Titan0Element<Edge> implements AtlasEdge<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
|
||||
public Titan0Edge(Titan0Graph graph, Edge edge) {
|
||||
super(graph, edge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return wrappedElement.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Titan0Edge getE() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> getInVertex() {
|
||||
Vertex v = wrappedElement.getVertex(Direction.IN);
|
||||
return GraphDbObjectFactory.createVertex(graph, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> getOutVertex() {
|
||||
Vertex v = wrappedElement.getVertex(Direction.OUT);
|
||||
return GraphDbObjectFactory.createVertex(graph, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Titan0Edge [id=" + getId() + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
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.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;
|
||||
import com.tinkerpop.blueprints.Element;
|
||||
import com.tinkerpop.blueprints.util.io.graphson.GraphSONMode;
|
||||
import com.tinkerpop.blueprints.util.io.graphson.GraphSONUtility;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasElement.
|
||||
*/
|
||||
public class Titan0Element<T extends Element> implements AtlasElement {
|
||||
|
||||
protected Titan0Graph graph;
|
||||
protected T wrappedElement;
|
||||
|
||||
public Titan0Element(Titan0Graph graph, T element) {
|
||||
wrappedElement = element;
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getId() {
|
||||
return wrappedElement.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getPropertyKeys() {
|
||||
return wrappedElement.getPropertyKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> void setProperty(String propertyName, U value) {
|
||||
try {
|
||||
wrappedElement.setProperty(propertyName, value);
|
||||
} catch (SchemaViolationException e) {
|
||||
throw new AtlasSchemaViolationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <U> U getProperty(String propertyName, Class<U> clazz) {
|
||||
return (U)convert(wrappedElement.getProperty(propertyName), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void removeProperty(String propertyName) {
|
||||
wrappedElement.removeProperty(propertyName);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject toJson(Set<String> propertyKeys) throws JSONException {
|
||||
return GraphSONUtility.jsonFromElement(wrappedElement, propertyKeys, GraphSONMode.NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasElement#getListProperty(java.
|
||||
* lang.String)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getListProperty(String propertyName) {
|
||||
return getProperty(propertyName, List.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasElement#setListProperty(java.
|
||||
* lang.String, java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public void setListProperty(String propertyName, List<String> values) {
|
||||
setProperty(propertyName, values);
|
||||
|
||||
}
|
||||
|
||||
// not in interface
|
||||
public T getWrappedElement() {
|
||||
return wrappedElement;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
Titan0Element otherElement = (Titan0Element) other;
|
||||
return getWrappedElement().equals(otherElement.getWrappedElement());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasElement#exists()
|
||||
*/
|
||||
@Override
|
||||
public boolean exists() {
|
||||
try {
|
||||
return ! ((TitanElement)wrappedElement).isRemoved();
|
||||
}
|
||||
catch(IllegalStateException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasElement#setJsonProperty(java.
|
||||
* lang.String, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public <T> void setJsonProperty(String propertyName, T value) {
|
||||
setProperty(propertyName, value);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasElement#getJsonProperty(java.
|
||||
* lang.String)
|
||||
*/
|
||||
@Override
|
||||
public <T> T getJsonProperty(String propertyName) {
|
||||
return (T) getProperty(propertyName, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdForDisplay() {
|
||||
return getId().toString();
|
||||
}
|
||||
|
||||
private <T> T convert(Object propertyValue, Class<T> clazz) {
|
||||
if(propertyValue == null) {
|
||||
return null;
|
||||
}
|
||||
if(AtlasEdge.class.isAssignableFrom(clazz)) {
|
||||
return (T)graph.getEdge(propertyValue.toString());
|
||||
}
|
||||
if(AtlasVertex.class.isAssignableFrom(clazz)) {
|
||||
return (T)graph.getVertex(propertyValue.toString());
|
||||
}
|
||||
return (T)propertyValue;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <V> List<V> getListProperty(String propertyName, Class<V> elementType) {
|
||||
|
||||
List<String> value = getListProperty(propertyName);
|
||||
|
||||
if(value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
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 element: values) {
|
||||
propertyValue.add(element.getId().toString());
|
||||
}
|
||||
setProperty(propertyName, propertyValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setPropertyFromElementId(String propertyName, AtlasElement value) {
|
||||
setProperty(propertyName, value.getId().toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isIdAssigned() {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdge;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraph;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.AtlasIndexQuery;
|
||||
import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.graphdb.GremlinVersion;
|
||||
import org.apache.atlas.repository.graphdb.titan0.query.Titan0GraphQuery;
|
||||
import org.apache.atlas.typesystem.types.IDataType;
|
||||
import org.apache.atlas.utils.IteratorToIterableAdapter;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.thinkaurelius.titan.core.SchemaViolationException;
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
import com.thinkaurelius.titan.core.TitanIndexQuery;
|
||||
import com.thinkaurelius.titan.core.util.TitanCleanup;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Element;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
import com.tinkerpop.blueprints.util.io.graphson.GraphSONWriter;
|
||||
import com.tinkerpop.pipes.util.structures.Row;
|
||||
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasGraph.
|
||||
*/
|
||||
public class Titan0Graph implements AtlasGraph<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
public Titan0Graph() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasEdge<Titan0Vertex, Titan0Edge> addEdge(AtlasVertex<Titan0Vertex, Titan0Edge> outVertex,
|
||||
AtlasVertex<Titan0Vertex, Titan0Edge> inVertex, String edgeLabel) {
|
||||
try {
|
||||
Edge edge = getGraph().addEdge(null, outVertex.getV().getWrappedElement(),
|
||||
inVertex.getV().getWrappedElement(), edgeLabel);
|
||||
return GraphDbObjectFactory.createEdge(this, edge);
|
||||
} catch (SchemaViolationException e) {
|
||||
throw new AtlasSchemaViolationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<Titan0Vertex, Titan0Edge> query() {
|
||||
|
||||
return new Titan0GraphQuery(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasEdge<Titan0Vertex, Titan0Edge> getEdge(String edgeId) {
|
||||
Edge edge = getGraph().getEdge(edgeId);
|
||||
return GraphDbObjectFactory.createEdge(this, edge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEdge(AtlasEdge<Titan0Vertex, Titan0Edge> edge) {
|
||||
getGraph().removeEdge(edge.getE().getWrappedElement());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVertex(AtlasVertex<Titan0Vertex, Titan0Edge> vertex) {
|
||||
getGraph().removeVertex(vertex.getV().getWrappedElement());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> getEdges() {
|
||||
Iterable<Edge> edges = getGraph().getEdges();
|
||||
return wrapEdges(edges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasVertex<Titan0Vertex, Titan0Edge>> getVertices() {
|
||||
Iterable<Vertex> vertices = getGraph().getVertices();
|
||||
return wrapVertices(vertices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> addVertex() {
|
||||
Vertex result = getGraph().addVertex(null);
|
||||
return GraphDbObjectFactory.createVertex(this, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
getGraph().commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
getGraph().rollback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasIndexQuery<Titan0Vertex, Titan0Edge> indexQuery(String fulltextIndex, String graphQuery) {
|
||||
TitanIndexQuery query = getGraph().indexQuery(fulltextIndex, graphQuery);
|
||||
return new Titan0IndexQuery(this, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphManagement getManagementSystem() {
|
||||
return new Titan0DatabaseManager(getGraph().getManagementSystem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
getGraph().shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getVertexIndexKeys() {
|
||||
return getIndexKeys(Vertex.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getEdgeIndexKeys() {
|
||||
return getIndexKeys(Edge.class);
|
||||
}
|
||||
|
||||
private Set<String> getIndexKeys(Class<? extends Element> titanClass) {
|
||||
|
||||
return getGraph().getIndexedKeys(titanClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> getVertex(String vertexId) {
|
||||
Vertex v = getGraph().getVertex(vertexId);
|
||||
return GraphDbObjectFactory.createVertex(this, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasVertex<Titan0Vertex, Titan0Edge>> getVertices(String key, Object value) {
|
||||
|
||||
Iterable<Vertex> result = getGraph().getVertices(key, value);
|
||||
return wrapVertices(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGremlinColumnValue(Object rowValue, String colName, int idx) {
|
||||
Row<List> rV = (Row<List>) rowValue;
|
||||
Object value = rV.getColumn(colName).get(idx);
|
||||
return convertGremlinValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertGremlinValue(Object rawValue) {
|
||||
if (rawValue instanceof Vertex) {
|
||||
return GraphDbObjectFactory.createVertex(this, (Vertex) rawValue);
|
||||
}
|
||||
if (rawValue instanceof Edge) {
|
||||
return GraphDbObjectFactory.createEdge(this, (Edge) rawValue);
|
||||
}
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GremlinVersion getSupportedGremlinVersion() {
|
||||
|
||||
return GremlinVersion.TWO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> convertPathQueryResultToList(Object rawValue) {
|
||||
return (List<Object>) rawValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
TitanGraph graph = getGraph();
|
||||
if (graph.isOpen()) {
|
||||
// only a shut down graph can be cleared
|
||||
graph.shutdown();
|
||||
}
|
||||
TitanCleanup.clear(graph);
|
||||
}
|
||||
|
||||
private TitanGraph getGraph() {
|
||||
// return the singleton instance of the graph in the plugin
|
||||
return Titan0Database.getGraphInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportToGson(OutputStream os) throws IOException {
|
||||
GraphSONWriter.outputGraph(getGraph(), os);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.apache.atlas.repository.graphdb.AtlasGraph#executeGremlinScript(java.
|
||||
* lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object executeGremlinScript(String gremlinQuery) throws ScriptException {
|
||||
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("gremlin-groovy");
|
||||
Bindings bindings = engine.createBindings();
|
||||
bindings.put("g", getGraph());
|
||||
Object result = engine.eval(gremlinQuery, bindings);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generatePersisentToLogicalConversionExpression(String expr, IDataType<?> type) {
|
||||
|
||||
//nothing special needed, value is stored in required type
|
||||
return expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPropertyValueConversionNeeded(IDataType<?> type) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresInitialIndexedPredicate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitialIndexedPredicate() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOutputTransformationPredicate(boolean inSelect, boolean isPath) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> wrapEdges(Iterator<Edge> it) {
|
||||
|
||||
Iterable<Edge> iterable = new IteratorToIterableAdapter<Edge>(it);
|
||||
return wrapEdges(iterable);
|
||||
}
|
||||
|
||||
public Iterable<AtlasVertex<Titan0Vertex, Titan0Edge>> wrapVertices(Iterator<Vertex> it) {
|
||||
Iterable<Vertex> iterable = new IteratorToIterableAdapter<Vertex>(it);
|
||||
return wrapVertices(iterable);
|
||||
}
|
||||
|
||||
public Iterable<AtlasVertex<Titan0Vertex, Titan0Edge>> wrapVertices(Iterable<Vertex> it) {
|
||||
|
||||
return Iterables.transform(it, new Function<Vertex, AtlasVertex<Titan0Vertex, Titan0Edge>>(){
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> apply(Vertex input) {
|
||||
return GraphDbObjectFactory.createVertex(Titan0Graph.this, input);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> wrapEdges(Iterable<Edge> it) {
|
||||
Iterable<Edge> result = (Iterable<Edge>)it;
|
||||
return Iterables.transform(result, new Function<Edge, AtlasEdge<Titan0Vertex, Titan0Edge>>(){
|
||||
|
||||
@Override
|
||||
public AtlasEdge<Titan0Vertex, Titan0Edge> apply(Edge input) {
|
||||
return GraphDbObjectFactory.createEdge(Titan0Graph.this, input);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphIndex;
|
||||
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
|
||||
|
||||
import com.thinkaurelius.titan.core.PropertyKey;
|
||||
import com.thinkaurelius.titan.core.schema.TitanGraphIndex;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasGraphIndex.
|
||||
*/
|
||||
public class Titan0GraphIndex implements AtlasGraphIndex {
|
||||
|
||||
private TitanGraphIndex wrappedIndex;
|
||||
|
||||
public Titan0GraphIndex(TitanGraphIndex toWrap) {
|
||||
wrappedIndex = toWrap;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isMixedIndex()
|
||||
*/
|
||||
@Override
|
||||
public boolean isMixedIndex() {
|
||||
return wrappedIndex.isMixedIndex();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isEdgeIndex()
|
||||
*/
|
||||
@Override
|
||||
public boolean isEdgeIndex() {
|
||||
return Edge.class.isAssignableFrom(wrappedIndex.getIndexedElement());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isVertexIndex()
|
||||
*/
|
||||
@Override
|
||||
public boolean isVertexIndex() {
|
||||
return Vertex.class.isAssignableFrom(wrappedIndex.getIndexedElement());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isCompositeIndex()
|
||||
*/
|
||||
@Override
|
||||
public boolean isCompositeIndex() {
|
||||
return wrappedIndex.isCompositeIndex();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isUnique()
|
||||
*/
|
||||
@Override
|
||||
public boolean isUnique() {
|
||||
return wrappedIndex.isUnique();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#getFieldKeys()
|
||||
*/
|
||||
@Override
|
||||
public Set<AtlasPropertyKey> getFieldKeys() {
|
||||
PropertyKey[] keys = wrappedIndex.getFieldKeys();
|
||||
Set<AtlasPropertyKey> result = new HashSet<AtlasPropertyKey>();
|
||||
for(PropertyKey key : keys) {
|
||||
result.add(GraphDbObjectFactory.createPropertyKey(key));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
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.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasIndexQuery.
|
||||
*/
|
||||
public class Titan0IndexQuery implements AtlasIndexQuery<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
private Titan0Graph graph;
|
||||
private TitanIndexQuery wrappedIndexQuery;
|
||||
|
||||
|
||||
public Titan0IndexQuery(Titan0Graph graph, TitanIndexQuery query) {
|
||||
wrappedIndexQuery = query;
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<AtlasIndexQuery.Result<Titan0Vertex, Titan0Edge>> vertices() {
|
||||
Iterator<TitanIndexQuery.Result<Vertex>> results = wrappedIndexQuery.vertices().iterator();
|
||||
|
||||
Function<TitanIndexQuery.Result<Vertex>, AtlasIndexQuery.Result<Titan0Vertex, Titan0Edge>> function =
|
||||
new Function<TitanIndexQuery.Result<Vertex>, AtlasIndexQuery.Result<Titan0Vertex, Titan0Edge>>() {
|
||||
|
||||
@Override
|
||||
public AtlasIndexQuery.Result<Titan0Vertex, Titan0Edge> apply(TitanIndexQuery.Result<Vertex> source) {
|
||||
return new ResultImpl(source);
|
||||
}
|
||||
};
|
||||
return Iterators.transform(results, function);
|
||||
}
|
||||
|
||||
private final class ResultImpl implements AtlasIndexQuery.Result<Titan0Vertex, Titan0Edge> {
|
||||
private TitanIndexQuery.Result<Vertex> wrappedResult;
|
||||
|
||||
public ResultImpl(TitanIndexQuery.Result<Vertex> source) {
|
||||
wrappedResult = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertex<Titan0Vertex, Titan0Edge> getVertex() {
|
||||
return GraphDbObjectFactory.createVertex(graph, wrappedResult.getElement());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getScore() {
|
||||
return wrappedResult.getScore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
|
||||
|
||||
import com.thinkaurelius.titan.core.PropertyKey;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementaiton of AtlasPropertyKey.
|
||||
*/
|
||||
public class Titan0PropertyKey implements AtlasPropertyKey {
|
||||
|
||||
private PropertyKey wrappedPropertyKey;
|
||||
|
||||
public Titan0PropertyKey(PropertyKey toWrap) {
|
||||
wrappedPropertyKey = toWrap;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.apache.atlas.repository.graphdb.AtlasPropertyKey#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return wrappedPropertyKey.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public PropertyKey getWrappedPropertyKey() {
|
||||
return wrappedPropertyKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof Titan0PropertyKey)) {
|
||||
return false;
|
||||
}
|
||||
Titan0PropertyKey otherKey = (Titan0PropertyKey) other;
|
||||
return wrappedPropertyKey.equals(otherKey.wrappedPropertyKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 37 * result + wrappedPropertyKey.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdge;
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
|
||||
import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertexQuery;
|
||||
|
||||
import com.thinkaurelius.titan.core.SchemaViolationException;
|
||||
import com.thinkaurelius.titan.core.TitanProperty;
|
||||
import com.thinkaurelius.titan.core.TitanVertex;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasVertex.
|
||||
*/
|
||||
public class Titan0Vertex extends Titan0Element<Vertex> implements AtlasVertex<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
public Titan0Vertex(Titan0Graph graph, Vertex source) {
|
||||
super(graph, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> getEdges(AtlasEdgeDirection dir, String edgeLabel) {
|
||||
Iterable<Edge> titanEdges = wrappedElement.getEdges(TitanObjectFactory.createDirection(dir), edgeLabel);
|
||||
return graph.wrapEdges(titanEdges);
|
||||
}
|
||||
|
||||
private TitanVertex getAsTitanVertex() {
|
||||
return (TitanVertex) wrappedElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> getEdges(AtlasEdgeDirection in) {
|
||||
Iterable<Edge> titanResult = wrappedElement.getEdges(TitanObjectFactory.createDirection(in));
|
||||
return graph.wrapEdges(titanResult);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getProperty(String propertyName, Class<T> clazz) {
|
||||
|
||||
if (AtlasGraphManagement.MULTIPLICITY_MANY_PROPERTY_KEYS.contains(propertyName)) {
|
||||
// throw exception in this case to be consistent with Titan 1.0.0
|
||||
// behavior.
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return super.getProperty(propertyName, clazz);
|
||||
}
|
||||
|
||||
public <T> void setProperty(String propertyName, T value) {
|
||||
|
||||
try {
|
||||
super.setProperty(propertyName, value);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// For consistency with Titan 1.0.0, treat sets of multiplicity many
|
||||
// properties as adds. Handle this here since this is an uncommon
|
||||
// occurrence.
|
||||
if (AtlasGraphManagement.MULTIPLICITY_MANY_PROPERTY_KEYS.contains(propertyName)) {
|
||||
addProperty(propertyName, value);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addProperty(String propertyName, T value) {
|
||||
try {
|
||||
getAsTitanVertex().addProperty(propertyName, value);
|
||||
} catch (SchemaViolationException e) {
|
||||
if (getPropertyValues(propertyName, value.getClass()).contains(value)) {
|
||||
// follow java set semantics, don't throw an exception if
|
||||
// value is already there.
|
||||
return;
|
||||
}
|
||||
throw new AtlasSchemaViolationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Collection<T> getPropertyValues(String key, Class<T> clazz) {
|
||||
|
||||
TitanVertex tv = getAsTitanVertex();
|
||||
Collection<T> result = new ArrayList<T>();
|
||||
for (TitanProperty property : tv.getProperties(key)) {
|
||||
result.add((T) property.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertexQuery<Titan0Vertex, Titan0Edge> query() {
|
||||
return new Titan0VertexQuery(graph, wrappedElement.query());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Titan0Vertex getV() {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Titan0Vertex [id=" + getId() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
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.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
import com.tinkerpop.blueprints.VertexQuery;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasVertexQuery.
|
||||
*/
|
||||
public class Titan0VertexQuery implements AtlasVertexQuery<Titan0Vertex, Titan0Edge> {
|
||||
|
||||
private Titan0Graph graph;
|
||||
private VertexQuery vertexQuery;
|
||||
|
||||
public Titan0VertexQuery(Titan0Graph graph, VertexQuery vertexQuery) {
|
||||
this.vertexQuery = vertexQuery;
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasVertexQuery<Titan0Vertex, Titan0Edge> direction(AtlasEdgeDirection queryDirection) {
|
||||
vertexQuery.direction(TitanObjectFactory.createDirection(queryDirection));
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasVertex<Titan0Vertex, Titan0Edge>> vertices() {
|
||||
Iterable<Vertex> vertices = vertexQuery.vertices();
|
||||
return graph.wrapVertices(vertices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> edges() {
|
||||
Iterable<Edge> edges = vertexQuery.edges();
|
||||
return graph.wrapEdges(edges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return vertexQuery.count();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
|
||||
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
|
||||
import org.apache.atlas.typesystem.types.Multiplicity;
|
||||
|
||||
import com.thinkaurelius.titan.core.Cardinality;
|
||||
import com.thinkaurelius.titan.core.PropertyKey;
|
||||
import com.tinkerpop.blueprints.Direction;
|
||||
|
||||
/**
|
||||
* 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(Multiplicity multiplicity) {
|
||||
|
||||
if (multiplicity == Multiplicity.OPTIONAL || multiplicity == Multiplicity.REQUIRED) {
|
||||
return Cardinality.SINGLE;
|
||||
} else if (multiplicity == Multiplicity.COLLECTION) {
|
||||
return Cardinality.LIST;
|
||||
} else if (multiplicity == Multiplicity.SET) {
|
||||
return Cardinality.SET;
|
||||
}
|
||||
// default to LIST as this is the most forgiving
|
||||
return Cardinality.LIST;
|
||||
}
|
||||
|
||||
public static PropertyKey createPropertyKey(AtlasPropertyKey key) {
|
||||
return ((Titan0PropertyKey)key).getWrappedPropertyKey();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* 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.titan0.query;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Database;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Edge;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Graph;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Vertex;
|
||||
|
||||
import com.thinkaurelius.titan.core.TitanGraphQuery;
|
||||
import com.thinkaurelius.titan.core.attribute.Contain;
|
||||
import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
|
||||
import com.tinkerpop.blueprints.Compare;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of NativeTitanGraphQuery.
|
||||
*
|
||||
* @author jeff
|
||||
*
|
||||
*/
|
||||
public class NativeTitan0GraphQuery implements NativeTitanGraphQuery<Titan0Vertex,Titan0Edge> {
|
||||
|
||||
private Titan0Graph graph_;
|
||||
private TitanGraphQuery<?> query_;
|
||||
|
||||
public NativeTitan0GraphQuery(Titan0Graph graph) {
|
||||
query_ = Titan0Database.getGraphInstance().query();
|
||||
graph_ = graph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<AtlasVertex<Titan0Vertex,Titan0Edge>> vertices() {
|
||||
Iterable it = query_.vertices();
|
||||
return graph_.wrapVertices(it);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void in(String propertyName, Collection<? extends Object> values) {
|
||||
query_.has(propertyName, Contain.IN, values);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void has(String propertyName, ComparisionOperator op, Object value) {
|
||||
|
||||
Compare c = getGremlinPredicate(op);
|
||||
TitanPredicate pred = TitanPredicate.Converter.convert(c);
|
||||
query_.has(propertyName, pred, value);
|
||||
}
|
||||
|
||||
private Compare getGremlinPredicate(ComparisionOperator op) {
|
||||
switch (op) {
|
||||
case EQUAL:
|
||||
return Compare.EQUAL;
|
||||
case GREATER_THAN_EQUAL:
|
||||
return Compare.GREATER_THAN_EQUAL;
|
||||
case LESS_THAN_EQUAL:
|
||||
return Compare.LESS_THAN_EQUAL;
|
||||
case NOT_EQUAL:
|
||||
return Compare.NOT_EQUAL;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unsupported comparison operator:" + op);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* 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.titan0.query;
|
||||
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.TitanGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.titan.query.NativeTitanQueryFactory;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Edge;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Graph;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Vertex;
|
||||
|
||||
/**
|
||||
* Titan 0.5.4 implementation of AtlasGraphQuery.
|
||||
*/
|
||||
public class Titan0GraphQuery extends TitanGraphQuery<Titan0Vertex,Titan0Edge> implements NativeTitanQueryFactory<Titan0Vertex,Titan0Edge> {
|
||||
|
||||
public Titan0GraphQuery(Titan0Graph graph, boolean isChildQuery) {
|
||||
super(graph, isChildQuery);
|
||||
}
|
||||
|
||||
public Titan0GraphQuery(Titan0Graph graph) {
|
||||
super(graph);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtlasGraphQuery<Titan0Vertex, Titan0Edge> createChildQuery() {
|
||||
return new Titan0GraphQuery((Titan0Graph)graph_, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NativeTitanQueryFactory<Titan0Vertex,Titan0Edge> getQueryFactory() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NativeTitanGraphQuery<Titan0Vertex, Titan0Edge> createNativeTitanQuery() {
|
||||
return new NativeTitan0GraphQuery((Titan0Graph)graph_);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Adapter class that allows an Iterator to be presented as an instance of java.util.Iterable.
|
||||
*/
|
||||
public final class IteratorToIterableAdapter<T> implements Iterable<T> {
|
||||
|
||||
private final Iterator<T> wrapped;
|
||||
|
||||
public IteratorToIterableAdapter(Iterator<T> wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return wrapped;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,20 @@
|
|||
|
||||
package com.thinkaurelius.titan.diskstorage.hbase;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.thinkaurelius.titan.diskstorage.BackendException;
|
||||
import com.thinkaurelius.titan.diskstorage.EntryMetaData;
|
||||
import com.thinkaurelius.titan.diskstorage.StaticBuffer;
|
||||
|
|
@ -28,20 +42,6 @@ import com.thinkaurelius.titan.diskstorage.util.KeyColumn;
|
|||
import com.thinkaurelius.titan.diskstorage.util.time.StandardDuration;
|
||||
import com.thinkaurelius.titan.diskstorage.util.time.Timepoint;
|
||||
import com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
public class HBaseKeyColumnValueStoreTest {
|
||||
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.atlas.repository.Constants;
|
||||
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.apache.atlas.typesystem.types.Multiplicity;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractGraphDatabaseTest {
|
||||
|
||||
private static 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_;
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String WEIGHT_PROPERTY = "weight";
|
||||
protected static final String TRAIT_NAMES = Constants.TRAIT_NAMES_PROPERTY_KEY;
|
||||
protected static final String typeProperty = "__type";
|
||||
protected static final String typeSystem = "typeSystem";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String BACKING_INDEX_NAME = "backing";
|
||||
|
||||
private AtlasGraph<?,?> graph = null;
|
||||
|
||||
@AfterMethod
|
||||
public void commitGraph() {
|
||||
//force any pending actions to be committed so we can be sure they don't cause errors.
|
||||
pushChangesAndFlushCache();
|
||||
graph.commit();
|
||||
}
|
||||
protected <V, E> void pushChangesAndFlushCache() {
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
graph.commit();
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void createIndices() {
|
||||
Titan0Database db = new Titan0Database();
|
||||
AtlasGraphManagement mgmt = db.getGraph().getManagementSystem();
|
||||
|
||||
if(mgmt.getGraphIndex(BACKING_INDEX_NAME) == null) {
|
||||
mgmt.buildMixedVertexIndex(BACKING_INDEX_NAME, Constants.BACKING_INDEX);
|
||||
}
|
||||
mgmt.makePropertyKey("age13",Integer.class, Multiplicity.OPTIONAL);
|
||||
|
||||
createIndices(mgmt, "name", String.class, false, Multiplicity.REQUIRED);
|
||||
createIndices(mgmt, WEIGHT_PROPERTY, Integer.class, false, Multiplicity.OPTIONAL);
|
||||
createIndices(mgmt, "size15", String.class, false, Multiplicity.REQUIRED);
|
||||
createIndices(mgmt, "typeName", String.class, false, Multiplicity.REQUIRED);
|
||||
createIndices(mgmt, "__type", String.class, false, Multiplicity.REQUIRED);
|
||||
createIndices(mgmt, Constants.GUID_PROPERTY_KEY, String.class, true, Multiplicity.REQUIRED);
|
||||
createIndices(mgmt, Constants.TRAIT_NAMES_PROPERTY_KEY, String.class, false, Multiplicity.SET);
|
||||
createIndices(mgmt, Constants.SUPER_TYPES_PROPERTY_KEY, String.class, false, Multiplicity.SET);
|
||||
mgmt.commit();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void cleanUp() {
|
||||
Titan0Graph graph = new Titan0Graph();
|
||||
graph.clear();
|
||||
|
||||
}
|
||||
|
||||
private static void createIndices(AtlasGraphManagement management, String propertyName, Class propertyClass,
|
||||
boolean isUnique, Multiplicity cardinality) {
|
||||
|
||||
|
||||
|
||||
if(management.containsPropertyKey(propertyName)) {
|
||||
//index was already created
|
||||
return;
|
||||
}
|
||||
|
||||
AtlasPropertyKey key = management.makePropertyKey(propertyName, propertyClass, cardinality);
|
||||
try {
|
||||
if(propertyClass != Integer.class) {
|
||||
management.addIndexKey(BACKING_INDEX_NAME, key);
|
||||
}
|
||||
}
|
||||
catch(Throwable t) {
|
||||
//ok
|
||||
t.printStackTrace();
|
||||
}
|
||||
try {
|
||||
//if(propertyClass != Integer.class) {
|
||||
management.createCompositeIndex(propertyName, key, isUnique);
|
||||
//}
|
||||
}
|
||||
catch(Throwable t) {
|
||||
//ok
|
||||
t.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AbstractGraphDatabaseTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
protected final <V,E> AtlasGraph<V, E> getGraph() {
|
||||
if(graph == null) {
|
||||
graph = new Titan0Graph();
|
||||
}
|
||||
return (AtlasGraph<V,E>)graph;
|
||||
}
|
||||
|
||||
protected Titan0Graph getTitan0Graph() {
|
||||
AtlasGraph g = getGraph();
|
||||
return (Titan0Graph)g;
|
||||
}
|
||||
|
||||
|
||||
protected List<AtlasVertex> newVertices_ = new ArrayList<>();
|
||||
|
||||
protected final <V, E> AtlasVertex<V, E> createVertex(AtlasGraph<V, E> graph) {
|
||||
AtlasVertex<V,E> vertex = graph.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraph;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests for Titan0GraphQuery
|
||||
*/
|
||||
@Test
|
||||
public class GraphQueryTest extends AbstractGraphDatabaseTest {
|
||||
|
||||
|
||||
@Test
|
||||
public <V,E> void testQueryThatCannotRunInMemory() throws AtlasException {
|
||||
AtlasGraph<V,E> graph = getGraph();
|
||||
AtlasVertex<V,E> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
|
||||
AtlasVertex<V,E> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
|
||||
graph.commit();
|
||||
|
||||
AtlasVertex<V,E> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Fred");
|
||||
v4.setProperty("size15", "15");
|
||||
|
||||
AtlasGraphQuery q = graph.query();
|
||||
q.has("name", ComparisionOperator.NOT_EQUAL, "George");
|
||||
q.has("size15","15");
|
||||
graph.commit();
|
||||
pause(); //pause to let the index get updated
|
||||
|
||||
assertQueryMatches(q, v1, v3, v4);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombinationOfAndsAndOrs() throws AtlasException {
|
||||
Titan0Graph graph = getTitan0Graph();
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
v1.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "George");
|
||||
v2.setProperty("size15", "16");
|
||||
v2.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v3 = createVertex(graph);
|
||||
v3.setProperty("name", "Jane");
|
||||
v3.setProperty("size15", "17");
|
||||
v3.setProperty("typeName", "Person");
|
||||
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Bob");
|
||||
v4.setProperty("size15", "18");
|
||||
v4.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v5 = createVertex(graph);
|
||||
v5.setProperty("name", "Julia");
|
||||
v5.setProperty("size15", "19");
|
||||
v5.setProperty("typeName", "Manager");
|
||||
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("typeName","Person");
|
||||
//initially match
|
||||
AtlasGraphQuery inner1a = q.createChildQuery();
|
||||
AtlasGraphQuery inner1b = q.createChildQuery();
|
||||
inner1a.has("name","Fred");
|
||||
inner1b.has("name","Jane");
|
||||
q.or(toList(inner1a, inner1b));
|
||||
|
||||
|
||||
AtlasGraphQuery inner2a = q.createChildQuery();
|
||||
AtlasGraphQuery inner2b = q.createChildQuery();
|
||||
AtlasGraphQuery inner2c = q.createChildQuery();
|
||||
inner2a.has("size15","18");
|
||||
inner2b.has("size15","15");
|
||||
inner2c.has("size15", "16");
|
||||
q.or(toList(inner2a, inner2b, inner2c));
|
||||
|
||||
assertQueryMatches(q, v1);
|
||||
graph.commit();
|
||||
pause(); //let the index update
|
||||
assertQueryMatches(q, v1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithinStep() throws AtlasException {
|
||||
Titan0Graph graph = getTitan0Graph();
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
v1.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "George");
|
||||
v2.setProperty("size15", "16");
|
||||
v2.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v3 = createVertex(graph);
|
||||
v3.setProperty("name", "Jane");
|
||||
v3.setProperty("size15", "17");
|
||||
v3.setProperty("typeName", "Person");
|
||||
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Bob");
|
||||
v4.setProperty("size15", "18");
|
||||
v4.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v5 = createVertex(graph);
|
||||
v5.setProperty("name", "Julia");
|
||||
v5.setProperty("size15", "19");
|
||||
v5.setProperty("typeName", "Manager");
|
||||
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("typeName","Person");
|
||||
//initially match
|
||||
q.in("name", toList("Fred", "Jane"));
|
||||
q.in("size15", toList("18", "15", "16"));
|
||||
|
||||
assertQueryMatches(q, v1);
|
||||
graph.commit();
|
||||
pause(); //let the index update
|
||||
assertQueryMatches(q, v1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithinStepWhereGraphIsStale() throws AtlasException {
|
||||
Titan0Graph graph = getTitan0Graph();
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
v1.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "George");
|
||||
v2.setProperty("size15", "16");
|
||||
v2.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v3 = createVertex(graph);
|
||||
v3.setProperty("name", "Jane");
|
||||
v3.setProperty("size15", "17");
|
||||
v3.setProperty("typeName", "Person");
|
||||
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Bob");
|
||||
v4.setProperty("size15", "18");
|
||||
v4.setProperty("typeName", "Person");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v5 = createVertex(graph);
|
||||
v5.setProperty("name", "Julia");
|
||||
v5.setProperty("size15", "19");
|
||||
v5.setProperty("typeName", "Manager");
|
||||
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("typeName","Person");
|
||||
//initially match
|
||||
q.in("name", toList("Fred", "Jane"));
|
||||
|
||||
graph.commit();
|
||||
pause(); //let the index update
|
||||
assertQueryMatches(q, v1, v3);
|
||||
v3.setProperty("name", "Janet"); //make v3 no longer match the query. Within step should filter out the vertex since it no longer matches.
|
||||
assertQueryMatches(q, v1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleOrQuery() throws AtlasException {
|
||||
Titan0Graph graph = getTitan0Graph();
|
||||
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
|
||||
graph.commit();
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Fred");
|
||||
v4.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<Titan0Vertex,Titan0Edge> v5 = createVertex(graph);
|
||||
v5.setProperty("name", "George");
|
||||
v5.setProperty("size15", "16");
|
||||
|
||||
AtlasGraphQuery q = graph.query();
|
||||
AtlasGraphQuery inner1 = q.createChildQuery().has("name", "Fred");
|
||||
AtlasGraphQuery inner2 = q.createChildQuery().has("size15", "15");
|
||||
q.or(toList(inner1, inner2));
|
||||
assertQueryMatches(q, v1, v2, v3, v4);
|
||||
graph.commit();
|
||||
pause(); //pause to let the indexer get updated (this fails frequently without a pause)
|
||||
assertQueryMatches(q, v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public <V,E> void testQueryMatchesAddedVertices() throws AtlasException {
|
||||
AtlasGraph<V,E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V,E> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
|
||||
AtlasVertex<V,E> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
|
||||
graph.commit();
|
||||
|
||||
AtlasVertex<V,E> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Fred");
|
||||
v4.setProperty("size15", "15");
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("name", "Fred");
|
||||
q.has("size15","15");
|
||||
|
||||
assertQueryMatches(q, v1, v4);
|
||||
graph.commit();
|
||||
assertQueryMatches(q, v1, v4);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public <V,E> void testQueryDoesNotMatchRemovedVertices() throws AtlasException {
|
||||
AtlasGraph<V,E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V,E> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
|
||||
AtlasVertex<V,E> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Fred");
|
||||
v4.setProperty("size15", "15");
|
||||
|
||||
graph.commit();
|
||||
|
||||
graph.removeVertex(v1);
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("name", "Fred");
|
||||
q.has("size15","15");
|
||||
|
||||
assertQueryMatches(q, v4);
|
||||
graph.commit();
|
||||
|
||||
assertQueryMatches(q, v4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V,E> void testQueryDoesNotMatchUncommittedAddedAndRemovedVertices() throws AtlasException {
|
||||
AtlasGraph<V,E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V,E> v1 = createVertex(graph);
|
||||
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
|
||||
AtlasVertex<V,E> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
|
||||
AtlasVertex<V,E> v4 = createVertex(graph);
|
||||
v4.setProperty("name", "Fred");
|
||||
v4.setProperty("size15", "15");
|
||||
|
||||
|
||||
AtlasGraphQuery q = getGraphQuery();
|
||||
q.has("name", "Fred");
|
||||
q.has("size15","15");
|
||||
|
||||
assertQueryMatches(q, v1, v4);
|
||||
|
||||
graph.removeVertex(v1);
|
||||
|
||||
|
||||
assertQueryMatches(q, v4);
|
||||
graph.commit();
|
||||
|
||||
assertQueryMatches(q, v4);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public <V,E> void testQueryResultsReflectPropertyAdd() throws AtlasException {
|
||||
AtlasGraph<V,E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V,E> v1 = createVertex(graph);
|
||||
v1.setProperty("name", "Fred");
|
||||
v1.setProperty("size15", "15");
|
||||
v1.addProperty(TRAIT_NAMES, "trait1");
|
||||
v1.addProperty(TRAIT_NAMES, "trait2");
|
||||
|
||||
AtlasVertex<V,E> v2 = createVertex(graph);
|
||||
v2.setProperty("name", "Fred");
|
||||
v2.addProperty(TRAIT_NAMES, "trait1");
|
||||
|
||||
AtlasVertex<V,E> v3 = createVertex(graph);
|
||||
v3.setProperty("size15", "15");
|
||||
v3.addProperty(TRAIT_NAMES, "trait2");
|
||||
|
||||
AtlasGraphQuery query = getGraphQuery();
|
||||
query.has("name", "Fred");
|
||||
query.has(TRAIT_NAMES, "trait1");
|
||||
query.has("size15", "15");
|
||||
|
||||
assertQueryMatches(query, v1);
|
||||
//make v3 match the query
|
||||
v3.setProperty("name", "Fred");
|
||||
v3.addProperty(TRAIT_NAMES, "trait1");
|
||||
assertQueryMatches(query, v1, v3);
|
||||
v3.removeProperty(TRAIT_NAMES);
|
||||
assertQueryMatches(query, v1);
|
||||
v3.addProperty(TRAIT_NAMES, "trait2");
|
||||
assertQueryMatches(query, v1);
|
||||
v1.removeProperty(TRAIT_NAMES);
|
||||
assertQueryMatches(query);
|
||||
graph.commit();
|
||||
assertQueryMatches(query);
|
||||
|
||||
}
|
||||
|
||||
private static <T> List<T> toList(Iterable<T> itr) {
|
||||
List<T> result = new ArrayList<T>();
|
||||
for(T object : itr) {
|
||||
result.add(object);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private <V,E >void assertQueryMatches(AtlasGraphQuery expr, AtlasVertex... expectedResults) throws AtlasException {
|
||||
|
||||
//getGraph().commit();
|
||||
Collection<AtlasVertex<Titan0Vertex, Titan0Edge>> temp = toList(expr.vertices());
|
||||
//filter out vertices from previous test executions
|
||||
Collection<AtlasVertex<Titan0Vertex, Titan0Edge>> result = Collections2.filter(temp, new Predicate<AtlasVertex<Titan0Vertex, Titan0Edge>>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(AtlasVertex<Titan0Vertex, Titan0Edge> input) {
|
||||
return newVertices_.contains(input);
|
||||
}
|
||||
|
||||
});
|
||||
assertEquals("Expected/found result sizes differ. Expected: " + Arrays.asList(expectedResults).toString() +", found: " + result, expectedResults.length, result.size());
|
||||
|
||||
for(AtlasVertex<V,E> v : expectedResults) {
|
||||
assertTrue(result.contains(v));
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Object> toList(Object...objects) {
|
||||
return Arrays.asList(objects);
|
||||
}
|
||||
|
||||
private AtlasGraphQuery<Titan0Vertex, Titan0Edge> getGraphQuery() {
|
||||
return getTitan0Graph().query();
|
||||
}
|
||||
|
||||
private void pause() {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,428 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdge;
|
||||
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraph;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphManagement;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
|
||||
import org.apache.atlas.repository.graphdb.AtlasPropertyKey;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
|
||||
import org.apache.atlas.typesystem.types.Multiplicity;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Sanity test of basic graph operations using the Titan 0.5.4 graphdb
|
||||
* abstraction layer implementation.
|
||||
*/
|
||||
public class Titan0DatabaseTest {
|
||||
|
||||
private AtlasGraph<?, ?> atlasGraph;
|
||||
|
||||
private <V, E> AtlasGraph<V, E> getGraph() {
|
||||
if (atlasGraph == null) {
|
||||
Titan0Database db = new Titan0Database();
|
||||
atlasGraph = db.getGraph();
|
||||
AtlasGraphManagement mgmt = atlasGraph.getManagementSystem();
|
||||
// create the index (which defines these properties as being mult
|
||||
// many)
|
||||
for (String propertyName : AtlasGraphManagement.MULTIPLICITY_MANY_PROPERTY_KEYS) {
|
||||
AtlasPropertyKey propertyKey = mgmt.getPropertyKey(propertyName);
|
||||
if (propertyKey == null) {
|
||||
propertyKey = mgmt.makePropertyKey(propertyName, String.class, Multiplicity.SET);
|
||||
mgmt.createCompositeIndex(propertyName, propertyKey, false);
|
||||
}
|
||||
}
|
||||
mgmt.commit();
|
||||
}
|
||||
return (AtlasGraph<V, E>) atlasGraph;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void cleanup() {
|
||||
atlasGraph.clear();
|
||||
atlasGraph = null;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testPropertyDataTypes() {
|
||||
|
||||
// primitives
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
|
||||
testProperty(graph, "booleanProperty", Boolean.TRUE);
|
||||
testProperty(graph, "booleanProperty", Boolean.FALSE);
|
||||
testProperty(graph, "booleanProperty", new Boolean(Boolean.TRUE));
|
||||
testProperty(graph, "booleanProperty", new Boolean(Boolean.FALSE));
|
||||
|
||||
testProperty(graph, "byteProperty", Byte.MAX_VALUE);
|
||||
testProperty(graph, "byteProperty", Byte.MIN_VALUE);
|
||||
testProperty(graph, "byteProperty", new Byte(Byte.MAX_VALUE));
|
||||
testProperty(graph, "byteProperty", new Byte(Byte.MIN_VALUE));
|
||||
|
||||
testProperty(graph, "shortProperty", Short.MAX_VALUE);
|
||||
testProperty(graph, "shortProperty", Short.MIN_VALUE);
|
||||
testProperty(graph, "shortProperty", new Short(Short.MAX_VALUE));
|
||||
testProperty(graph, "shortProperty", new Short(Short.MIN_VALUE));
|
||||
|
||||
testProperty(graph, "intProperty", Integer.MAX_VALUE);
|
||||
testProperty(graph, "intProperty", Integer.MIN_VALUE);
|
||||
testProperty(graph, "intProperty", new Integer(Integer.MAX_VALUE));
|
||||
testProperty(graph, "intProperty", new Integer(Integer.MIN_VALUE));
|
||||
|
||||
testProperty(graph, "longProperty", Long.MIN_VALUE);
|
||||
testProperty(graph, "longProperty", Long.MAX_VALUE);
|
||||
testProperty(graph, "longProperty", new Long(Long.MIN_VALUE));
|
||||
testProperty(graph, "longProperty", new Long(Long.MAX_VALUE));
|
||||
|
||||
testProperty(graph, "doubleProperty", Double.MAX_VALUE);
|
||||
testProperty(graph, "doubleProperty", Double.MIN_VALUE);
|
||||
testProperty(graph, "doubleProperty", new Double(Double.MAX_VALUE));
|
||||
testProperty(graph, "doubleProperty", new Double(Double.MIN_VALUE));
|
||||
|
||||
testProperty(graph, "floatProperty", Float.MAX_VALUE);
|
||||
testProperty(graph, "floatProperty", Float.MIN_VALUE);
|
||||
testProperty(graph, "floatProperty", new Float(Float.MAX_VALUE));
|
||||
testProperty(graph, "floatProperty", new Float(Float.MIN_VALUE));
|
||||
|
||||
// enumerations - TypeCategory
|
||||
testProperty(graph, "typeCategoryProperty", TypeCategory.CLASS);
|
||||
|
||||
// biginteger
|
||||
testProperty(graph, "bigIntegerProperty",
|
||||
new BigInteger(String.valueOf(Long.MAX_VALUE)).multiply(BigInteger.TEN));
|
||||
|
||||
// bigdecimal
|
||||
BigDecimal bigDecimal = new BigDecimal(Double.MAX_VALUE);
|
||||
testProperty(graph, "bigDecimalProperty", bigDecimal.multiply(bigDecimal));
|
||||
}
|
||||
|
||||
private <V, E> void testProperty(AtlasGraph<V, E> graph, String name, Object value) {
|
||||
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
vertex.setProperty(name, value);
|
||||
assertEquals(value, vertex.getProperty(name, value.getClass()));
|
||||
AtlasVertex<V, E> loaded = graph.getVertex(vertex.getId().toString());
|
||||
assertEquals(value, loaded.getProperty(name, value.getClass()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testMultiplicityOnePropertySupport() {
|
||||
|
||||
AtlasGraph<V, E> graph = (AtlasGraph<V, E>) getGraph();
|
||||
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
vertex.setProperty("name", "Jeff");
|
||||
vertex.setProperty("location", "Littleton");
|
||||
assertEquals("Jeff", vertex.getProperty("name", String.class));
|
||||
assertEquals("Littleton", vertex.getProperty("location", String.class));
|
||||
|
||||
AtlasVertex<V, E> vertexCopy = graph.getVertex(vertex.getId().toString());
|
||||
|
||||
assertEquals("Jeff", vertexCopy.getProperty("name", String.class));
|
||||
assertEquals("Littleton", vertexCopy.getProperty("location", String.class));
|
||||
|
||||
assertTrue(vertexCopy.getPropertyKeys().contains("name"));
|
||||
assertTrue(vertexCopy.getPropertyKeys().contains("location"));
|
||||
|
||||
assertTrue(vertexCopy.getPropertyValues("name", String.class).contains("Jeff"));
|
||||
assertTrue(vertexCopy.getPropertyValues("location", String.class).contains("Littleton"));
|
||||
assertTrue(vertexCopy.getPropertyValues("test", String.class).isEmpty());
|
||||
assertNull(vertexCopy.getProperty("test", String.class));
|
||||
|
||||
vertex.removeProperty("name");
|
||||
assertFalse(vertex.getPropertyKeys().contains("name"));
|
||||
assertNull(vertex.getProperty("name", String.class));
|
||||
assertTrue(vertex.getPropertyValues("name", String.class).isEmpty());
|
||||
|
||||
vertexCopy = graph.getVertex(vertex.getId().toString());
|
||||
assertFalse(vertexCopy.getPropertyKeys().contains("name"));
|
||||
assertNull(vertexCopy.getProperty("name", String.class));
|
||||
assertTrue(vertexCopy.getPropertyValues("name", String.class).isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testRemoveEdge() {
|
||||
|
||||
AtlasGraph<V, E> graph = (AtlasGraph<V, E>) getGraph();
|
||||
AtlasVertex<V, E> v1 = graph.addVertex();
|
||||
AtlasVertex<V, E> v2 = graph.addVertex();
|
||||
|
||||
AtlasEdge<V, E> edge = graph.addEdge(v1, v2, "knows");
|
||||
|
||||
// make sure the edge exists
|
||||
AtlasEdge<V, E> edgeCopy = graph.getEdge(edge.getId().toString());
|
||||
assertNotNull(edgeCopy);
|
||||
assertEquals(edgeCopy, edge);
|
||||
|
||||
graph.removeEdge(edge);
|
||||
|
||||
edgeCopy = graph.getEdge(edge.getId().toString());
|
||||
// should return null now, since edge was deleted
|
||||
assertNull(edgeCopy);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testRemoveVertex() {
|
||||
|
||||
AtlasGraph<V, E> graph = (AtlasGraph<V, E>) getGraph();
|
||||
|
||||
AtlasVertex<V, E> v1 = graph.addVertex();
|
||||
|
||||
assertNotNull(graph.getVertex(v1.getId().toString()));
|
||||
|
||||
graph.removeVertex(v1);
|
||||
|
||||
assertNull(graph.getVertex(v1.getId().toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testGetEdges() {
|
||||
|
||||
AtlasGraph<V, E> graph = (AtlasGraph<V, E>) getGraph();
|
||||
AtlasVertex<V, E> v1 = graph.addVertex();
|
||||
AtlasVertex<V, E> v2 = graph.addVertex();
|
||||
AtlasVertex<V, E> v3 = graph.addVertex();
|
||||
|
||||
AtlasEdge<V, E> knows = graph.addEdge(v2, v1, "knows");
|
||||
AtlasEdge<V, E> eats = graph.addEdge(v3, v1, "eats");
|
||||
AtlasEdge<V, E> drives = graph.addEdge(v3, v2, "drives");
|
||||
AtlasEdge<V, E> sleeps = graph.addEdge(v2, v3, "sleeps");
|
||||
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.IN), knows, eats);
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.OUT));
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.BOTH), knows, eats);
|
||||
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.IN, "knows"), knows);
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.OUT, "knows"));
|
||||
assertEdgesMatch(v1.getEdges(AtlasEdgeDirection.BOTH, "knows"), knows);
|
||||
|
||||
assertEdgesMatch(v2.getEdges(AtlasEdgeDirection.IN), drives);
|
||||
assertEdgesMatch(v2.getEdges(AtlasEdgeDirection.OUT), knows, sleeps);
|
||||
assertEdgesMatch(v2.getEdges(AtlasEdgeDirection.BOTH), knows, sleeps, drives);
|
||||
|
||||
assertEdgesMatch(v2.getEdges(AtlasEdgeDirection.BOTH, "delivers"));
|
||||
}
|
||||
|
||||
private <V, E> void assertEdgesMatch(Iterable<AtlasEdge<V, E>> edgesIt, AtlasEdge<V, E>... expected) {
|
||||
List<AtlasEdge<V, E>> edges = toList(edgesIt);
|
||||
assertEquals(expected.length, edges.size());
|
||||
for (AtlasEdge<V, E> edge : expected) {
|
||||
assertTrue(edges.contains(edge));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testMultiplictyManyPropertySupport() {
|
||||
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
String vertexId = vertex.getId().toString();
|
||||
vertex.setProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait1");
|
||||
vertex.setProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait2");
|
||||
assertEquals(vertex.getPropertyValues(Constants.TRAIT_NAMES_PROPERTY_KEY, String.class).size(), 2);
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait3");
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait4");
|
||||
|
||||
assertTrue(vertex.getPropertyKeys().contains(Constants.TRAIT_NAMES_PROPERTY_KEY));
|
||||
validateMultManyPropertiesInVertex(vertex);
|
||||
// fetch a copy of the vertex, make sure result
|
||||
// is the same
|
||||
|
||||
validateMultManyPropertiesInVertex(graph.getVertex(vertexId));
|
||||
|
||||
}
|
||||
|
||||
private <V, E> void validateMultManyPropertiesInVertex(AtlasVertex<V, E> vertex) {
|
||||
|
||||
assertTrue(vertex.getPropertyKeys().contains(Constants.TRAIT_NAMES_PROPERTY_KEY));
|
||||
Collection<String> traitNames = vertex.getPropertyValues(Constants.TRAIT_NAMES_PROPERTY_KEY, String.class);
|
||||
assertTrue(traitNames.contains("trait1"));
|
||||
assertTrue(traitNames.contains("trait2"));
|
||||
assertTrue(traitNames.contains("trait3"));
|
||||
assertTrue(traitNames.contains("trait4"));
|
||||
|
||||
try {
|
||||
vertex.getProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, String.class);
|
||||
fail("Expected exception not thrown");
|
||||
} catch (IllegalStateException expected) {
|
||||
// multiple property values exist
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testListProperties() throws AtlasException {
|
||||
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
vertex.setListProperty("colors", Arrays.asList(new String[] { "red", "blue", "green" }));
|
||||
List<String> colors = vertex.getListProperty("colors");
|
||||
assertTrue(colors.contains("red"));
|
||||
assertTrue(colors.contains("blue"));
|
||||
assertTrue(colors.contains("green"));
|
||||
|
||||
AtlasVertex<V, E> vertexCopy = graph.getVertex(vertex.getId().toString());
|
||||
colors = vertexCopy.getListProperty("colors");
|
||||
assertTrue(colors.contains("red"));
|
||||
assertTrue(colors.contains("blue"));
|
||||
assertTrue(colors.contains("green"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testRemoveProperty() {
|
||||
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait1");
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait1");
|
||||
vertex.setProperty("name", "Jeff");
|
||||
|
||||
// remove existing property - multiplicity one
|
||||
vertex.removeProperty("jeff");
|
||||
|
||||
assertFalse(vertex.getPropertyKeys().contains("jeff"));
|
||||
|
||||
// remove existing property - multiplicity many
|
||||
vertex.removeProperty(Constants.TRAIT_NAMES_PROPERTY_KEY);
|
||||
assertFalse(vertex.getPropertyKeys().contains(Constants.TRAIT_NAMES_PROPERTY_KEY));
|
||||
|
||||
AtlasVertex<V, E> vertexCopy = graph.getVertex(vertex.getId().toString());
|
||||
assertFalse(vertexCopy.getPropertyKeys().contains("jeff"));
|
||||
assertFalse(vertexCopy.getPropertyKeys().contains(Constants.TRAIT_NAMES_PROPERTY_KEY));
|
||||
|
||||
// remove non-existing property
|
||||
vertex.removeProperty(Constants.TRAIT_NAMES_PROPERTY_KEY);
|
||||
vertex.removeProperty("jeff");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void getGetGraphQueryForVertices() {
|
||||
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
|
||||
AtlasVertex<V, E> v1 = graph.addVertex();
|
||||
AtlasVertex<V, E> v2 = graph.addVertex();
|
||||
AtlasVertex<V, E> v3 = graph.addVertex();
|
||||
|
||||
v1.setProperty("name", "Jeff");
|
||||
v1.setProperty("weight", 1);
|
||||
|
||||
v2.setProperty("name", "Fred");
|
||||
v2.setProperty("weight", 2);
|
||||
|
||||
v3.setProperty("name", "Chris");
|
||||
v3.setProperty("weight", 3);
|
||||
|
||||
AtlasEdge<V, E> knows = graph.addEdge(v2, v1, "knows");
|
||||
knows.setProperty("weight", 1);
|
||||
AtlasEdge<V, E> eats = graph.addEdge(v3, v1, "eats");
|
||||
eats.setProperty("weight", 2);
|
||||
AtlasEdge<V, E> drives = graph.addEdge(v3, v2, "drives");
|
||||
drives.setProperty("weight", 3);
|
||||
|
||||
AtlasEdge<V, E> sleeps = graph.addEdge(v2, v3, "sleeps");
|
||||
sleeps.setProperty("weight", 4);
|
||||
|
||||
testExecuteGraphQuery("name", null, "Jeff", v1);
|
||||
testExecuteGraphQuery("weight", ComparisionOperator.EQUAL, 2, v2);
|
||||
testExecuteGraphQuery("weight", ComparisionOperator.GREATER_THAN_EQUAL, 2, v2, v3);
|
||||
testExecuteGraphQuery("weight", ComparisionOperator.LESS_THAN_EQUAL, 2, v2, v1);
|
||||
|
||||
}
|
||||
|
||||
private <V, E> void testExecuteGraphQuery(String property, ComparisionOperator op, Object value,
|
||||
AtlasVertex<V, E>... expected) {
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
AtlasGraphQuery<V, E> query = graph.query();
|
||||
if (op != null) {
|
||||
query.has(property, op, value);
|
||||
} else {
|
||||
query.has(property, value);
|
||||
}
|
||||
Iterable<? extends AtlasVertex<V, E>> result = query.vertices();
|
||||
List<AtlasVertex<V, E>> list = toList(result);
|
||||
assertEquals(expected.length, list.size());
|
||||
for (AtlasVertex<V, E> vertex : expected) {
|
||||
assertTrue(list.contains(vertex));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public <V, E> void testAddMultManyPropertyValueTwice() {
|
||||
|
||||
AtlasGraph<V, E> graph = getGraph();
|
||||
String vertexId;
|
||||
|
||||
AtlasVertex<V, E> vertex = graph.addVertex();
|
||||
vertexId = vertex.getId().toString();
|
||||
vertex.setProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait1");
|
||||
vertex.setProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait1");
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait2");
|
||||
vertex.addProperty(Constants.TRAIT_NAMES_PROPERTY_KEY, "trait2");
|
||||
|
||||
validateDuplicatePropertyVertex(vertex);
|
||||
|
||||
// fetch a copy of the vertex, make sure result is the same
|
||||
|
||||
validateDuplicatePropertyVertex(graph.getVertex(vertexId));
|
||||
}
|
||||
|
||||
private <V, E> void validateDuplicatePropertyVertex(AtlasVertex<V, E> vertex) {
|
||||
assertEquals(2, vertex.getPropertyValues(Constants.TRAIT_NAMES_PROPERTY_KEY, String.class).size());
|
||||
assertTrue(vertex.getPropertyKeys().contains(Constants.TRAIT_NAMES_PROPERTY_KEY));
|
||||
Collection<String> traitNames = vertex.getPropertyValues(Constants.TRAIT_NAMES_PROPERTY_KEY, String.class);
|
||||
assertTrue(traitNames.contains("trait1"));
|
||||
assertTrue(traitNames.contains("trait2"));
|
||||
}
|
||||
|
||||
private static <T> List<T> toList(Iterable<? extends T> iterable) {
|
||||
List<T> result = new ArrayList<T>();
|
||||
for (T item : iterable) {
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* 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.titan0;
|
||||
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
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 Titan0DatabaseValidationTest {
|
||||
|
||||
private Configuration configuration;
|
||||
private AtlasGraph<?, ?> graph;
|
||||
|
||||
@BeforeTest
|
||||
public void setUp() throws AtlasException {
|
||||
// First get Instance
|
||||
graph = new Titan0Graph();
|
||||
configuration = ApplicationProperties.getSubsetConfiguration(ApplicationProperties.get(),
|
||||
Titan0Database.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 {
|
||||
Titan0Database.validateIndexBackend(configuration);
|
||||
} catch (Exception e) {
|
||||
Assert.fail("Unexpected exception ", e);
|
||||
}
|
||||
|
||||
// Change backend
|
||||
configuration.setProperty(Titan0Database.INDEX_BACKEND_CONF, Titan0Database.INDEX_BACKEND_LUCENE);
|
||||
try {
|
||||
Titan0Database.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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#
|
||||
# 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.titan0.Titan0Database
|
||||
|
||||
######### Atlas Server Configs #########
|
||||
atlas.rest.address=http://localhost:31000
|
||||
|
||||
######### Graph Database Configs #########
|
||||
# Graph Storage
|
||||
atlas.graph.storage.backend=${titan.storage.backend}
|
||||
|
||||
# Graph Search Index Backend
|
||||
atlas.graph.index.search.backend=${titan.index.backend}
|
||||
|
||||
#Berkeley storage directory
|
||||
atlas.graph.storage.directory=${sys:atlas.data}/berkley
|
||||
|
||||
#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=${titan.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
|
||||
113
pom.xml
113
pom.xml
|
|
@ -434,7 +434,8 @@
|
|||
|
||||
<titan.storage.backend>berkeleyje</titan.storage.backend>
|
||||
<titan.index.backend>elasticsearch</titan.index.backend>
|
||||
<entity.repository.impl>org.apache.atlas.repository.audit.InMemoryEntityAuditRepository</entity.repository.impl>
|
||||
<entity.repository.impl>org.apache.atlas.repository.audit.InMemoryEntityAuditRepository</entity.repository.impl>
|
||||
<atlas.surefire.options></atlas.surefire.options>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
|
|
@ -446,10 +447,10 @@
|
|||
</activation>
|
||||
<properties>
|
||||
<titan.storage.backend>hbase</titan.storage.backend>
|
||||
<titan.index.backend>solr5</titan.index.backend>
|
||||
<titan.index.backend>solr</titan.index.backend>
|
||||
<solr.zk.address>localhost:9983</solr.zk.address>
|
||||
<titan.storage.hostname>localhost</titan.storage.hostname>
|
||||
<entity.repository.impl>org.apache.atlas.repository.audit.HBaseBasedAuditRepository</entity.repository.impl>
|
||||
<entity.repository.impl>org.apache.atlas.repository.audit.HBaseBasedAuditRepository</entity.repository.impl>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
|
@ -487,7 +488,6 @@
|
|||
<module>notification</module>
|
||||
<module>client</module>
|
||||
<module>graphdb</module>
|
||||
<module>titan</module>
|
||||
<module>repository</module>
|
||||
<module>authorization</module>
|
||||
<module>catalog</module>
|
||||
|
|
@ -683,6 +683,11 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-auth</artifactId>
|
||||
<version>${hadoop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
|
|
@ -874,58 +879,7 @@
|
|||
</dependency>
|
||||
|
||||
<!-- Graph DB -->
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-core</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
<exclusions>
|
||||
<!-- rexster does not work with servlet-api -->
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop.rexster</groupId>
|
||||
<artifactId>rexster-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop.rexster</groupId>
|
||||
<artifactId>rexster-server</artifactId>
|
||||
</exclusion>
|
||||
<!-- asm 4.0 does not work with jersey asm 3.1 -->
|
||||
<exclusion>
|
||||
<groupId>com.tinkerpop</groupId>
|
||||
<artifactId>frames</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.esotericsoftware.reflectasm</groupId>
|
||||
<artifactId>reflectasm</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</exclusion>
|
||||
<exclusion> <!-- GPL license imported from ganglia -->
|
||||
<groupId>org.acplt</groupId>
|
||||
<artifactId>oncrpc</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-berkeleyje</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-hbase</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hbase</groupId>
|
||||
<artifactId>hbase-client</artifactId>
|
||||
|
|
@ -979,12 +933,6 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-es</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.vividsolutions</groupId>
|
||||
<artifactId>jts</artifactId>
|
||||
|
|
@ -1016,6 +964,10 @@
|
|||
<artifactId>*</artifactId>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>*</artifactId>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
|
|
@ -1025,19 +977,6 @@
|
|||
<version>${solr.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-lucene</artifactId>
|
||||
<version>${titan.version}</version>
|
||||
<!--<scope>test</scope>-->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.gremlin</groupId>
|
||||
<artifactId>gremlin-java</artifactId>
|
||||
<version>${tinkerpop.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- atlas modules -->
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
|
|
@ -1055,7 +994,13 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-titan</artifactId>
|
||||
<artifactId>atlas-graphdb-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-titan0</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
|
@ -1576,6 +1521,14 @@
|
|||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<configuration>
|
||||
<excludeGroupIds>org.restlet.jee</excludeGroupIds>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
|
|
@ -1628,7 +1581,7 @@
|
|||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
<argLine>-Djava.awt.headless=true -Dproject.version=${project.version}
|
||||
-Dhadoop.tmp.dir="${project.build.directory}/tmp-hadoop-${user.name}"
|
||||
-Xmx1024m -XX:MaxPermSize=512m -Djava.net.preferIPv4Stack=true
|
||||
-Xmx1024m -XX:MaxPermSize=512m -Djava.net.preferIPv4Stack=true ${atlas.surefire.options}
|
||||
</argLine>
|
||||
<skip>${skipUTs}</skip>
|
||||
</configuration>
|
||||
|
|
@ -1654,7 +1607,7 @@
|
|||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
<argLine>-Djava.awt.headless=true -Dproject.version=${project.version}
|
||||
-Dhadoop.tmp.dir="${project.build.directory}/tmp-hadoop-${user.name}"
|
||||
-Xmx1024m -XX:MaxPermSize=512m
|
||||
-Xmx1024m -XX:MaxPermSize=512m ${atlas.surefire.options}
|
||||
</argLine>
|
||||
<skip>${skipITs}</skip>
|
||||
<parallel>none</parallel>
|
||||
|
|
@ -1727,7 +1680,11 @@
|
|||
<useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
|
||||
<excludeSubProjects>true</excludeSubProjects>
|
||||
<excludes>
|
||||
<exclude>**/dependency-reduced-pom.xml</exclude>
|
||||
<exclude>.reviewboardrc</exclude>
|
||||
<exclude>3party-licenses/**</exclude>
|
||||
<exclude>**/.cache-main</exclude>
|
||||
<exclude>**/.checkstyle</exclude>
|
||||
<exclude>*.txt</exclude>
|
||||
<exclude>**/*.json</exclude>
|
||||
<exclude>.pc/**</exclude>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
|
|||
ATLAS-1060 Add composite indexes for exact match performance improvements for all attributes (sumasai via shwethags)
|
||||
|
||||
ALL CHANGES:
|
||||
ATLAS-693 Titan 0.5.4 implementation of the graph db abstraction {jnhagelb via dkantor)
|
||||
ATLAS-1099 UI : multiple tag assign button hides wrongly (Kalyanikashikar via sumasai)
|
||||
ATLAS-1087 Provide an option to turn off persisting entity definition in audits (sumasai, shwethags)
|
||||
ATLAS-1097 Fix a potential NPE issue flagged by Coverity scan (mneethiraj via shwethags)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,12 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-titan</artifactId>
|
||||
<artifactId>atlas-graphdb-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-titan0</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
@ -82,16 +87,6 @@
|
|||
<artifactId>json-simple</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.gremlin</groupId>
|
||||
<artifactId>gremlin-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.scala-lang</groupId>
|
||||
<artifactId>scala-reflect</artifactId>
|
||||
|
|
|
|||
|
|
@ -75,9 +75,12 @@ public class RepositoryMetadataModule extends com.google.inject.AbstractModule {
|
|||
// bind the ITypeStore interface to an implementation
|
||||
bind(ITypeStore.class).to(GraphBackedTypeStore.class).asEagerSingleton();
|
||||
|
||||
//GraphBackedSearchIndexer must be an eager singleton to force the search index creation to happen before
|
||||
//we try to restore the type system (otherwise we'll end up running queries
|
||||
//before we have any indices during the initial graph setup)
|
||||
Multibinder<TypesChangeListener> typesChangeListenerBinder =
|
||||
Multibinder.newSetBinder(binder(), TypesChangeListener.class);
|
||||
typesChangeListenerBinder.addBinding().to(GraphBackedSearchIndexer.class);
|
||||
typesChangeListenerBinder.addBinding().to(GraphBackedSearchIndexer.class).asEagerSingleton();
|
||||
|
||||
// bind the MetadataService interface to an implementation
|
||||
bind(MetadataService.class).to(DefaultMetadataService.class).asEagerSingleton();
|
||||
|
|
|
|||
|
|
@ -18,18 +18,14 @@
|
|||
|
||||
package org.apache.atlas.repository.graph;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
import com.thinkaurelius.titan.core.TitanProperty;
|
||||
import com.thinkaurelius.titan.core.TitanVertex;
|
||||
import com.tinkerpop.blueprints.Direction;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Element;
|
||||
import com.tinkerpop.blueprints.Graph;
|
||||
import com.tinkerpop.blueprints.GraphQuery;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.RequestContext;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
|
|
@ -44,17 +40,23 @@ import org.apache.atlas.typesystem.types.DataTypes;
|
|||
import org.apache.atlas.typesystem.types.HierarchicalType;
|
||||
import org.apache.atlas.typesystem.types.IDataType;
|
||||
import org.apache.atlas.typesystem.types.TypeSystem;
|
||||
import org.apache.atlas.typesystem.types.utils.TypesUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
import com.thinkaurelius.titan.core.TitanProperty;
|
||||
import com.thinkaurelius.titan.core.TitanVertex;
|
||||
import com.tinkerpop.blueprints.Direction;
|
||||
import com.tinkerpop.blueprints.Edge;
|
||||
import com.tinkerpop.blueprints.Element;
|
||||
import com.tinkerpop.blueprints.Graph;
|
||||
import com.tinkerpop.blueprints.GraphQuery;
|
||||
import com.tinkerpop.blueprints.Vertex;
|
||||
|
||||
/**
|
||||
* Utility class for graph operations.
|
||||
|
|
@ -295,7 +297,7 @@ public final class GraphHelper {
|
|||
|
||||
/**
|
||||
* Remove the specified edge from the graph.
|
||||
*
|
||||
*
|
||||
* @param edge
|
||||
*/
|
||||
public void removeEdge(Edge edge) {
|
||||
|
|
@ -304,10 +306,10 @@ public final class GraphHelper {
|
|||
titanGraph.removeEdge(edge);
|
||||
LOG.info("Removed {}", edgeString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the specified vertex from the graph.
|
||||
*
|
||||
*
|
||||
* @param vertex
|
||||
*/
|
||||
public void removeVertex(Vertex vertex) {
|
||||
|
|
@ -488,4 +490,17 @@ public final class GraphHelper {
|
|||
}
|
||||
return key;
|
||||
}
|
||||
public static AttributeInfo getAttributeInfoForSystemAttributes(String field) {
|
||||
switch (field) {
|
||||
case Constants.STATE_PROPERTY_KEY:
|
||||
case Constants.GUID_PROPERTY_KEY:
|
||||
return TypesUtil.newAttributeInfo(field, DataTypes.STRING_TYPE);
|
||||
|
||||
case Constants.TIMESTAMP_PROPERTY_KEY:
|
||||
case Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY:
|
||||
return TypesUtil.newAttributeInfo(field, DataTypes.LONG_TYPE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,122 +18,33 @@
|
|||
|
||||
package org.apache.atlas.repository.graph;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
import com.thinkaurelius.titan.core.TitanFactory;
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
import com.thinkaurelius.titan.core.schema.TitanManagement;
|
||||
import com.thinkaurelius.titan.diskstorage.StandardIndexProvider;
|
||||
import com.thinkaurelius.titan.diskstorage.solr.Solr5Index;
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.repository.graphdb.titan0.Titan0Database;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
|
||||
/**
|
||||
* Default implementation for Graph Provider that doles out Titan Graph.
|
||||
* Temporary TitanGraphProvider to use until the graph database abstraction
|
||||
* layer is fully in place. Delegates to the Titan 0.5.4 implementation. This
|
||||
* will be removed once the abstraction layer is being used.
|
||||
*/
|
||||
public class TitanGraphProvider implements GraphProvider<TitanGraph> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TitanGraphProvider.class);
|
||||
|
||||
/**
|
||||
* Constant for the configuration property that indicates the prefix.
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.atlas.repository.graph.GraphProvider#get()
|
||||
*/
|
||||
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 TitanGraph graphInstance;
|
||||
|
||||
public static Configuration getConfiguration() throws AtlasException {
|
||||
Configuration configProperties = ApplicationProperties.get();
|
||||
return ApplicationProperties.getSubsetConfiguration(configProperties, GRAPH_PREFIX);
|
||||
}
|
||||
|
||||
static {
|
||||
addSolr5Index();
|
||||
}
|
||||
|
||||
/**
|
||||
* Titan loads index backend name to implementation using StandardIndexProvider.ALL_MANAGER_CLASSES
|
||||
* But StandardIndexProvider.ALL_MANAGER_CLASSES is a private static final ImmutableMap
|
||||
* Only way to inject Solr5Index is to modify this field. So, using hacky reflection to add Sol5Index
|
||||
*/
|
||||
private static void addSolr5Index() {
|
||||
try {
|
||||
Field field = StandardIndexProvider.class.getDeclaredField("ALL_MANAGER_CLASSES");
|
||||
field.setAccessible(true);
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
Map<String, String> customMap = new HashMap(StandardIndexProvider.getAllProviderClasses());
|
||||
customMap.put("solr5", Solr5Index.class.getName());
|
||||
ImmutableMap<String, String> immap = ImmutableMap.copyOf(customMap);
|
||||
field.set(null, immap);
|
||||
|
||||
LOG.debug("Injected solr5 index - {}", Solr5Index.class.getName());
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@Override
|
||||
public TitanGraph get() {
|
||||
return Titan0Database.getGraphInstance();
|
||||
}
|
||||
|
||||
public static TitanGraph getGraphInstance() {
|
||||
if (graphInstance == null) {
|
||||
synchronized (TitanGraphProvider.class) {
|
||||
if (graphInstance == null) {
|
||||
Configuration config;
|
||||
try {
|
||||
config = getConfiguration();
|
||||
} catch (AtlasException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
graphInstance = TitanFactory.open(config);
|
||||
validateIndexBackend(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return graphInstance;
|
||||
return Titan0Database.getGraphInstance();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
synchronized (TitanGraphProvider.class) {
|
||||
graphInstance.shutdown();
|
||||
graphInstance = null;
|
||||
}
|
||||
public static Configuration getConfiguration() throws AtlasException {
|
||||
return Titan0Database.getConfiguration();
|
||||
}
|
||||
|
||||
static void validateIndexBackend(Configuration config) {
|
||||
String configuredIndexBackend = config.getString(INDEX_BACKEND_CONF);
|
||||
|
||||
TitanManagement managementSystem = graphInstance.getManagementSystem();
|
||||
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
|
||||
@Singleton
|
||||
@Provides
|
||||
public TitanGraph get() {
|
||||
return getGraphInstance();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger
|
|||
import org.apache.atlas.AtlasException
|
||||
import org.apache.atlas.query.Expressions.{LimitExpression, PathExpression, SelectExpression}
|
||||
import org.apache.atlas.repository.Constants
|
||||
import org.apache.atlas.repository.graph.GraphHelper
|
||||
import org.apache.atlas.typesystem.types.DataTypes.{ArrayType, PrimitiveType, TypeCategory}
|
||||
import org.apache.atlas.typesystem.types._
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ object TypeUtils {
|
|||
return Some(FieldInfo(typ,fMap.get.fields.get(id)))
|
||||
}
|
||||
|
||||
val systemField = Constants.getAttributeInfoForSystemAttributes(id)
|
||||
val systemField = GraphHelper.getAttributeInfoForSystemAttributes(id)
|
||||
if (systemField != null) {
|
||||
return Some(FieldInfo(systemField.dataType(), systemField))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* 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.graph;
|
||||
|
||||
import com.thinkaurelius.titan.core.TitanGraph;
|
||||
import com.thinkaurelius.titan.core.util.TitanCleanup;
|
||||
import com.thinkaurelius.titan.diskstorage.Backend;
|
||||
import com.thinkaurelius.titan.graphdb.database.StandardTitanGraph;
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.mockito.Mockito;
|
||||
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 TitanGraph graph;
|
||||
|
||||
@BeforeTest
|
||||
public void setUp() throws AtlasException {
|
||||
//First get Instance
|
||||
graph = TitanGraphProvider.getGraphInstance();
|
||||
configuration = ApplicationProperties.getSubsetConfiguration(ApplicationProperties.get(), TitanGraphProvider.GRAPH_PREFIX);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() throws Exception {
|
||||
try {
|
||||
graph.shutdown();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
TitanCleanup.clear(graph);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidate() throws AtlasException {
|
||||
try {
|
||||
TitanGraphProvider.validateIndexBackend(configuration);
|
||||
} catch(Exception e){
|
||||
Assert.fail("Unexpected exception ", e);
|
||||
}
|
||||
|
||||
//Change backend
|
||||
configuration.setProperty(TitanGraphProvider.INDEX_BACKEND_CONF, TitanGraphProvider.INDEX_BACKEND_LUCENE);
|
||||
try {
|
||||
TitanGraphProvider.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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,4 +23,7 @@
|
|||
|
||||
<suppressions>
|
||||
<suppress checks="JavadocType" files="[/\\]src[/\\]test[/\\]java[/\\]"/>
|
||||
|
||||
<!-- skip checks on customized titan 0.5.4 files -->
|
||||
<suppress checks="[a-zA-Z0-9]*" files="[/\\]com[/\\]thinkaurelius[/\\]titan[/\\]"/>
|
||||
</suppressions>
|
||||
|
|
|
|||
105
titan/pom.xml
105
titan/pom.xml
|
|
@ -1,105 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apache-atlas</artifactId>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<version>0.8-incubating-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>atlas-titan</artifactId>
|
||||
<description>Apache Atlas Titan Overrides</description>
|
||||
<name>Apache Atlas Titan</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hbase</groupId>
|
||||
<artifactId>hbase-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.vividsolutions</groupId>
|
||||
<artifactId>jts</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-core</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<version>${solr.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-es</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-berkeleyje</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-lucene</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/log4j.xml</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>scala-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
@ -103,6 +103,11 @@
|
|||
<artifactId>atlas-repository</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-graphdb-titan0</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-client</artifactId>
|
||||
|
|
@ -123,7 +128,6 @@
|
|||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-minikdc</artifactId>
|
||||
|
|
@ -133,7 +137,7 @@
|
|||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-hdfs</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-catalog</artifactId>
|
||||
|
|
@ -165,16 +169,6 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.tinkerpop.blueprints</groupId>
|
||||
<artifactId>blueprints-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.thinkaurelius.titan</groupId>
|
||||
<artifactId>titan-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
|
|
|
|||
Loading…
Reference in New Issue