Skip to content

Commit 0d495f8

Browse files
committed
fix(server): close upgrade review gaps
- remove unsafe typed GraphSON V1 from shipped configs - preserve mixed edge ID membership and count semantics - encode public enums and SchemaManager with standard wire values - share compatible Cypher factories across imports and replay - align Jackson modules and release dependency notices
1 parent 671240b commit 0d495f8

29 files changed

Lines changed: 534 additions & 109 deletions

File tree

‎docs/upgrade-tinkerpop-3.8.md‎

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,15 @@ serializer:
3232
3333
GraphBinary preserves graph elements and UUID IDs for Java Driver accessors such
3434
as `Result.getVertex()` and `Result.get(UUID.class)`. Untyped GraphSON V1 decodes
35-
these results as maps and strings, and typed GraphSON V1 still decodes graph
36-
elements as maps.
35+
these results as maps and strings.
3736

3837
`remote-objects.yaml` serves the Cypher HTTP JSON path and continues to use
3938
`org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` with
4039
`HugeGraphIoRegistry`. It retains its duplicate registry entry as a TinkerPop
4140
driver compatibility workaround.
4241

4342
For the server, keep the GraphBinary builder and registry. The serializer order
44-
is GraphBinary, untyped GraphSON V1/V2/V3, then typed GraphSON V1/V2/V3. The
43+
is GraphBinary, untyped GraphSON V1/V2/V3, then typed GraphSON V2/V3. The
4544
GraphSON entries keep the HugeGraph registry. The first entries look like this:
4645

4746
```yaml
@@ -63,7 +62,8 @@ The full ordering is in `gremlin-server.yaml`; the config test checks that
6362

6463
Typed GraphSON is available for the supported simple values and IDs, not as a
6564
replacement for untyped serialization of every HugeGraph schema or graph
66-
object. GraphSON V1 uses legacy `@class` metadata; V2/V3 use `@type`/`@value`.
65+
object. Typed V1 is not registered: its legacy `@class` deserialization can
66+
construct Java objects before request authentication. V2/V3 use `@type`/`@value`.
6767

6868
GraphBinary uses `HugeGraphTypeSerializerRegistryBuilder` to write HugeGraph IDs
6969
as their underlying values. Schema results use standard maps and Blob values use
@@ -78,6 +78,15 @@ registry limited to untyped V1 messages. Standard graph-file IO and typed
7878
GraphSON serializers keep `HugeGraphIoRegistry` alone and use the TinkerPop
7979
Tree format for their negotiated version.
8080

81+
HugeGraph enums such as `DataType.TEXT` and `Directions.OUT` return their names
82+
over GraphBinary, including in maps and lists. `graph.schema()` returns a map
83+
with `propertykeys`, `vertexlabels`, `edgelabels` and `indexlabels` lists, using
84+
the same schema conversion. TinkerPop enums retain their native wire types.
85+
86+
Local edge ID filters accept both serialized strings and native edge IDs in
87+
mixed collections: `hasId(not(without(ids)))` and `hasId(within(ids))` agree on
88+
membership and count. Numeric and string vertex IDs keep their distinct types.
89+
8190
Groovy interpolated strings (`GString`, including subclasses) return as standard
8291
strings over GraphBinary, including inside lists and maps. For example,
8392
`def value = 42; "r3-value:${value}"` returns `"r3-value:42"`. The untyped GraphSON
@@ -87,6 +96,9 @@ Cypher extension predicates use the current TinkerPop predicate constructor
8796
through the existing translator extension point. Computed-expression regex
8897
filters retain whole-string matching (`String.matches`), so `"marko"` matches
8998
`"mar.*"` and does not match `"ark"`.
99+
The public `cypherRegex`, `cypherIsString`, `cypherIsNode` and `cypherIsRelationship`
100+
factories imported by the bundled Gremlin configuration use that same adapter,
101+
so the Gremlin translation returned by `EXPLAIN` can be replayed.
90102

91103
Cypher results normalize HugeGraph IDs, including
92104
values nested in collections, maps and paths. Cyclic results and nesting deeper
@@ -98,6 +110,10 @@ TinkerPop 3.5.1 to 3.8.1 upgrade interval before deploying.
98110

99111
## YAML configuration safety
100112

113+
Jackson JSON and YAML modules share the root BOM version. Fabric8 kubeconfig
114+
extensions can contain integer and decimal values; the K8s configuration
115+
regression verifies auto-configuration without contacting a cluster.
116+
101117
This TinkerPop 3.8.1 upgrade uses SnakeYAML 2.2, Spring Boot 2.5.15 and
102118
Spring Framework 5.3.27. The Boot patch keeps PD and Store's YAML startup
103119
loader compatible with SnakeYAML 2.x. These versions belong to the upgraded

‎hugegraph-commons/hugegraph-common/pom.xml‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,22 +164,18 @@
164164
<dependency>
165165
<groupId>com.fasterxml.jackson.core</groupId>
166166
<artifactId>jackson-annotations</artifactId>
167-
<version>${jackson.version}</version>
168167
</dependency>
169168
<dependency>
170169
<groupId>com.fasterxml.jackson.core</groupId>
171170
<artifactId>jackson-core</artifactId>
172-
<version>${jackson.version}</version>
173171
</dependency>
174172
<dependency>
175173
<groupId>com.fasterxml.jackson.core</groupId>
176174
<artifactId>jackson-databind</artifactId>
177-
<version>${jackson.version}</version>
178175
</dependency>
179176
<dependency>
180177
<groupId>com.fasterxml.jackson.module</groupId>
181178
<artifactId>jackson-module-jaxb-annotations</artifactId>
182-
<version>${jackson.version}</version>
183179
<exclusions>
184180
<exclusion>
185181
<artifactId>jakarta.xml.bind-api</artifactId>
@@ -190,12 +186,10 @@
190186
<dependency>
191187
<groupId>com.fasterxml.jackson.jaxrs</groupId>
192188
<artifactId>jackson-jaxrs-base</artifactId>
193-
<version>${jackson.version}</version>
194189
</dependency>
195190
<dependency>
196191
<groupId>com.fasterxml.jackson.jaxrs</groupId>
197192
<artifactId>jackson-jaxrs-json-provider</artifactId>
198-
<version>${jackson.version}</version>
199193
</dependency>
200194

201195
<dependency>

‎hugegraph-commons/pom.xml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@
109109
<javassist.version>3.28.0-GA</javassist.version>
110110
<jersey.version>3.0.3</jersey.version>
111111
<jersey.hk2.version>3.0.3</jersey.hk2.version>
112-
<jackson.version>2.14.0-rc1</jackson.version>
113112
<junit.version>4.13.1</junit.version>
114113
<mockito.version>4.1.0</mockito.version>
115114
<jakarta.xml.version>4.0.0-RC2</jakarta.xml.version>

‎hugegraph-pd/hg-pd-cli/pom.xml‎

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
<artifactId>hg-pd-cli</artifactId>
3232

3333
<properties>
34-
<jackson.version>2.15.2</jackson.version>
3534
</properties>
3635

3736
<dependencies>
@@ -84,32 +83,26 @@
8483
<dependency>
8584
<groupId>com.fasterxml.jackson.core</groupId>
8685
<artifactId>jackson-annotations</artifactId>
87-
<version>${jackson.version}</version>
8886
</dependency>
8987
<dependency>
9088
<groupId>com.fasterxml.jackson.core</groupId>
9189
<artifactId>jackson-core</artifactId>
92-
<version>${jackson.version}</version>
9390
</dependency>
9491
<dependency>
9592
<groupId>com.fasterxml.jackson.core</groupId>
9693
<artifactId>jackson-databind</artifactId>
97-
<version>${jackson.version}</version>
9894
</dependency>
9995
<dependency>
10096
<groupId>com.fasterxml.jackson.module</groupId>
10197
<artifactId>jackson-module-jaxb-annotations</artifactId>
102-
<version>${jackson.version}</version>
10398
</dependency>
10499
<dependency>
105100
<groupId>com.fasterxml.jackson.jaxrs</groupId>
106101
<artifactId>jackson-jaxrs-base</artifactId>
107-
<version>${jackson.version}</version>
108102
</dependency>
109103
<dependency>
110104
<groupId>com.fasterxml.jackson.jaxrs</groupId>
111105
<artifactId>jackson-jaxrs-json-provider</artifactId>
112-
<version>${jackson.version}</version>
113106
</dependency>
114107
<dependency>
115108
<groupId>org.apache.hugegraph</groupId>

‎hugegraph-pd/hg-pd-test/pom.xml‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,14 @@
138138
<dependency>
139139
<groupId>com.fasterxml.jackson.core</groupId>
140140
<artifactId>jackson-databind</artifactId>
141-
<version>2.13.0</version>
142141
</dependency>
143142
<dependency>
144143
<groupId>com.fasterxml.jackson.core</groupId>
145144
<artifactId>jackson-core</artifactId>
146-
<version>2.13.0</version>
147145
</dependency>
148146
<dependency>
149147
<groupId>com.fasterxml.jackson.core</groupId>
150148
<artifactId>jackson-annotations</artifactId>
151-
<version>2.13.0</version>
152149
</dependency>
153150

154151
<dependency>

‎hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherGremlinPredicates.java‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,37 @@ public final class CypherGremlinPredicates extends TraversalGremlinPredicates {
3030

3131
@Override
3232
public P<Object> regexMatch(Object value) {
33-
return predicate(CustomPredicate.cypherRegex, value);
33+
return cypherRegex(value);
3434
}
3535

3636
@Override
3737
public P<Object> isNode() {
38-
return predicate(CustomPredicate.cypherIsNode, null);
38+
return cypherIsNode();
3939
}
4040

4141
@Override
4242
public P<Object> isRelationship() {
43-
return predicate(CustomPredicate.cypherIsRelationship, null);
43+
return cypherIsRelationship();
4444
}
4545

4646
@Override
4747
public P<Object> isString() {
48+
return cypherIsString();
49+
}
50+
51+
public static P<Object> cypherRegex(Object value) {
52+
return predicate(CustomPredicate.cypherRegex, value);
53+
}
54+
55+
public static P<Object> cypherIsNode() {
56+
return predicate(CustomPredicate.cypherIsNode, null);
57+
}
58+
59+
public static P<Object> cypherIsRelationship() {
60+
return predicate(CustomPredicate.cypherIsRelationship, null);
61+
}
62+
63+
public static P<Object> cypherIsString() {
4864
return predicate(CustomPredicate.cypherIsString, null);
4965
}
5066

‎hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/opencypher/CypherPlugin.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,14 @@
4040
import org.apache.tinkerpop.gremlin.jsr223.GremlinPlugin;
4141
import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer;
4242
import org.opencypher.gremlin.traversal.CustomFunctions;
43-
import org.opencypher.gremlin.traversal.CustomPredicate;
4443

4544
public class CypherPlugin implements GremlinPlugin {
4645

4746
private static final ImportCustomizer IMPORTS =
4847
DefaultImportCustomizer.build()
49-
.addClassImports(CustomPredicate.class)
48+
.addClassImports(CypherGremlinPredicates.class)
5049
.addMethodImports(
51-
getDeclaredPublicMethods(CustomPredicate.class))
50+
getDeclaredPublicMethods(CypherGremlinPredicates.class))
5251
.addClassImports(CustomFunctions.class)
5352
.addMethodImports(
5453
getDeclaredPublicMethods(CustomFunctions.class))
@@ -57,7 +56,8 @@ public class CypherPlugin implements GremlinPlugin {
5756
private static List<Method> getDeclaredPublicMethods(Class<?> klass) {
5857
Method[] declaredMethods = klass.getDeclaredMethods();
5958
return Stream.of(declaredMethods)
60-
.filter(method -> Modifier.isPublic(method.getModifiers()))
59+
.filter(method -> Modifier.isPublic(method.getModifiers()) &&
60+
Modifier.isStatic(method.getModifiers()))
6161
.collect(Collectors.toList());
6262
}
6363

‎hugegraph-server/hugegraph-core/pom.xml‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,14 @@
4949
<dependency>
5050
<groupId>com.fasterxml.jackson.core</groupId>
5151
<artifactId>jackson-databind</artifactId>
52-
<version>2.13.2</version>
5352
</dependency>
5453
<dependency>
5554
<groupId>com.fasterxml.jackson.core</groupId>
5655
<artifactId>jackson-core</artifactId>
57-
<version>2.13.2</version>
5856
</dependency>
5957
<dependency>
6058
<groupId>com.fasterxml.jackson.core</groupId>
6159
<artifactId>jackson-annotations</artifactId>
62-
<version>2.15.2</version>
6360
</dependency>
6461
<dependency>
6562
<groupId>io.fabric8</groupId>

‎hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/io/HugeGraphTypeSerializerRegistryBuilder.java‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.hugegraph.schema.IndexLabel;
3434
import org.apache.hugegraph.schema.PropertyKey;
3535
import org.apache.hugegraph.schema.SchemaElement;
36+
import org.apache.hugegraph.schema.SchemaManager;
3637
import org.apache.hugegraph.schema.VertexLabel;
3738
import org.apache.hugegraph.type.define.HugeKeys;
3839
import org.apache.hugegraph.util.Blob;
@@ -55,6 +56,10 @@ public final class HugeGraphTypeSerializerRegistryBuilder
5556
new WireTransformSerializer<>(blob -> ByteBuffer.wrap(blob.bytes()));
5657
private static final TypeSerializer<SchemaElement> SCHEMA_TRANSFORM_SERIALIZER =
5758
new WireTransformSerializer<>(HugeGraphTypeSerializerRegistryBuilder::schemaMap);
59+
private static final TypeSerializer<SchemaManager> SCHEMA_MANAGER_TRANSFORM_SERIALIZER =
60+
new WireTransformSerializer<>(HugeGraphTypeSerializerRegistryBuilder::schemaManagerMap);
61+
private static final TypeSerializer<Enum<?>> ENUM_TRANSFORM_SERIALIZER =
62+
new WireTransformSerializer<>(Enum::name);
5863

5964
private static final TypeSerializer<Optional<?>> OPTIONAL_TRANSFORM_SERIALIZER =
6065
new WireTransformSerializer<>(optional -> optional.orElse(null));
@@ -75,6 +80,12 @@ public HugeGraphTypeSerializerRegistryBuilder() {
7580
if (SchemaElement.class.isAssignableFrom(type)) {
7681
return SCHEMA_TRANSFORM_SERIALIZER;
7782
}
83+
if (SchemaManager.class.isAssignableFrom(type)) {
84+
return SCHEMA_MANAGER_TRANSFORM_SERIALIZER;
85+
}
86+
if (isHugeGraphEnum(type)) {
87+
return ENUM_TRANSFORM_SERIALIZER;
88+
}
7889
if (Optional.class.isAssignableFrom(type)) {
7990
return OPTIONAL_TRANSFORM_SERIALIZER;
8091
}
@@ -88,6 +99,21 @@ public HugeGraphTypeSerializerRegistryBuilder() {
8899
});
89100
}
90101

102+
private static boolean isHugeGraphEnum(Class<?> type) {
103+
// Scope the fallback to HugeGraph; native TinkerPop enums keep their serializers.
104+
return Enum.class.isAssignableFrom(type) &&
105+
type.getName().startsWith("org.apache.hugegraph.");
106+
}
107+
108+
private static Map<String, Object> schemaManagerMap(SchemaManager schema) {
109+
Map<String, Object> result = new LinkedHashMap<>();
110+
result.put("propertykeys", schemaValue(schema.getPropertyKeys()));
111+
result.put("vertexlabels", schemaValue(schema.getVertexLabels()));
112+
result.put("edgelabels", schemaValue(schema.getEdgeLabels()));
113+
result.put("indexlabels", schemaValue(schema.getIndexLabels()));
114+
return result;
115+
}
116+
91117
private static Map<String, Object> schemaMap(SchemaElement schema) {
92118
// Use the same field names and values as the existing GraphSON schema API.
93119
GraphSONSchemaSerializer serializer = new GraphSONSchemaSerializer();
@@ -109,9 +135,15 @@ private static Map<String, Object> schemaMap(SchemaElement schema) {
109135
}
110136

111137
private static Object schemaValue(Object value) {
112-
if (value instanceof Enum) {
138+
if (value instanceof Enum && isHugeGraphEnum(value.getClass())) {
113139
return ((Enum<?>) value).name();
114140
}
141+
if (value instanceof SchemaElement) {
142+
return schemaMap((SchemaElement) value);
143+
}
144+
if (value instanceof SchemaManager) {
145+
return schemaManagerMap((SchemaManager) value);
146+
}
115147
if (value instanceof Map) {
116148
Map<Object, Object> result = new LinkedHashMap<>();
117149
((Map<?, ?>) value).forEach((key, item) -> result.put(schemaValue(key), schemaValue(item)));

‎hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/TraversalUtil.java‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.hugegraph.HugeException;
3333
import org.apache.hugegraph.HugeGraph;
3434
import org.apache.hugegraph.backend.BackendException;
35+
import org.apache.hugegraph.backend.id.EdgeId;
3536
import org.apache.hugegraph.backend.id.Id;
3637
import org.apache.hugegraph.backend.id.IdGenerator;
3738
import org.apache.hugegraph.backend.page.PageInfo;
@@ -46,6 +47,7 @@
4647
import org.apache.hugegraph.schema.IndexLabel;
4748
import org.apache.hugegraph.schema.PropertyKey;
4849
import org.apache.hugegraph.schema.SchemaLabel;
50+
import org.apache.hugegraph.structure.HugeEdge;
4951
import org.apache.hugegraph.structure.HugeElement;
5052
import org.apache.hugegraph.structure.HugeProperty;
5153
import org.apache.hugegraph.type.HugeType;
@@ -1325,7 +1327,12 @@ private static boolean testIdPredicate(P<?> predicate, Element element) {
13251327
for (Object value : values) {
13261328
Object actual = id instanceof IdGenerator.StringId && value instanceof String ?
13271329
((Id) id).asString() : id;
1328-
if (Compare.eq.test(actual, value)) {
1330+
// Edge lookup accepts its serialized ID as well as EdgeId.
1331+
// Preserve that contract in local mixed-ID filters without
1332+
// collapsing numeric and string vertex IDs.
1333+
Object expected = id instanceof EdgeId &&
1334+
value instanceof String ? HugeEdge.getIdValue(value, true) : value;
1335+
if (Compare.eq.test(actual, expected)) {
13291336
return predicate.getBiPredicate() == Contains.within;
13301337
}
13311338
}

0 commit comments

Comments
 (0)