This is an automated email from the ASF dual-hosted git repository.
imbajin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph-computer.git
The following commit(s) were added to refs/heads/master by this push:
new b636712d refactor(computer): support new edgeid format in 1.7 (#349)
b636712d is described below
commit b636712dd9452f60d1a9f2db7da1cdc44be800fe
Author: hutiefang76 <[email protected]>
AuthorDate: Tue Jun 30 16:18:43 2026 +0800
refactor(computer): support new edgeid format in 1.7 (#349)
* fix: complete huge client compatibility registration
---------
Co-authored-by: hutiefang <[email protected]>
---
.github/workflows/computer-ci.yml | 4 +-
.../computer/core/output/hg/task/TaskManager.java | 5 +-
.../computer/core/util/HugeClientUtil.java | 79 ++++++++++++++++++++
.../computer/core/input/HugeConverter.java | 20 ++++++
.../computer/core/input/hg/HugeGraphFetcher.java | 5 +-
.../core/input/hg/HugeInputSplitFetcher.java | 7 +-
.../computer/core/worker/load/LoadService.java | 3 +-
.../computer/core/input/HugeConverterTest.java | 72 +++++++++++++++++++
.../computer/core/input/InputTestSuite.java | 4 +-
.../core/input/hg/HugeClientCompatibilityTest.java | 84 ++++++++++++++++++++++
.../computer/suite/unit/UnitTestBase.java | 4 +-
11 files changed, 273 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/computer-ci.yml
b/.github/workflows/computer-ci.yml
index 26652470..336d2e47 100644
--- a/.github/workflows/computer-ci.yml
+++ b/.github/workflows/computer-ci.yml
@@ -22,9 +22,7 @@ jobs:
TRAVIS_DIR: computer-dist/src/assembly/travis
BSP_ETCD_URL: http://localhost:2579
KUBERNETES_VERSION: 1.20.1
- # TODO: adapt the HugeGraph Server/Loader version to 1.5.0 (EdgeID has 5
parts now)
- # NOTE: Remember to adaptor/update the version before new release
- GRAPH_ENV_VERSION: 1.3.0
+ GRAPH_ENV_VERSION: 1.7.0
steps:
- name: Checkout
diff --git
a/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/output/hg/task/TaskManager.java
b/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/output/hg/task/TaskManager.java
index cdeb95ed..d71911bc 100644
---
a/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/output/hg/task/TaskManager.java
+++
b/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/output/hg/task/TaskManager.java
@@ -28,8 +28,8 @@ import org.apache.hugegraph.computer.core.config.Config;
import
org.apache.hugegraph.computer.core.output.hg.exceptions.WriteBackException;
import org.apache.hugegraph.computer.core.output.hg.metrics.LoadSummary;
import org.apache.hugegraph.computer.core.output.hg.metrics.Printer;
+import org.apache.hugegraph.computer.core.util.HugeClientUtil;
import org.apache.hugegraph.driver.HugeClient;
-import org.apache.hugegraph.driver.HugeClientBuilder;
import org.apache.hugegraph.structure.graph.Vertex;
import org.apache.hugegraph.util.ExecutorUtil;
import org.apache.hugegraph.util.Log;
@@ -58,7 +58,8 @@ public final class TaskManager {
String graph = config.get(ComputerOptions.HUGEGRAPH_GRAPH_NAME);
String username = config.get(ComputerOptions.HUGEGRAPH_USERNAME);
String password = config.get(ComputerOptions.HUGEGRAPH_PASSWORD);
- this.client = new HugeClientBuilder(url, graph).configUser(username,
password).build();
+ this.client = HugeClientUtil.newHugeClient(url, graph, username,
+ password);
// Try to make all batch threads running and don't wait for producer
this.batchSemaphore = new Semaphore(this.batchSemaphoreNum());
/*
diff --git
a/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/util/HugeClientUtil.java
b/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/util/HugeClientUtil.java
new file mode 100644
index 00000000..f3f890d1
--- /dev/null
+++
b/computer/computer-api/src/main/java/org/apache/hugegraph/computer/core/util/HugeClientUtil.java
@@ -0,0 +1,79 @@
+/*
+ * 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.computer.core.util;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.hugegraph.driver.HugeClient;
+import org.apache.hugegraph.driver.HugeClientBuilder;
+import org.apache.hugegraph.rest.RestResult;
+import org.apache.hugegraph.structure.schema.EdgeLabel;
+import org.apache.hugegraph.util.JsonUtil;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public final class HugeClientUtil {
+
+ private static final AtomicBoolean COMPATIBILITY_REGISTERED =
+ new AtomicBoolean(false);
+
+ public static HugeClient newHugeClient(String url, String graph,
+ String username, String password) {
+ registerCompatibilityModule();
+ return new HugeClientBuilder(url, graph).configUser(username, password)
+ .build();
+ }
+
+ public static HugeClient newHugeClient(String url, String graph,
+ String username, String password,
+ int timeout) {
+ registerCompatibilityModule();
+ return new HugeClientBuilder(url, graph).configUser(username, password)
+ .configTimeout(timeout)
+ .build();
+ }
+
+ public static void registerCompatibilityModule() {
+ if (COMPATIBILITY_REGISTERED.get()) {
+ return;
+ }
+ synchronized (HugeClientUtil.class) {
+ if (COMPATIBILITY_REGISTERED.get()) {
+ return;
+ }
+ RestResult.registerModule(newCompatibilityModule());
+ JsonUtil.registerModule(newCompatibilityModule());
+ COMPATIBILITY_REGISTERED.set(true);
+ }
+ }
+
+ private static SimpleModule newCompatibilityModule() {
+ SimpleModule module = new SimpleModule(
+ "hugegraph-computer-client-compatibility");
+ module.setMixInAnnotation(EdgeLabel.class, IgnoreUnknownFields.class);
+ return module;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ private abstract static class IgnoreUnknownFields {
+ }
+
+ private HugeClientUtil() {
+ }
+}
diff --git
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverter.java
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverter.java
index dd94dabc..1d17a337 100644
---
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverter.java
+++
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverter.java
@@ -36,10 +36,15 @@ import
org.apache.hugegraph.computer.core.graph.value.LongValue;
import org.apache.hugegraph.computer.core.graph.value.NullValue;
import org.apache.hugegraph.computer.core.graph.value.StringValue;
import org.apache.hugegraph.computer.core.graph.value.Value;
+import org.apache.hugegraph.structure.graph.Edge;
import org.apache.hugegraph.util.E;
+import org.apache.hugegraph.util.SplicingIdGenerator;
public final class HugeConverter {
+ private static final int LEGACY_EDGE_ID_PARTS = 4;
+ private static final int DIRECTIONAL_EDGE_ID_PARTS = 6;
+
private static final GraphFactory GRAPH_FACTORY =
ComputerContext.instance().graphFactory();
@@ -96,4 +101,19 @@ public final class HugeConverter {
}
return properties;
}
+
+ public static String convertEdgeName(Edge edge) {
+ E.checkArgumentNotNull(edge, "The edge can't be null");
+ String edgeId = edge.id();
+ if (edgeId == null) {
+ return edge.name();
+ }
+
+ String[] parts = SplicingIdGenerator.split(edgeId);
+ if (parts.length >= LEGACY_EDGE_ID_PARTS &&
+ parts.length <= DIRECTIONAL_EDGE_ID_PARTS) {
+ return parts[parts.length - 2];
+ }
+ return edge.name();
+ }
}
diff --git
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeGraphFetcher.java
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeGraphFetcher.java
index 813fd007..bc546d6e 100644
---
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeGraphFetcher.java
+++
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeGraphFetcher.java
@@ -24,8 +24,8 @@ import org.apache.hugegraph.computer.core.input.GraphFetcher;
import org.apache.hugegraph.computer.core.input.InputSplit;
import org.apache.hugegraph.computer.core.input.VertexFetcher;
import org.apache.hugegraph.computer.core.rpc.InputSplitRpcService;
+import org.apache.hugegraph.computer.core.util.HugeClientUtil;
import org.apache.hugegraph.driver.HugeClient;
-import org.apache.hugegraph.driver.HugeClientBuilder;
public class HugeGraphFetcher implements GraphFetcher {
@@ -39,7 +39,8 @@ public class HugeGraphFetcher implements GraphFetcher {
String graph = config.get(ComputerOptions.HUGEGRAPH_GRAPH_NAME);
String username = config.get(ComputerOptions.HUGEGRAPH_USERNAME);
String password = config.get(ComputerOptions.HUGEGRAPH_PASSWORD);
- this.client = new HugeClientBuilder(url, graph).configUser(username,
password).build();
+ this.client = HugeClientUtil.newHugeClient(url, graph, username,
+ password);
this.vertexFetcher = new HugeVertexFetcher(config, this.client);
this.edgeFetcher = new HugeEdgeFetcher(config, this.client);
this.rpcService = rpcService;
diff --git
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeInputSplitFetcher.java
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeInputSplitFetcher.java
index cd1654c9..0f877754 100644
---
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeInputSplitFetcher.java
+++
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeInputSplitFetcher.java
@@ -24,8 +24,8 @@ import
org.apache.hugegraph.computer.core.config.ComputerOptions;
import org.apache.hugegraph.computer.core.config.Config;
import org.apache.hugegraph.computer.core.input.InputSplit;
import org.apache.hugegraph.computer.core.input.InputSplitFetcher;
+import org.apache.hugegraph.computer.core.util.HugeClientUtil;
import org.apache.hugegraph.driver.HugeClient;
-import org.apache.hugegraph.driver.HugeClientBuilder;
import org.apache.hugegraph.structure.graph.Shard;
import org.apache.hugegraph.util.E;
@@ -41,9 +41,8 @@ public class HugeInputSplitFetcher implements
InputSplitFetcher {
String username = config.get(ComputerOptions.HUGEGRAPH_USERNAME);
String password = config.get(ComputerOptions.HUGEGRAPH_PASSWORD);
int timeout = config.get(ComputerOptions.INPUT_SPLIT_FETCH_TIMEOUT);
- this.client = new HugeClientBuilder(url, graph).configUser(username,
password)
- .configTimeout(timeout)
- .build();
+ this.client = HugeClientUtil.newHugeClient(url, graph, username,
+ password, timeout);
}
@Override
diff --git
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/worker/load/LoadService.java
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/worker/load/LoadService.java
index 237b02d5..2b4af436 100644
---
a/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/worker/load/LoadService.java
+++
b/computer/computer-core/src/main/java/org/apache/hugegraph/computer/core/worker/load/LoadService.java
@@ -238,7 +238,8 @@ public class LoadService {
Properties properties = HugeConverter.convertProperties(
edge.properties());
Edge computerEdge = graphFactory.createEdge(edge.label(),
- edge.name(), targetId
+
HugeConverter.convertEdgeName(edge),
+ targetId
);
computerEdge.label(edge.label());
computerEdge.properties(properties);
diff --git
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverterTest.java
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverterTest.java
index cc58f2a3..0049ec59 100644
---
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverterTest.java
+++
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/HugeConverterTest.java
@@ -35,8 +35,10 @@ import
org.apache.hugegraph.computer.core.graph.value.NullValue;
import org.apache.hugegraph.computer.core.graph.value.StringValue;
import org.apache.hugegraph.computer.core.graph.value.ValueType;
import org.apache.hugegraph.computer.suite.unit.UnitTestBase;
+import org.apache.hugegraph.structure.graph.Edge;
import org.apache.hugegraph.testutil.Assert;
import org.junit.Test;
+import org.mockito.Mockito;
import com.google.common.collect.ImmutableList;
@@ -126,4 +128,74 @@ public class HugeConverterTest extends UnitTestBase {
Assert.assertEquals(properties,
HugeConverter.convertProperties(rawProperties));
}
+
+ @Test
+ public void testConvertEdgeNameWithLegacyFourPartEdgeId() {
+ Edge edge = Mockito.mock(Edge.class);
+ Mockito.when(edge.id()).thenReturn(
+ "S1:178201>5>参数标准!3BA0>S4:239464");
+ Mockito.when(edge.name()).thenReturn("stale_client_name");
+
+ Assert.assertEquals("参数标准!3BA0",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithFivePartEdgeId() {
+ Edge edge = new Edge("belong_to_el_defect");
+ edge.id("S1:178201>5>5>参数标准!3BA0>S4:239464");
+
+ Assert.assertEquals("参数标准!3BA0",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithSixPartEdgeId() {
+ Edge edge = new Edge("belong_to_el_defect");
+ edge.id("S1:178201>O>5>5>参数标准!3BA0>S4:239464");
+
+ Assert.assertEquals("参数标准!3BA0",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithSixPartInEdgeId() {
+ Edge edge = new Edge("belong_to_el_defect");
+ edge.id("S4:239464>I>5>5>参数标准!3BA0>S1:178201");
+
+ Assert.assertEquals("参数标准!3BA0",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithNullEdgeId() {
+ Edge edge = Mockito.mock(Edge.class);
+ Mockito.when(edge.id()).thenReturn(null);
+ Mockito.when(edge.name()).thenReturn("fallback_name");
+
+ Assert.assertEquals("fallback_name",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithUnknownEdgeIdFormat() {
+ Edge edge = Mockito.mock(Edge.class);
+ Mockito.when(edge.id()).thenReturn(
+ "S1:178201>bad>edge");
+ Mockito.when(edge.name()).thenReturn("fallback_name");
+
+ Assert.assertEquals("fallback_name",
+ HugeConverter.convertEdgeName(edge));
+
+ Mockito.when(edge.id()).thenReturn(
+ "S1:178201>O>5>5>参数标准!3BA0>S4:239464>extra");
+ Assert.assertEquals("fallback_name",
+ HugeConverter.convertEdgeName(edge));
+ }
+
+ @Test
+ public void testConvertEdgeNameWithNullEdge() {
+ Assert.assertThrows(IllegalArgumentException.class,
+ () -> HugeConverter.convertEdgeName(null));
+ }
}
diff --git
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/InputTestSuite.java
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/InputTestSuite.java
index d83e9023..79cc1f1b 100644
---
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/InputTestSuite.java
+++
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/InputTestSuite.java
@@ -17,6 +17,7 @@
package org.apache.hugegraph.computer.core.input;
+import org.apache.hugegraph.computer.core.input.hg.HugeClientCompatibilityTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -25,7 +26,8 @@ import org.junit.runners.Suite;
InputSplitTest.class,
FileInputSplitTest.class,
InputSplitDataTest.class,
- HugeConverterTest.class
+ HugeConverterTest.class,
+ HugeClientCompatibilityTest.class
})
public class InputTestSuite {
}
diff --git
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeClientCompatibilityTest.java
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeClientCompatibilityTest.java
new file mode 100644
index 00000000..77358618
--- /dev/null
+++
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/core/input/hg/HugeClientCompatibilityTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.computer.core.input.hg;
+
+import java.lang.reflect.Method;
+
+import org.apache.hugegraph.computer.core.util.HugeClientUtil;
+import org.apache.hugegraph.rest.RestResult;
+import org.apache.hugegraph.structure.schema.EdgeLabel;
+import org.apache.hugegraph.testutil.Assert;
+import org.junit.Test;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class HugeClientCompatibilityTest {
+
+ @Test
+ public void testReadEdgeLabelWithCurrentServerFields() {
+ HugeClientUtil.registerCompatibilityModule();
+
+ String content = "{" +
+ "\"id\":1," +
+ "\"name\":\"link\"," +
+ "\"edgelabel_type\":\"NORMAL\"," +
+ "\"source_label\":\"user\"," +
+ "\"target_label\":\"user\"," +
+ "\"links\":[{\"user\":\"user\"}]," +
+ "\"frequency\":\"SINGLE\"," +
+ "\"sort_keys\":[]," +
+ "\"nullable_keys\":[]," +
+ "\"index_labels\":[]," +
+ "\"properties\":[]," +
+ "\"status\":\"CREATED\"," +
+ "\"ttl\":0," +
+ "\"enable_label_index\":true," +
+ "\"user_data\":{\"~create_time\":\"2026-06-22
15:26:42.781\"}" +
+ "}";
+
+ EdgeLabel edgeLabel = new RestResult(200, content, null).readObject(
+ EdgeLabel.class);
+
+ Assert.assertEquals("link", edgeLabel.name());
+ Assert.assertEquals("user", edgeLabel.sourceLabel());
+ Assert.assertEquals("user", edgeLabel.targetLabel());
+ }
+
+ @Test
+ public void testEdgeLabelCompatibilityUsesIgnoreUnknownMixin()
+ throws Exception {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.registerModule(newCompatibilityModule());
+
+ Class<?> mixIn = mapper.getDeserializationConfig()
+ .findMixInClassFor(EdgeLabel.class);
+ JsonIgnoreProperties annotation = mixIn.getAnnotation(
+ JsonIgnoreProperties.class);
+
+ Assert.assertTrue(annotation.ignoreUnknown());
+ }
+
+ private static SimpleModule newCompatibilityModule() throws Exception {
+ Method method = HugeClientUtil.class.getDeclaredMethod(
+ "newCompatibilityModule");
+ method.setAccessible(true);
+ return (SimpleModule) method.invoke(null);
+ }
+}
diff --git
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/unit/UnitTestBase.java
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/unit/UnitTestBase.java
index 1ce8e31a..ee9545aa 100644
---
a/computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/unit/UnitTestBase.java
+++
b/computer/computer-test/src/main/java/org/apache/hugegraph/computer/suite/unit/UnitTestBase.java
@@ -46,6 +46,7 @@ import
org.apache.hugegraph.computer.core.io.StreamGraphOutput;
import org.apache.hugegraph.computer.core.io.Writable;
import org.apache.hugegraph.computer.core.store.entry.EntryInput;
import org.apache.hugegraph.computer.core.store.entry.EntryInputImpl;
+import org.apache.hugegraph.computer.core.util.HugeClientUtil;
import org.apache.hugegraph.computer.core.util.ComputerContextUtil;
import org.apache.hugegraph.computer.core.worker.MockComputationParams;
import org.apache.hugegraph.config.OptionSpace;
@@ -287,7 +288,8 @@ public class UnitTestBase {
protected static synchronized HugeClient client() {
if (CLIENT == null) {
- CLIENT = HugeClient.builder(URL, GRAPH).configUser(USERNAME,
PASSWORD).build();
+ CLIENT = HugeClientUtil.newHugeClient(URL, GRAPH, USERNAME,
+ PASSWORD);
}
return CLIENT;
}