Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Added verification to `io()` ensuring a class named by `IO.reader`, `IO.writer` or `IO.registry` implements the expected interface before loading and initializing it.
* Fixed `io().write()` to resolve its `GraphWriter` before opening the output file, so that a writer which cannot be constructed no longer truncates the target.
* Fixed `TinkerGraph` GraphSON deserialization to fail fast with `JsonParseException` on malformed `tinker:graph` input.
* Changed GraphSON 1.0 typed deserialization to resolve a `@class` type id only when the name is in a set of exact class names.
* Restricted Hadoop/Spark OLAP `io()` from a remotely submitted traversal to operator-approved reader/writer classes and `with()` keys, adding the `gremlin.io.trusted`, `gremlin.io.approvedClasses` and `gremlin.io.approvedGraphConfigKeys` options.
* Restricted OLAP `GraphComputer.configure()` from a remotely submitted traversal to built-in and operator-approved keys, adding the `gremlin.io.approvedComputerConfigKeys` option.
* Fixed `subgraph()` to throw a descriptive error identifying the required `Edge` input instead of an internal `ClassCastException` when the traversal produces a non-edge value.
Expand Down
2 changes: 1 addition & 1 deletion docker/gremlin-server/gremlin-server-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ scriptEngines: {
serializers:
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3] }}
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2] }}
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1] }}
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1], allowedTypeIdNames: [java.awt.Point] }}
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1 }
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
processors:
Expand Down
10 changes: 9 additions & 1 deletion docs/src/dev/io/graphson.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,15 @@ Version 1.0 of GraphSON was released with TinkerPop 3.0.0. It is referred to by
When types are embedded, GraphSON uses the standard
link:https://github.com/FasterXML/jackson-databind[Jackson] type embedding approach that writes the full Java class
name into a "@class" field in the JSON. While this approach isn't especially language agnostic it does at least give
some hint as to what the expected type is.
some hint as to what the expected type is. On read, that class name resolves only when it is in a set of exact class
names, derived from the types that GraphSON 2.0 and 3.0 register plus the concrete runtime classes that GraphSON 1.0
writes and the registry does not declare. Names are matched by equality, and an array is decided by its component
name. A parameterized type id is always refused. The `java.lang.Class` type is refused by default but can be
explicitly allowed. A provider or application can add its own class names with
`GraphSONMapper.Builder.addAllowedTypeIdName(String...)`, for example `addAllowedTypeIdName("com.example.MyType")`.
For a very narrow set of types, typed GraphSON 1.0 writing and reading are asymmetric. The writer may emit a concrete
or parameterized Java type id that the reader refuses. Examples include `ByteBuffer` and `EnumMap`, which can be
written but cannot be read back.

This section focuses on non-embedded types and their formats as there was little usage of embedded types in generalized
object serialization use cases. The format was simply too cumbersome to parse of non-Jackson enabled libraries and the
Expand Down
24 changes: 22 additions & 2 deletions docs/src/reference/gremlin-applications.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,7 @@ The drivers are designed to use that type information to properly produce result
system and may not function correctly without it. Generally speaking, `GraphBinary` is always the best choice for the
drivers.

[[server-graphson]]
===== GraphSON

The GraphSON serializer produces human-readable output in JSON format and is a good configuration choice for those
Expand Down Expand Up @@ -1211,14 +1212,30 @@ Configuring GraphSON in the Gremlin Server configuration looks like this:
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3 }
----

Gremlin Server is configured by default with GraphSON 3.0 as shown above. It has the following configuration option:
Gremlin Server is configured by default with GraphSON 3.0 as shown above. It has the following configuration options:

[width="100%",cols="3,10,^2",options="header"]
|=========================================================
|Key |Description |Default
|ioRegistries |A list of `IoRegistry` implementations to be applied to the serializer. |_none_
|allowedTypeIdNames |A list of fully qualified class names that `GraphSONMessageSerializerV1` is allowed to resolve from `@class` type ids, in addition to its defaults. |_none_
|=========================================================

The `allowedTypeIdNames` option only affects typed GraphSON 1.0 reads. The equivalent mapper configuration uses
`GraphSONMapper.Builder.addAllowedTypeIdName(String...)`:

[source,java]
----
GraphSONMapper.build().version(GraphSONVersion.V1_0).typeInfo(TypeInfo.PARTIAL_TYPES)
.addAllowedTypeIdName("com.example.MyType", "com.example.MyOtherType").create();
----

Each configured name is matched exactly, so it does not allow subclasses or other classes in the same package. An
array is checked by its component class name, so allowing `com.example.MyType` also allows arrays of that class.
Parameterized type ids are rejected before class-name matching. Therefore, a type id such as
`java.util.EnumMap<...>` cannot be enabled by adding either `java.util.EnumMap` or the parameterized type id to the
configured names.

It is worth noting that GraphSON 1.0 still has some appeal for some users as it can be configured to produce an untyped
JSON format which is a bit easier to consume than its successors which embed data types into the output. This version
of GraphSON tends to be the one that users like to utilize when <<connecting-via-http,connecting via HTTP>> and is still
Expand All @@ -1228,7 +1245,10 @@ To configure Gremlin Server this way, the `GraphSONMessageSerializerV1` must be

[source,yaml]
----
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1 }
- className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1
config:
allowedTypeIdNames:
- com.example.MyType
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3 }
----

Expand Down
39 changes: 39 additions & 0 deletions docs/src/upgrade/release-3.7.x.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,45 @@ GryoIo.build().graph(graph).onMapper(m -> ((GryoMapper.Builder) m)

See: link:https://issues.apache.org/jira/browse/TINKERPOP-3278[TINKERPOP-3278]

==== GraphSON 1.0 Type Allow-List

Typed GraphSON 1.0 now resolves a Java class named by an `@class` property only when that exact name is allowed.
This change is breaking on read for provider and application types outside the default set. Some values that GraphSON
1.0 can write, including `ByteBuffer` and `EnumMap`, also no longer round-trip. The written format is unchanged.

The failure looks like this:

[source,text]
----
Could not resolve type id ...: Configured `PolymorphicTypeValidator` ... denied resolution
----

Further simple class names can be added on the mapper:

[source,java]
----
GraphSONMapper.build().version(GraphSONVersion.V1_0).typeInfo(TypeInfo.PARTIAL_TYPES)
.addAllowedTypeIdName("com.example.MyType", "com.example.MyOtherType").create();
----

Expected application types can be added to the message serializer configuration:

[source,yaml]
----
serializers:
- className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1
config:
allowedTypeIdNames:
- com.example.MyType
----

Allowlisting cannot restore a parameterized type id such as `java.util.EnumMap<...>` because GraphSON 1.0 rejects
all parameterized type ids unconditionally. Affected applications can convert values to non-parameterized
representations such as `HashMap`, or move to GraphSON 2.0, GraphSON 3.0 or GraphBinary.

See: link:https://tinkerpop.apache.org/docs/3.7.7/reference/#server-graphson[GraphSON Server Configuration],
link:https://tinkerpop.apache.org/docs/3.7.7/dev/io/#graphson-1d0[GraphSON 1.0 IO Documentation]

==== OLAP Restrictions

The OLAP `io()` step on `HadoopGraph` (`g.withComputer().io(path)...`) historically transferred every
Expand Down
Loading
Loading