diff --git a/.github/workflows/client-ci.yml b/.github/workflows/client-ci.yml index ee5e95620..7ba285c3d 100644 --- a/.github/workflows/client-ci.yml +++ b/.github/workflows/client-ci.yml @@ -24,7 +24,8 @@ jobs: env: USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-client/assembly/travis - COMMIT_ID: bfe9fae150446857412db23ada0dae9d05035837 + # TODO: replace it with the (latest - n) commit id (n >= 15) + COMMIT_ID: b52517c strategy: fail-fast: false matrix: diff --git a/.github/workflows/client-go-ci.yml b/.github/workflows/client-go-ci.yml index 2a941a0d0..b29b6304f 100644 --- a/.github/workflows/client-go-ci.yml +++ b/.github/workflows/client-go-ci.yml @@ -23,7 +23,8 @@ jobs: env: USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-client/assembly/travis - COMMIT_ID: bfe9fae150446857412db23ada0dae9d05035837 + # TODO: replace it with the (latest - n) commit id (n >= 15) + COMMIT_ID: b52517c strategy: fail-fast: false matrix: diff --git a/.github/workflows/hubble-ci.yml b/.github/workflows/hubble-ci.yml index d88c65092..35016394b 100644 --- a/.github/workflows/hubble-ci.yml +++ b/.github/workflows/hubble-ci.yml @@ -23,8 +23,8 @@ on: env: TRAVIS_DIR: hugegraph-hubble/hubble-dist/assembly/travis - # TODO: need update it later (eed6103359fe40d2f1476fb8c56d9388c3111a99) - COMMIT_ID: bfe9fae150446857412db23ada0dae9d05035837 + # TODO: replace it with the (latest - n) commit id (n >= 15) + COMMIT_ID: b52517c jobs: hubble-ci: diff --git a/.github/workflows/loader-ci.yml b/.github/workflows/loader-ci.yml index 70849b521..c983eee5f 100644 --- a/.github/workflows/loader-ci.yml +++ b/.github/workflows/loader-ci.yml @@ -26,7 +26,8 @@ jobs: USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-loader/assembly/travis STATIC_DIR: hugegraph-loader/assembly/static - COMMIT_ID: bfe9fae150446857412db23ada0dae9d05035837 + # TODO: replace it with the (latest - n) commit id (n >= 15) + COMMIT_ID: b52517c DB_USER: root DB_PASS: root DB_DATABASE: load_test diff --git a/.github/workflows/tools-ci.yml b/.github/workflows/tools-ci.yml index ea4756d70..ac0673d84 100644 --- a/.github/workflows/tools-ci.yml +++ b/.github/workflows/tools-ci.yml @@ -25,7 +25,8 @@ jobs: USE_STAGE: 'true' # Whether to include the stage repository. TRAVIS_DIR: hugegraph-tools/assembly/travis # TODO: could we use one param to unify it? or use a action template (could use one ci file) - COMMIT_ID: bfe9fae150446857412db23ada0dae9d05035837 + # TODO: replace it with the (latest - n) commit id (n >= 15) + COMMIT_ID: b52517c steps: - name: Install JDK 11 uses: actions/setup-java@v3 diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java new file mode 100644 index 000000000..a62a7972c --- /dev/null +++ b/hugegraph-client/src/main/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPI.java @@ -0,0 +1,59 @@ +/* + * 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.hugegraph.api.traverser; + + +import org.apache.hugegraph.api.graph.GraphAPI; +import org.apache.hugegraph.client.RestClient; +import org.apache.hugegraph.rest.RestResult; +import org.apache.hugegraph.structure.graph.Edge; +import org.apache.logging.log4j.util.Strings; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class EdgeExistenceAPI extends TraversersAPI { + + public EdgeExistenceAPI(RestClient client, String graph) { + super(client, graph); + } + + @Override + protected String type() { + return "edgeexist"; + } + + public List get(Object sourceId, Object targetId, String edgeLabel, + String sortValues, int limit) { + this.client.checkApiVersion("0.70", "count"); + String source = GraphAPI.formatVertexId(sourceId, false); + String target = GraphAPI.formatVertexId(targetId, false); + + Map params = new LinkedHashMap<>(); + params.put("source", source); + params.put("target", target); + params.put("label", edgeLabel); + if (!Strings.isEmpty(sortValues)) { + params.put("sort_values", sortValues); + } + params.put("limit", limit); + RestResult result = this.client.get(this.path(), params); + return result.readList("edges", Edge.class); + } +} diff --git a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java index 3d9d1208e..580813426 100644 --- a/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java +++ b/hugegraph-client/src/main/java/org/apache/hugegraph/driver/TraverserManager.java @@ -42,6 +42,7 @@ import org.apache.hugegraph.api.traverser.TemplatePathsAPI; import org.apache.hugegraph.api.traverser.VerticesAPI; import org.apache.hugegraph.api.traverser.WeightedShortestPathAPI; +import org.apache.hugegraph.api.traverser.EdgeExistenceAPI; import org.apache.hugegraph.client.RestClient; import org.apache.hugegraph.structure.constant.Direction; import org.apache.hugegraph.structure.constant.Traverser; @@ -76,28 +77,29 @@ public class TraverserManager { private final GraphManager graphManager; - private JaccardSimilarityAPI jaccardSimilarityAPI; - private SameNeighborsAPI sameNeighborsAPI; - private ShortestPathAPI shortestPathAPI; - private AllShortestPathsAPI allShortestPathsAPI; - private SingleSourceShortestPathAPI singleSourceShortestPathAPI; - private WeightedShortestPathAPI weightedShortestPathAPI; - private MultiNodeShortestPathAPI multiNodeShortestPathAPI; - private PathsAPI pathsAPI; - private CrosspointsAPI crosspointsAPI; - private KoutAPI koutAPI; - private KneighborAPI kneighborAPI; - private CountAPI countAPI; - private RingsAPI ringsAPI; - private RaysAPI raysAPI; - private CustomizedPathsAPI customizedPathsAPI; - private CustomizedCrosspointsAPI customizedCrosspointsAPI; - private TemplatePathsAPI templatePathsAPI; - private FusiformSimilarityAPI fusiformSimilarityAPI; - private NeighborRankAPI neighborRankAPI; - private PersonalRankAPI personalRankAPI; - private VerticesAPI verticesAPI; - private EdgesAPI edgesAPI; + private final JaccardSimilarityAPI jaccardSimilarityAPI; + private final SameNeighborsAPI sameNeighborsAPI; + private final ShortestPathAPI shortestPathAPI; + private final AllShortestPathsAPI allShortestPathsAPI; + private final SingleSourceShortestPathAPI singleSourceShortestPathAPI; + private final WeightedShortestPathAPI weightedShortestPathAPI; + private final MultiNodeShortestPathAPI multiNodeShortestPathAPI; + private final PathsAPI pathsAPI; + private final CrosspointsAPI crosspointsAPI; + private final KoutAPI koutAPI; + private final KneighborAPI kneighborAPI; + private final CountAPI countAPI; + private final RingsAPI ringsAPI; + private final RaysAPI raysAPI; + private final CustomizedPathsAPI customizedPathsAPI; + private final CustomizedCrosspointsAPI customizedCrosspointsAPI; + private final TemplatePathsAPI templatePathsAPI; + private final FusiformSimilarityAPI fusiformSimilarityAPI; + private final NeighborRankAPI neighborRankAPI; + private final PersonalRankAPI personalRankAPI; + private final VerticesAPI verticesAPI; + private final EdgesAPI edgesAPI; + private final EdgeExistenceAPI edgeExistenceAPI; public TraverserManager(RestClient client, GraphManager graphManager) { this.graphManager = graphManager; @@ -124,6 +126,7 @@ public TraverserManager(RestClient client, GraphManager graphManager) { this.personalRankAPI = new PersonalRankAPI(client, graph); this.verticesAPI = new VerticesAPI(client, graph); this.edgesAPI = new EdgesAPI(client, graph); + this.edgeExistenceAPI = new EdgeExistenceAPI(client, graph); } public double jaccardSimilarity(Object vertexId, Object otherId) { @@ -540,4 +543,17 @@ public Iterator iteratorEdges(Shard shard, int sizePerPage) { return this.edges(shard, page, sizePerPage); }); } + + public List edgeExistence(Object sourceId, Object targetId, String edgeLabel, + String sortValues, int limit) { + return this.edgeExistenceAPI.get(sourceId, targetId, edgeLabel, sortValues, limit); + } + + public List edgeExistence(Object sourceId, Object targetId) { + return this.edgeExistenceAPI.get(sourceId, targetId, "", "", -1); + } + + public List edgeExistence(Object sourceId, Object targetId, String edgeLabel) { + return this.edgeExistenceAPI.get(sourceId, targetId, edgeLabel, null, -1); + } } diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/ApiTestSuite.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/ApiTestSuite.java index 6fdb3c537..c9edba73f 100644 --- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/ApiTestSuite.java +++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/ApiTestSuite.java @@ -44,6 +44,7 @@ import org.apache.hugegraph.api.traverser.SingleSourceShortestPathApiTest; import org.apache.hugegraph.api.traverser.TemplatePathsApiTest; import org.apache.hugegraph.api.traverser.WeightedShortestPathApiTest; +import org.apache.hugegraph.api.traverser.EdgeExistenceAPITest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -84,6 +85,7 @@ FusiformSimilarityApiTest.class, NeighborRankApiTest.class, PersonalRankApiTest.class, + EdgeExistenceAPITest.class, TargetApiTest.class, GroupApiTest.class, diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/BaseApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/BaseApiTest.java index 37e88622e..c6570149b 100644 --- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/BaseApiTest.java +++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/BaseApiTest.java @@ -120,25 +120,25 @@ protected static void clearData() { indexLabelAPI.list().forEach(indexLabel -> { ilTaskIds.add(indexLabelAPI.delete(indexLabel.name())); }); - ilTaskIds.forEach(taskId -> waitUntilTaskCompleted(taskId)); + ilTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); List elTaskIds = new ArrayList<>(); edgeLabelAPI.list().forEach(edgeLabel -> { elTaskIds.add(edgeLabelAPI.delete(edgeLabel.name())); }); - elTaskIds.forEach(taskId -> waitUntilTaskCompleted(taskId)); + elTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); List vlTaskIds = new ArrayList<>(); vertexLabelAPI.list().forEach(vertexLabel -> { vlTaskIds.add(vertexLabelAPI.delete(vertexLabel.name())); }); - vlTaskIds.forEach(taskId -> waitUntilTaskCompleted(taskId)); + vlTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); List pkTaskIds = new ArrayList<>(); propertyKeyAPI.list().forEach(propertyKey -> { pkTaskIds.add(propertyKeyAPI.delete(propertyKey.name())); }); - pkTaskIds.forEach(taskId -> waitUntilTaskCompleted(taskId)); + pkTaskIds.forEach(BaseApiTest::waitUntilTaskCompleted); // Clear system taskAPI.list(null, -1).forEach(task -> { diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPITest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPITest.java new file mode 100644 index 000000000..ff46066c0 --- /dev/null +++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/EdgeExistenceAPITest.java @@ -0,0 +1,70 @@ +/* + * 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.hugegraph.api.traverser; + + +import org.apache.hugegraph.api.BaseApiTest; +import org.apache.hugegraph.structure.graph.Edge; +import org.apache.hugegraph.testutil.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +public class EdgeExistenceAPITest extends TraverserApiTest { + + @BeforeClass + public static void prepareSchemaAndGraph() { + BaseApiTest.initPropertyKey(); + BaseApiTest.initVertexLabel(); + BaseApiTest.initEdgeLabel(); + BaseApiTest.initIndexLabel(); + BaseApiTest.initVertex(); + BaseApiTest.initEdge(); + } + + @Test + public void testEdgeExistenceGet() { + Object markoId = getVertexId("person", "name", "marko"); + Object vadasId = getVertexId("person", "name", "vadas"); + + List edges = edgeExistenceAPI.get(markoId, vadasId, "", "", 100); + Assert.assertEquals(1, edges.size()); + + String sortValues = edges.get(0).name(); + edges = edgeExistenceAPI.get(markoId, vadasId, "knows", sortValues, 100); + String id = edges.get(0).id(); + + Assert.assertEquals(1, edges.size()); + Assert.assertTrue(id.contains("marko") && id.contains("vadas") && id.contains(sortValues)); + + Object lopId = getVertexId("software", "name", "lop"); + + edges = edgeExistenceAPI.get(lopId, vadasId, "knows", "", 100); + Assert.assertEquals(0, edges.size()); + + Object joshId = getVertexId("person", "name", "josh"); + Object rippleId = getVertexId("software", "name", "ripple"); + + edges = edgeExistenceAPI.get(joshId, rippleId, "created", "", 100); + Assert.assertEquals(1, edges.size()); + + edges = edgeExistenceAPI.get(joshId, rippleId, "created", "", 0); + Assert.assertEquals(0, edges.size()); + } +} diff --git a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java index 2a02dd10d..f6ab77156 100644 --- a/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java +++ b/hugegraph-client/src/test/java/org/apache/hugegraph/api/traverser/TraverserApiTest.java @@ -49,6 +49,7 @@ public class TraverserApiTest extends BaseApiTest { protected static VerticesAPI verticesAPI; protected static EdgesAPI edgesAPI; + protected static EdgeExistenceAPI edgeExistenceAPI; @BeforeClass public static void init() { @@ -82,5 +83,7 @@ public static void init() { verticesAPI = new VerticesAPI(client, GRAPH); edgesAPI = new EdgesAPI(client, GRAPH); + + edgeExistenceAPI = new EdgeExistenceAPI(client, GRAPH); } }