Commit 4fa10b6a by Jeff Hagelberg Committed by Dave Kantor

ATLAS-693 Titan 0.5.4 implementation of graph db abstraction. (jnhagelb via dkantor)

parent 2ef0fc46
......@@ -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;
}
\ No newline at end of file
/**
* 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
*/
AtlasPropertyKey makePropertyKey(String propertyName, Class propertyClass, Multiplicity multiplicity);
/**
* @param propertyKey
* @return
*/
AtlasPropertyKey getPropertyKey(String propertyName);
/**
* Creates a composite index for the graph.
*
* @param propertyName
* @param propertyKey
* @param isUnique
*/
void createCompositeIndex(String propertyName, Class propertyClass, Multiplicity multiplicity,
boolean isUnique);
void createCompositeIndex(String propertyName, AtlasPropertyKey propertyKey, boolean isUnique);
/**
* 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
* 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
*/
void createBackingIndex(String propertyName, String vertexIndexName, Class propertyClass,
Multiplicity multiplicity);
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.
* 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
*/
Iterable<AtlasVertex<V, E>> vertices();
AtlasGraphQuery<V,E> in(String propertyKey, Collection<? extends Object> values);
/**
* Executes the query and returns the matching edges.
* Executes the query and returns the matching vertices.
* @return
* @throws AtlasException
*/
Iterable<AtlasEdge<V, E>> edges();
Iterable<AtlasVertex<V, E>> vertices();
/**
* 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 its value matches the criterion specified.
*
*
* @param propertyKey
* @param value
* @return
*/
AtlasGraphQuery<V,E> has(String propertyKey, ComparisionOperator compMethod, Object value);
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();
......
/**
* 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();
/**
* Sets things up so that getGraph() will return a graph that can be used for running
* tests.
*/
void initializeTestGraph();
/**
* Unloads the graph (used testing)
* Removes the test graph that was created.
*/
void unloadGraph();
void removeTestGraph();
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ package org.apache.atlas.repository.graphdb;
/**
* Enumeration of the supported versions of Gremlin
*
*
*
*/
public enum GremlinVersion {
......
<?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>
/**
* 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);
}
/**
* 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();
}
/**
* 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_;
}
}
/**
* 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_ + "]";
}
}
\ No newline at end of file
/**
* 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_ + "]";
}
}
\ No newline at end of file
/**
* 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_ + "]";
}
}
\ No newline at end of file
/**
* 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();
}
}
\ No newline at end of file
/**
* 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);
}
\ No newline at end of file
......@@ -32,5 +32,7 @@
<modules>
<module>api</module>
<module>titan0</module>
<module>common</module>
</modules>
</project>
/**
* 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);
}
}
/**
* 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();
}
}
}
/**
* 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);
}
}
/**
* 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() + "]";
}
}
/**
* 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;
}
}
/**
* 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);
}
});
}
}
/**
* 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;
}
}
/**
* 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();
}
}
}
/**
* 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;
}
}
/**
* 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() + "]";
}
}
/**
* 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();
}
}
/**
* 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();
}
}
/**
* 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);
}
}
}
/**
* 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_);
}
}
/**
* 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 {
......
/**
* 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;
}
}
}
\ No newline at end of file
......@@ -15,33 +15,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.repository.graph;
package org.apache.atlas.repository.graphdb.titan0;
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.atlas.repository.graphdb.AtlasGraph;
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 {
public class Titan0DatabaseValidationTest {
private Configuration configuration;
private TitanGraph graph;
private Configuration configuration;
private AtlasGraph<?, ?> graph;
@BeforeTest
public void setUp() throws AtlasException {
//First get Instance
graph = TitanGraphProvider.getGraphInstance();
configuration = ApplicationProperties.getSubsetConfiguration(ApplicationProperties.get(), TitanGraphProvider.GRAPH_PREFIX);
}
@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 {
......@@ -52,27 +49,29 @@ public class TitanGraphProviderTest {
}
try {
TitanCleanup.clear(graph);
graph.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testValidate() throws AtlasException {
try {
TitanGraphProvider.validateIndexBackend(configuration);
} catch(Exception e){
Assert.fail("Unexpected exception ", e);
}
@Test
public void testValidate() throws AtlasException {
try {
Titan0Database.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!");
}
}
// 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!");
}
}
}
#
# 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
......@@ -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>
......@@ -980,12 +934,6 @@
</dependency>
<dependency>
<groupId>com.thinkaurelius.titan</groupId>
<artifactId>titan-es</artifactId>
<version>${titan.version}</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
......@@ -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>
......@@ -83,16 +88,6 @@
</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>
</dependency>
......
......@@ -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;
}
}
\ No newline at end of file
......@@ -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.
*/
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
/* (non-Javadoc)
* @see org.apache.atlas.repository.graph.GraphProvider#get()
*/
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;
}
public static void clear() {
synchronized (TitanGraphProvider.class) {
graphInstance.shutdown();
graphInstance = null;
}
return Titan0Database.getGraphInstance();
}
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!");
}
public static Configuration getConfiguration() throws AtlasException {
return Titan0Database.getConfiguration();
}
@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))
}
......
......@@ -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,6 +105,11 @@
<dependency>
<groupId>org.apache.atlas</groupId>
<artifactId>atlas-graphdb-titan0</artifactId>
</dependency>
<dependency>
<groupId>org.apache.atlas</groupId>
<artifactId>atlas-client</artifactId>
</dependency>
......@@ -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>
......@@ -166,16 +170,6 @@
</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>
</dependency>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment