Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 725ED200B69 for ; Sat, 6 Aug 2016 01:27:51 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 70F36160A8E; Fri, 5 Aug 2016 23:27:51 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 2D9B1160AAF for ; Sat, 6 Aug 2016 01:27:49 +0200 (CEST) Received: (qmail 25234 invoked by uid 500); 5 Aug 2016 23:27:48 -0000 Mailing-List: contact commits-help@atlas.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@atlas.incubator.apache.org Delivered-To: mailing list commits@atlas.incubator.apache.org Received: (qmail 25225 invoked by uid 99); 5 Aug 2016 23:27:48 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 05 Aug 2016 23:27:48 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id CC7AFC034D for ; Fri, 5 Aug 2016 23:27:47 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.646 X-Spam-Level: X-Spam-Status: No, score=-4.646 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id JWxMKskGsMv8 for ; Fri, 5 Aug 2016 23:27:35 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id 8672C5FAEF for ; Fri, 5 Aug 2016 23:27:32 +0000 (UTC) Received: (qmail 24596 invoked by uid 99); 5 Aug 2016 23:27:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 05 Aug 2016 23:27:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 7BA42EEB00; Fri, 5 Aug 2016 23:27:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: dkantor@apache.org To: commits@atlas.incubator.apache.org Date: Fri, 05 Aug 2016 23:27:35 -0000 Message-Id: <40a48a0391264ebb9a6381014e407719@git.apache.org> In-Reply-To: <5fb410cf8fa34b4e97e5e336f7d84b2a@git.apache.org> References: <5fb410cf8fa34b4e97e5e336f7d84b2a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [5/9] incubator-atlas git commit: ATLAS-693 Titan 0.5.4 implementation of graph db abstraction. (jnhagelb via dkantor) archived-at: Fri, 05 Aug 2016 23:27:51 -0000 http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Edge.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Edge.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Edge.java new file mode 100644 index 0000000..1d5d409 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Edge.java @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasVertex; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; + +/** + * Titan 0.5.4 implementation of AtlasEdge. + */ +public class Titan0Edge extends Titan0Element implements AtlasEdge { + + + 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 getInVertex() { + Vertex v = wrappedElement.getVertex(Direction.IN); + return GraphDbObjectFactory.createVertex(graph, v); + } + + @Override + public AtlasVertex getOutVertex() { + Vertex v = wrappedElement.getVertex(Direction.OUT); + return GraphDbObjectFactory.createVertex(graph, v); + } + + @Override + public String toString() { + return "Titan0Edge [id=" + getId() + "]"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Element.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Element.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Element.java new file mode 100644 index 0000000..cacbaf8 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Element.java @@ -0,0 +1,267 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasElement; +import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.thinkaurelius.titan.core.SchemaViolationException; +import com.thinkaurelius.titan.core.TitanElement; +import com.tinkerpop.blueprints.Element; +import com.tinkerpop.blueprints.util.io.graphson.GraphSONMode; +import com.tinkerpop.blueprints.util.io.graphson.GraphSONUtility; + +/** + * Titan 0.5.4 implementation of AtlasElement. + */ +public class Titan0Element 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 getPropertyKeys() { + return wrappedElement.getPropertyKeys(); + } + + @Override + public void setProperty(String propertyName, U value) { + try { + wrappedElement.setProperty(propertyName, value); + } catch (SchemaViolationException e) { + throw new AtlasSchemaViolationException(e); + } + } + + @Override + public U getProperty(String propertyName, Class clazz) { + return (U)convert(wrappedElement.getProperty(propertyName), clazz); + } + + /** + * Gets all of the values of the given property. + * @param propertyName + * @return + */ + @Override + public Collection getPropertyValues(String propertyName, Class type) { + return Collections.singleton(getProperty(propertyName, type)); + } + + @Override + public void removeProperty(String propertyName) { + wrappedElement.removeProperty(propertyName); + + } + + @Override + public JSONObject toJson(Set 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 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 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 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 getJsonProperty(String propertyName) { + return (T) getProperty(propertyName, String.class); + } + + @Override + public String getIdForDisplay() { + return getId().toString(); + } + + private T convert(Object propertyValue, Class 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 List getListProperty(String propertyName, Class elementType) { + + List value = getListProperty(propertyName); + + if(value == null) { + return null; + } + + if(AtlasEdge.class.isAssignableFrom(elementType)) { + + + return (List)Lists.transform(value, new Function(){ + + @Override + public AtlasEdge apply(String input) { + return graph.getEdge(input); + } + }); + } + + if(AtlasVertex.class.isAssignableFrom(elementType)) { + + return (List)Lists.transform(value, new Function(){ + + @Override + public AtlasVertex apply(String input) { + return graph.getVertex(input); + } + }); + } + + return (List)value; + } + + + @Override + public void setPropertyFromElementsIds(String propertyName, List values) { + List 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; + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Graph.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Graph.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Graph.java new file mode 100644 index 0000000..51531ed --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Graph.java @@ -0,0 +1,301 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.script.Bindings; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.graphdb.AtlasGraphManagement; +import org.apache.atlas.repository.graphdb.AtlasGraphQuery; +import org.apache.atlas.repository.graphdb.AtlasIndexQuery; +import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.graphdb.GremlinVersion; +import org.apache.atlas.repository.graphdb.titan0.query.Titan0GraphQuery; +import org.apache.atlas.typesystem.types.IDataType; +import org.apache.atlas.utils.IteratorToIterableAdapter; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.thinkaurelius.titan.core.SchemaViolationException; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanIndexQuery; +import com.thinkaurelius.titan.core.util.TitanCleanup; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Element; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.util.io.graphson.GraphSONWriter; +import com.tinkerpop.pipes.util.structures.Row; + + +/** + * Titan 0.5.4 implementation of AtlasGraph. + */ +public class Titan0Graph implements AtlasGraph { + + public Titan0Graph() { + + } + + @Override + public AtlasEdge addEdge(AtlasVertex outVertex, + AtlasVertex 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 query() { + + return new Titan0GraphQuery(this); + } + + @Override + public AtlasEdge getEdge(String edgeId) { + Edge edge = getGraph().getEdge(edgeId); + return GraphDbObjectFactory.createEdge(this, edge); + } + + @Override + public void removeEdge(AtlasEdge edge) { + getGraph().removeEdge(edge.getE().getWrappedElement()); + + } + + @Override + public void removeVertex(AtlasVertex vertex) { + getGraph().removeVertex(vertex.getV().getWrappedElement()); + + } + + @Override + public Iterable> getEdges() { + Iterable edges = getGraph().getEdges(); + return wrapEdges(edges); + } + + @Override + public Iterable> getVertices() { + Iterable vertices = getGraph().getVertices(); + return wrapVertices(vertices); + } + + @Override + public AtlasVertex 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 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 getVertexIndexKeys() { + return getIndexKeys(Vertex.class); + } + + @Override + public Set getEdgeIndexKeys() { + return getIndexKeys(Edge.class); + } + + private Set getIndexKeys(Class titanClass) { + + return getGraph().getIndexedKeys(titanClass); + } + + @Override + public AtlasVertex getVertex(String vertexId) { + Vertex v = getGraph().getVertex(vertexId); + return GraphDbObjectFactory.createVertex(this, v); + } + + @Override + public Iterable> getVertices(String key, Object value) { + + Iterable result = getGraph().getVertices(key, value); + return wrapVertices(result); + } + + @Override + public Object getGremlinColumnValue(Object rowValue, String colName, int idx) { + Row rV = (Row) 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 convertPathQueryResultToList(Object rawValue) { + return (List) 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> wrapEdges(Iterator it) { + + Iterable iterable = new IteratorToIterableAdapter(it); + return wrapEdges(iterable); + } + + public Iterable> wrapVertices(Iterator it) { + Iterable iterable = new IteratorToIterableAdapter(it); + return wrapVertices(iterable); + } + + public Iterable> wrapVertices(Iterable it) { + + return Iterables.transform(it, new Function>(){ + + @Override + public AtlasVertex apply(Vertex input) { + return GraphDbObjectFactory.createVertex(Titan0Graph.this, input); + } + }); + + } + + public Iterable> wrapEdges(Iterable it) { + Iterable result = (Iterable)it; + return Iterables.transform(result, new Function>(){ + + @Override + public AtlasEdge apply(Edge input) { + return GraphDbObjectFactory.createEdge(Titan0Graph.this, input); + } + }); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0GraphIndex.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0GraphIndex.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0GraphIndex.java new file mode 100644 index 0000000..7beed78 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0GraphIndex.java @@ -0,0 +1,96 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.atlas.repository.graphdb.titan0; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.atlas.repository.graphdb.AtlasGraphIndex; +import org.apache.atlas.repository.graphdb.AtlasPropertyKey; + +import com.thinkaurelius.titan.core.PropertyKey; +import com.thinkaurelius.titan.core.schema.TitanGraphIndex; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; + +/** + * Titan 0.5.4 implementation of AtlasGraphIndex. + */ +public class Titan0GraphIndex implements AtlasGraphIndex { + + private TitanGraphIndex wrappedIndex; + + public Titan0GraphIndex(TitanGraphIndex toWrap) { + wrappedIndex = toWrap; + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isMixedIndex() + */ + @Override + public boolean isMixedIndex() { + return wrappedIndex.isMixedIndex(); + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isEdgeIndex() + */ + @Override + public boolean isEdgeIndex() { + return Edge.class.isAssignableFrom(wrappedIndex.getIndexedElement()); + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isVertexIndex() + */ + @Override + public boolean isVertexIndex() { + return Vertex.class.isAssignableFrom(wrappedIndex.getIndexedElement()); + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isCompositeIndex() + */ + @Override + public boolean isCompositeIndex() { + return wrappedIndex.isCompositeIndex(); + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#isUnique() + */ + @Override + public boolean isUnique() { + return wrappedIndex.isUnique(); + } + + /* (non-Javadoc) + * @see org.apache.atlas.repository.graphdb.AtlasGraphIndex#getFieldKeys() + */ + @Override + public Set getFieldKeys() { + PropertyKey[] keys = wrappedIndex.getFieldKeys(); + Set result = new HashSet(); + for(PropertyKey key : keys) { + result.add(GraphDbObjectFactory.createPropertyKey(key)); + } + return result; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0IndexQuery.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0IndexQuery.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0IndexQuery.java new file mode 100644 index 0000000..18f0be5 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0IndexQuery.java @@ -0,0 +1,76 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import java.util.Iterator; + +import org.apache.atlas.repository.graphdb.AtlasIndexQuery; +import org.apache.atlas.repository.graphdb.AtlasVertex; + +import com.google.common.base.Function; +import com.google.common.collect.Iterators; +import com.thinkaurelius.titan.core.TitanIndexQuery; +import com.tinkerpop.blueprints.Vertex; + +/** + * Titan 0.5.4 implementation of AtlasIndexQuery. + */ +public class Titan0IndexQuery implements AtlasIndexQuery { + + private Titan0Graph graph; + private TitanIndexQuery wrappedIndexQuery; + + + public Titan0IndexQuery(Titan0Graph graph, TitanIndexQuery query) { + wrappedIndexQuery = query; + this.graph = graph; + } + + @Override + public Iterator> vertices() { + Iterator> results = wrappedIndexQuery.vertices().iterator(); + + Function, AtlasIndexQuery.Result> function = + new Function, AtlasIndexQuery.Result>() { + + @Override + public AtlasIndexQuery.Result apply(TitanIndexQuery.Result source) { + return new ResultImpl(source); + } + }; + return Iterators.transform(results, function); + } + + private final class ResultImpl implements AtlasIndexQuery.Result { + private TitanIndexQuery.Result wrappedResult; + + public ResultImpl(TitanIndexQuery.Result source) { + wrappedResult = source; + } + + @Override + public AtlasVertex getVertex() { + return GraphDbObjectFactory.createVertex(graph, wrappedResult.getElement()); + } + + @Override + public double getScore() { + return wrappedResult.getScore(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0PropertyKey.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0PropertyKey.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0PropertyKey.java new file mode 100644 index 0000000..1f9f6ef --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0PropertyKey.java @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.atlas.repository.graphdb.titan0; + +import org.apache.atlas.repository.graphdb.AtlasPropertyKey; + +import com.thinkaurelius.titan.core.PropertyKey; + +/** + * Titan 0.5.4 implementaiton of AtlasPropertyKey. + */ +public class Titan0PropertyKey implements AtlasPropertyKey { + + private PropertyKey wrappedPropertyKey; + + public Titan0PropertyKey(PropertyKey toWrap) { + wrappedPropertyKey = toWrap; + } + + /* + * (non-Javadoc) + * + * @see org.apache.atlas.repository.graphdb.AtlasPropertyKey#getName() + */ + @Override + public String getName() { + return wrappedPropertyKey.getName(); + } + + /** + * @return + */ + public PropertyKey getWrappedPropertyKey() { + return wrappedPropertyKey; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Titan0PropertyKey)) { + return false; + } + Titan0PropertyKey otherKey = (Titan0PropertyKey) other; + return wrappedPropertyKey.equals(otherKey.wrappedPropertyKey); + } + + @Override + public int hashCode() { + int result = 17; + result = 37 * result + wrappedPropertyKey.hashCode(); + return result; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Vertex.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Vertex.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Vertex.java new file mode 100644 index 0000000..b26ff04 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0Vertex.java @@ -0,0 +1,135 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; +import org.apache.atlas.repository.graphdb.AtlasGraphManagement; +import org.apache.atlas.repository.graphdb.AtlasSchemaViolationException; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.graphdb.AtlasVertexQuery; + +import com.thinkaurelius.titan.core.SchemaViolationException; +import com.thinkaurelius.titan.core.TitanProperty; +import com.thinkaurelius.titan.core.TitanVertex; +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; + +/** + * Titan 0.5.4 implementation of AtlasVertex. + */ +public class Titan0Vertex extends Titan0Element implements AtlasVertex { + + public Titan0Vertex(Titan0Graph graph, Vertex source) { + super(graph, source); + } + + @Override + public Iterable> getEdges(AtlasEdgeDirection dir, String edgeLabel) { + Iterable titanEdges = wrappedElement.getEdges(TitanObjectFactory.createDirection(dir), edgeLabel); + return graph.wrapEdges(titanEdges); + } + + private TitanVertex getAsTitanVertex() { + return (TitanVertex) wrappedElement; + } + + @Override + public Iterable> getEdges(AtlasEdgeDirection in) { + Iterable titanResult = wrappedElement.getEdges(TitanObjectFactory.createDirection(in)); + return graph.wrapEdges(titanResult); + + } + + @Override + public T getProperty(String propertyName, Class 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 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 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 Collection getPropertyValues(String key, Class clazz) { + + TitanVertex tv = getAsTitanVertex(); + Collection result = new ArrayList(); + for (TitanProperty property : tv.getProperties(key)) { + result.add((T) property.getValue()); + } + return result; + } + + @Override + public AtlasVertexQuery 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() + "]"; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0VertexQuery.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0VertexQuery.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0VertexQuery.java new file mode 100644 index 0000000..bd8b897 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/Titan0VertexQuery.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.graphdb.AtlasVertexQuery; + +import com.tinkerpop.blueprints.Edge; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.VertexQuery; + +/** + * Titan 0.5.4 implementation of AtlasVertexQuery. + */ +public class Titan0VertexQuery implements AtlasVertexQuery { + + private Titan0Graph graph; + private VertexQuery vertexQuery; + + public Titan0VertexQuery(Titan0Graph graph, VertexQuery vertexQuery) { + this.vertexQuery = vertexQuery; + this.graph = graph; + } + + @Override + public AtlasVertexQuery direction(AtlasEdgeDirection queryDirection) { + vertexQuery.direction(TitanObjectFactory.createDirection(queryDirection)); + return this; + + } + + @Override + public Iterable> vertices() { + Iterable vertices = vertexQuery.vertices(); + return graph.wrapVertices(vertices); + } + + @Override + public Iterable> edges() { + Iterable edges = vertexQuery.edges(); + return graph.wrapEdges(edges); + } + + @Override + public long count() { + return vertexQuery.count(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/TitanObjectFactory.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/TitanObjectFactory.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/TitanObjectFactory.java new file mode 100644 index 0000000..ab0e798 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/TitanObjectFactory.java @@ -0,0 +1,83 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0; + +import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; +import org.apache.atlas.repository.graphdb.AtlasPropertyKey; +import org.apache.atlas.typesystem.types.Multiplicity; + +import com.thinkaurelius.titan.core.Cardinality; +import com.thinkaurelius.titan.core.PropertyKey; +import com.tinkerpop.blueprints.Direction; + +/** + * Factory that serves up instances of Titan/Tinkerpop classes that correspond to + * graph database abstraction layer/Atlas classes. + */ +public final class TitanObjectFactory { + + private TitanObjectFactory() { + + } + + /** + * Retrieves the titan direction corresponding to the given + * AtlasEdgeDirection. + * + * @param dir + * @return + */ + public static Direction createDirection(AtlasEdgeDirection dir) { + + switch(dir) { + case IN: + return Direction.IN; + case OUT: + return Direction.OUT; + case BOTH: + return Direction.BOTH; + default: + throw new RuntimeException("Unrecognized direction: " + dir); + } + } + + + /** + * Converts a Multiplicity to a Cardinality. + * + * @param multiplicity + * @return + */ + public static Cardinality createCardinality(Multiplicity multiplicity) { + + if (multiplicity == Multiplicity.OPTIONAL || multiplicity == Multiplicity.REQUIRED) { + return Cardinality.SINGLE; + } else if (multiplicity == Multiplicity.COLLECTION) { + return Cardinality.LIST; + } else if (multiplicity == Multiplicity.SET) { + return Cardinality.SET; + } + // default to LIST as this is the most forgiving + return Cardinality.LIST; + } + + public static PropertyKey createPropertyKey(AtlasPropertyKey key) { + return ((Titan0PropertyKey)key).getWrappedPropertyKey(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java new file mode 100644 index 0000000..cfd9905 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java @@ -0,0 +1,88 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0.query; + +import java.util.Collection; + +import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery; +import org.apache.atlas.repository.graphdb.titan0.Titan0Database; +import org.apache.atlas.repository.graphdb.titan0.Titan0Edge; +import org.apache.atlas.repository.graphdb.titan0.Titan0Graph; +import org.apache.atlas.repository.graphdb.titan0.Titan0Vertex; + +import com.thinkaurelius.titan.core.TitanGraphQuery; +import com.thinkaurelius.titan.core.attribute.Contain; +import com.thinkaurelius.titan.graphdb.query.TitanPredicate; +import com.tinkerpop.blueprints.Compare; + +/** + * Titan 0.5.4 implementation of NativeTitanGraphQuery. + * + * @author jeff + * + */ +public class NativeTitan0GraphQuery implements NativeTitanGraphQuery { + + private Titan0Graph graph_; + private TitanGraphQuery query_; + + public NativeTitan0GraphQuery(Titan0Graph graph) { + query_ = Titan0Database.getGraphInstance().query(); + graph_ = graph; + } + + @Override + public Iterable> vertices() { + Iterable it = query_.vertices(); + return graph_.wrapVertices(it); + } + + + @Override + public void in(String propertyName, Collection 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); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/Titan0GraphQuery.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/Titan0GraphQuery.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/Titan0GraphQuery.java new file mode 100644 index 0000000..6c12ac2 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/Titan0GraphQuery.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.atlas.repository.graphdb.titan0.query; + +import org.apache.atlas.repository.graphdb.AtlasGraphQuery; +import org.apache.atlas.repository.graphdb.titan.query.TitanGraphQuery; +import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery; +import org.apache.atlas.repository.graphdb.titan.query.NativeTitanQueryFactory; +import org.apache.atlas.repository.graphdb.titan0.Titan0Edge; +import org.apache.atlas.repository.graphdb.titan0.Titan0Graph; +import org.apache.atlas.repository.graphdb.titan0.Titan0Vertex; + +/** + * Titan 0.5.4 implementation of AtlasGraphQuery. + */ +public class Titan0GraphQuery extends TitanGraphQuery implements NativeTitanQueryFactory { + + public Titan0GraphQuery(Titan0Graph graph, boolean isChildQuery) { + super(graph, isChildQuery); + } + + public Titan0GraphQuery(Titan0Graph graph) { + super(graph); + } + + @Override + public AtlasGraphQuery createChildQuery() { + return new Titan0GraphQuery((Titan0Graph)graph_, true); + } + + @Override + protected NativeTitanQueryFactory getQueryFactory() { + return this; + } + + + @Override + public NativeTitanGraphQuery createNativeTitanQuery() { + return new NativeTitan0GraphQuery((Titan0Graph)graph_); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/main/java/org/apache/atlas/utils/IteratorToIterableAdapter.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/utils/IteratorToIterableAdapter.java b/graphdb/titan0/src/main/java/org/apache/atlas/utils/IteratorToIterableAdapter.java new file mode 100644 index 0000000..ed7c2a7 --- /dev/null +++ b/graphdb/titan0/src/main/java/org/apache/atlas/utils/IteratorToIterableAdapter.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.atlas.utils; + +import java.util.Iterator; + +/** + * Adapter class that allows an Iterator to be presented as an instance of java.util.Iterable. + */ +public final class IteratorToIterableAdapter implements Iterable { + + private final Iterator wrapped; + + public IteratorToIterableAdapter(Iterator wrapped) { + this.wrapped = wrapped; + } + + @Override + public Iterator iterator() { + return wrapped; + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/hbase/HBaseKeyColumnValueStoreTest.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/hbase/HBaseKeyColumnValueStoreTest.java b/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/hbase/HBaseKeyColumnValueStoreTest.java new file mode 100644 index 0000000..21087a5 --- /dev/null +++ b/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/hbase/HBaseKeyColumnValueStoreTest.java @@ -0,0 +1,139 @@ +/** + * 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 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; +import com.thinkaurelius.titan.diskstorage.configuration.Configuration; +import com.thinkaurelius.titan.diskstorage.locking.LocalLockMediator; +import com.thinkaurelius.titan.diskstorage.locking.PermanentLockingException; +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; + +public class HBaseKeyColumnValueStoreTest { + + @Mock + HBaseStoreManager storeManager; + + @Mock + ConnectionMask connectionMask; + + @Mock + LocalLockMediator localLockMediator; + + @Mock + StaticBuffer key; + + @Mock + StaticBuffer column; + + @Mock + StaticBuffer expectedValue; + + @Mock + HBaseTransaction transaction; + + @Mock + Configuration storageConfig; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void shouldSucceedInLockingIfLockMediatorSucceeds() throws BackendException { + + when(storeManager.getMetaDataSchema("hbase")).thenReturn(new EntryMetaData[] {EntryMetaData.TIMESTAMP}); + when(storeManager.getStorageConfig()).thenReturn(storageConfig); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_EXPIRE)).thenReturn( + new StandardDuration(300L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_WAIT)).thenReturn( + new StandardDuration(10L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_RETRY)).thenReturn(3); + KeyColumn lockID = new KeyColumn(key, column); + when(localLockMediator.lock(eq(lockID), eq(transaction), any(Timepoint.class))). + thenReturn(true); + + HBaseKeyColumnValueStore hBaseKeyColumnValueStore = + new HBaseKeyColumnValueStore(storeManager, connectionMask, "titan", "e", "hbase", localLockMediator); + hBaseKeyColumnValueStore.acquireLock(key, column, expectedValue, transaction); + + verify(transaction).updateLocks(lockID, expectedValue); + verify(localLockMediator, times(1)).lock(eq(lockID), eq(transaction), any(Timepoint.class)); + } + + @Test + public void shouldRetryRightNumberOfTimesIfLockMediationFails() throws BackendException { + when(storeManager.getMetaDataSchema("hbase")).thenReturn(new EntryMetaData[] {EntryMetaData.TIMESTAMP}); + when(storeManager.getStorageConfig()).thenReturn(storageConfig); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_EXPIRE)).thenReturn( + new StandardDuration(300L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_WAIT)).thenReturn( + new StandardDuration(10L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_RETRY)).thenReturn(3); + KeyColumn lockID = new KeyColumn(key, column); + when(localLockMediator.lock(eq(lockID), eq(transaction), any(Timepoint.class))). + thenReturn(false).thenReturn(false).thenReturn(true); + + HBaseKeyColumnValueStore hBaseKeyColumnValueStore = + new HBaseKeyColumnValueStore(storeManager, connectionMask, "titan", "e", "hbase", localLockMediator); + hBaseKeyColumnValueStore.acquireLock(key, column, expectedValue, transaction); + + verify(transaction).updateLocks(lockID, expectedValue); + verify(localLockMediator, times(3)).lock(eq(lockID), eq(transaction), any(Timepoint.class)); + } + + @Test(expectedExceptions = PermanentLockingException.class) + public void shouldThrowExceptionAfterConfiguredRetriesIfLockMediationFails() throws BackendException { + when(storeManager.getMetaDataSchema("hbase")).thenReturn(new EntryMetaData[] {EntryMetaData.TIMESTAMP}); + when(storeManager.getStorageConfig()).thenReturn(storageConfig); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_EXPIRE)).thenReturn( + new StandardDuration(300L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_WAIT)).thenReturn( + new StandardDuration(10L, TimeUnit.MILLISECONDS)); + when(storageConfig.get(GraphDatabaseConfiguration.LOCK_RETRY)).thenReturn(3); + KeyColumn lockID = new KeyColumn(key, column); + when(localLockMediator.lock(eq(lockID), eq(transaction), any(Timepoint.class))). + thenReturn(false).thenReturn(false).thenReturn(false); + + HBaseKeyColumnValueStore hBaseKeyColumnValueStore = + new HBaseKeyColumnValueStore(storeManager, connectionMask, "titan", "e", "hbase", localLockMediator); + hBaseKeyColumnValueStore.acquireLock(key, column, expectedValue, transaction); + + fail("Should fail as lock could not be acquired after 3 retries."); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/locking/LocalLockMediatorTest.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/locking/LocalLockMediatorTest.java b/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/locking/LocalLockMediatorTest.java new file mode 100644 index 0000000..d0fd401 --- /dev/null +++ b/graphdb/titan0/src/test/java/com/thinkaurelius/titan/diskstorage/locking/LocalLockMediatorTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2013 Aurelius LLC + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.thinkaurelius.titan.diskstorage.locking; + +import com.thinkaurelius.titan.diskstorage.hbase.HBaseTransaction; +import com.thinkaurelius.titan.diskstorage.util.time.TimestampProvider; +import com.thinkaurelius.titan.diskstorage.util.time.Timestamps; +import com.thinkaurelius.titan.diskstorage.StaticBuffer; +import com.thinkaurelius.titan.diskstorage.util.KeyColumn; +import com.thinkaurelius.titan.diskstorage.util.StaticArrayBuffer; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.concurrent.TimeUnit; + +public class LocalLockMediatorTest { + + private static final String LOCK_NAMESPACE = "test"; + private static final StaticBuffer LOCK_ROW = StaticArrayBuffer.of(new byte[]{1}); + private static final StaticBuffer LOCK_COL = StaticArrayBuffer.of(new byte[]{1}); + private static final KeyColumn kc = new KeyColumn(LOCK_ROW, LOCK_COL); + private static final HBaseTransaction mockTx1 = Mockito.mock(HBaseTransaction.class); + private static final HBaseTransaction mockTx2 = Mockito.mock(HBaseTransaction.class); + + @Test + public void testLock() throws InterruptedException { + TimestampProvider times = Timestamps.MICRO; + LocalLockMediator llm = + new LocalLockMediator(LOCK_NAMESPACE, times); + + //Expire immediately + Assert.assertTrue(llm.lock(kc, mockTx1, times.getTime(0, TimeUnit.NANOSECONDS))); + Assert.assertTrue(llm.lock(kc, mockTx2, times.getTime(Long.MAX_VALUE, TimeUnit.NANOSECONDS))); + + llm = new LocalLockMediator(LOCK_NAMESPACE, times); + + //Expire later + Assert.assertTrue(llm.lock(kc, mockTx1, times.getTime(Long.MAX_VALUE, TimeUnit.NANOSECONDS))); + //So second lock should fail on same keyCol + Assert.assertFalse(llm.lock(kc, mockTx2, times.getTime(Long.MAX_VALUE, TimeUnit.NANOSECONDS))); + + //Unlock + Assert.assertTrue(llm.unlock(kc, mockTx1)); + //Now locking should succeed + Assert.assertTrue(llm.lock(kc, mockTx2, times.getTime(Long.MAX_VALUE, TimeUnit.NANOSECONDS))); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/AbstractGraphDatabaseTest.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/AbstractGraphDatabaseTest.java b/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/AbstractGraphDatabaseTest.java new file mode 100644 index 0000000..35735e3 --- /dev/null +++ b/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/AbstractGraphDatabaseTest.java @@ -0,0 +1,200 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.atlas.repository.graphdb.titan0; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.atlas.repository.Constants; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.graphdb.AtlasGraphManagement; +import org.apache.atlas.repository.graphdb.AtlasPropertyKey; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.typesystem.types.Multiplicity; +import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; + +/** + * + */ +public abstract class AbstractGraphDatabaseTest { + + private static class RunnableWrapper implements Runnable { + private final Runnable r; + private Throwable exceptionThrown_ = null; + + private RunnableWrapper(Runnable r) { + this.r = r; + } + + @Override + public void run() { + try { + r.run(); + } + catch(Throwable e) { + exceptionThrown_ = e; + } + + } + + public Throwable getExceptionThrown() { + return exceptionThrown_; + } + } + + protected static final String WEIGHT_PROPERTY = "weight"; + protected static final String TRAIT_NAMES = Constants.TRAIT_NAMES_PROPERTY_KEY; + protected static final String typeProperty = "__type"; + protected static final String typeSystem = "typeSystem"; + + /** + * + */ + private static final String BACKING_INDEX_NAME = "backing"; + + private AtlasGraph graph = null; + + @AfterMethod + public void commitGraph() { + //force any pending actions to be committed so we can be sure they don't cause errors. + pushChangesAndFlushCache(); + graph.commit(); + } + protected void pushChangesAndFlushCache() { + AtlasGraph 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 AtlasGraph getGraph() { + if(graph == null) { + graph = new Titan0Graph(); + } + return (AtlasGraph)graph; + } + + protected Titan0Graph getTitan0Graph() { + AtlasGraph g = getGraph(); + return (Titan0Graph)g; + } + + + protected List newVertices_ = new ArrayList<>(); + + protected final AtlasVertex createVertex(AtlasGraph graph) { + AtlasVertex 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 http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4fa10b6a/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/GraphQueryTest.java ---------------------------------------------------------------------- diff --git a/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/GraphQueryTest.java b/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/GraphQueryTest.java new file mode 100644 index 0000000..d02dce9 --- /dev/null +++ b/graphdb/titan0/src/test/java/org/apache/atlas/repository/graphdb/titan0/GraphQueryTest.java @@ -0,0 +1,447 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.atlas.repository.graphdb.titan0; + + + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.apache.atlas.AtlasException; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.graphdb.AtlasGraphQuery; +import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; + + + +/** + * Tests for Titan0GraphQuery + */ +@Test +public class GraphQueryTest extends AbstractGraphDatabaseTest { + + + @Test + public void testQueryThatCannotRunInMemory() throws AtlasException { + AtlasGraph graph = getGraph(); + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + + graph.commit(); + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Fred"); + v4.setProperty("size15", "15"); + + AtlasGraphQuery q = graph.query(); + q.has("name", ComparisionOperator.NOT_EQUAL, "George"); + q.has("size15","15"); + graph.commit(); + pause(); //pause to let the index get updated + + assertQueryMatches(q, v1, v3, v4); + + } + + @Test + public void testCombinationOfAndsAndOrs() throws AtlasException { + Titan0Graph graph = getTitan0Graph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + v1.setProperty("typeName", "Person"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "George"); + v2.setProperty("size15", "16"); + v2.setProperty("typeName", "Person"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("name", "Jane"); + v3.setProperty("size15", "17"); + v3.setProperty("typeName", "Person"); + + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Bob"); + v4.setProperty("size15", "18"); + v4.setProperty("typeName", "Person"); + + AtlasVertex v5 = createVertex(graph); + v5.setProperty("name", "Julia"); + v5.setProperty("size15", "19"); + v5.setProperty("typeName", "Manager"); + + + AtlasGraphQuery q = getGraphQuery(); + q.has("typeName","Person"); + //initially match + AtlasGraphQuery inner1a = q.createChildQuery(); + AtlasGraphQuery inner1b = q.createChildQuery(); + inner1a.has("name","Fred"); + inner1b.has("name","Jane"); + q.or(toList(inner1a, inner1b)); + + + AtlasGraphQuery inner2a = q.createChildQuery(); + AtlasGraphQuery inner2b = q.createChildQuery(); + AtlasGraphQuery inner2c = q.createChildQuery(); + inner2a.has("size15","18"); + inner2b.has("size15","15"); + inner2c.has("size15", "16"); + q.or(toList(inner2a, inner2b, inner2c)); + + assertQueryMatches(q, v1); + graph.commit(); + pause(); //let the index update + assertQueryMatches(q, v1); + } + + @Test + public void testWithinStep() throws AtlasException { + Titan0Graph graph = getTitan0Graph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + v1.setProperty("typeName", "Person"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "George"); + v2.setProperty("size15", "16"); + v2.setProperty("typeName", "Person"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("name", "Jane"); + v3.setProperty("size15", "17"); + v3.setProperty("typeName", "Person"); + + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Bob"); + v4.setProperty("size15", "18"); + v4.setProperty("typeName", "Person"); + + AtlasVertex v5 = createVertex(graph); + v5.setProperty("name", "Julia"); + v5.setProperty("size15", "19"); + v5.setProperty("typeName", "Manager"); + + + AtlasGraphQuery q = getGraphQuery(); + q.has("typeName","Person"); + //initially match + q.in("name", toList("Fred", "Jane")); + q.in("size15", toList("18", "15", "16")); + + assertQueryMatches(q, v1); + graph.commit(); + pause(); //let the index update + assertQueryMatches(q, v1); + } + + @Test + public void testWithinStepWhereGraphIsStale() throws AtlasException { + Titan0Graph graph = getTitan0Graph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + v1.setProperty("typeName", "Person"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "George"); + v2.setProperty("size15", "16"); + v2.setProperty("typeName", "Person"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("name", "Jane"); + v3.setProperty("size15", "17"); + v3.setProperty("typeName", "Person"); + + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Bob"); + v4.setProperty("size15", "18"); + v4.setProperty("typeName", "Person"); + + AtlasVertex v5 = createVertex(graph); + v5.setProperty("name", "Julia"); + v5.setProperty("size15", "19"); + v5.setProperty("typeName", "Manager"); + + + AtlasGraphQuery q = getGraphQuery(); + q.has("typeName","Person"); + //initially match + q.in("name", toList("Fred", "Jane")); + + graph.commit(); + pause(); //let the index update + assertQueryMatches(q, v1, v3); + v3.setProperty("name", "Janet"); //make v3 no longer match the query. Within step should filter out the vertex since it no longer matches. + assertQueryMatches(q, v1); + } + + @Test + public void testSimpleOrQuery() throws AtlasException { + Titan0Graph graph = getTitan0Graph(); + + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + + graph.commit(); + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Fred"); + v4.setProperty("size15", "15"); + + AtlasVertex v5 = createVertex(graph); + v5.setProperty("name", "George"); + v5.setProperty("size15", "16"); + + AtlasGraphQuery q = graph.query(); + AtlasGraphQuery inner1 = q.createChildQuery().has("name", "Fred"); + AtlasGraphQuery inner2 = q.createChildQuery().has("size15", "15"); + q.or(toList(inner1, inner2)); + assertQueryMatches(q, v1, v2, v3, v4); + graph.commit(); + pause(); //pause to let the indexer get updated (this fails frequently without a pause) + assertQueryMatches(q, v1, v2, v3, v4); + } + + + + + @Test + public void testQueryMatchesAddedVertices() throws AtlasException { + AtlasGraph graph = getGraph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + + graph.commit(); + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Fred"); + v4.setProperty("size15", "15"); + + AtlasGraphQuery q = getGraphQuery(); + q.has("name", "Fred"); + q.has("size15","15"); + + assertQueryMatches(q, v1, v4); + graph.commit(); + assertQueryMatches(q, v1, v4); + + } + + + @Test + public void testQueryDoesNotMatchRemovedVertices() throws AtlasException { + AtlasGraph graph = getGraph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Fred"); + v4.setProperty("size15", "15"); + + graph.commit(); + + graph.removeVertex(v1); + + AtlasGraphQuery q = getGraphQuery(); + q.has("name", "Fred"); + q.has("size15","15"); + + assertQueryMatches(q, v4); + graph.commit(); + + assertQueryMatches(q, v4); + } + + @Test + public void testQueryDoesNotMatchUncommittedAddedAndRemovedVertices() throws AtlasException { + AtlasGraph graph = getGraph(); + + AtlasVertex v1 = createVertex(graph); + + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + + AtlasVertex v4 = createVertex(graph); + v4.setProperty("name", "Fred"); + v4.setProperty("size15", "15"); + + + AtlasGraphQuery q = getGraphQuery(); + q.has("name", "Fred"); + q.has("size15","15"); + + assertQueryMatches(q, v1, v4); + + graph.removeVertex(v1); + + + assertQueryMatches(q, v4); + graph.commit(); + + assertQueryMatches(q, v4); + } + + + @Test + public void testQueryResultsReflectPropertyAdd() throws AtlasException { + AtlasGraph graph = getGraph(); + + AtlasVertex v1 = createVertex(graph); + v1.setProperty("name", "Fred"); + v1.setProperty("size15", "15"); + v1.addProperty(TRAIT_NAMES, "trait1"); + v1.addProperty(TRAIT_NAMES, "trait2"); + + AtlasVertex v2 = createVertex(graph); + v2.setProperty("name", "Fred"); + v2.addProperty(TRAIT_NAMES, "trait1"); + + AtlasVertex v3 = createVertex(graph); + v3.setProperty("size15", "15"); + v3.addProperty(TRAIT_NAMES, "trait2"); + + AtlasGraphQuery query = getGraphQuery(); + query.has("name", "Fred"); + query.has(TRAIT_NAMES, "trait1"); + query.has("size15", "15"); + + assertQueryMatches(query, v1); + //make v3 match the query + v3.setProperty("name", "Fred"); + v3.addProperty(TRAIT_NAMES, "trait1"); + assertQueryMatches(query, v1, v3); + v3.removeProperty(TRAIT_NAMES); + assertQueryMatches(query, v1); + v3.addProperty(TRAIT_NAMES, "trait2"); + assertQueryMatches(query, v1); + v1.removeProperty(TRAIT_NAMES); + assertQueryMatches(query); + graph.commit(); + assertQueryMatches(query); + + } + + private static List toList(Iterable itr) { + List result = new ArrayList(); + for(T object : itr) { + result.add(object); + } + return result; + + } + + private void assertQueryMatches(AtlasGraphQuery expr, AtlasVertex... expectedResults) throws AtlasException { + + //getGraph().commit(); + Collection> temp = toList(expr.vertices()); + //filter out vertices from previous test executions + Collection> result = Collections2.filter(temp, new Predicate>() { + + @Override + public boolean apply(AtlasVertex input) { + return newVertices_.contains(input); + } + + }); + assertEquals("Expected/found result sizes differ. Expected: " + Arrays.asList(expectedResults).toString() +", found: " + result, expectedResults.length, result.size()); + + for(AtlasVertex v : expectedResults) { + assertTrue(result.contains(v)); + } + } + + private static List toList(Object...objects) { + return Arrays.asList(objects); + } + + private AtlasGraphQuery getGraphQuery() { + return getTitan0Graph().query(); + } + + private void pause() { + try { + Thread.sleep(5000); + } + catch(InterruptedException e) + {} + } +}