Skip to content

feat: add v3 client compatibility layer (client-v3compat) - #655

Open
xiajingchun wants to merge 1 commit into
vesoft-inc:devfrom
xiajingchun:feature/v3client-compat
Open

feat: add v3 client compatibility layer (client-v3compat)#655
xiajingchun wants to merge 1 commit into
vesoft-inc:devfrom
xiajingchun:feature/v3client-compat

Conversation

@xiajingchun

@xiajingchun xiajingchun commented Aug 21, 2026

Copy link
Copy Markdown

What

Adds a v3 client compatibility layer so applications built on the NebulaGraph v3 Java client (com.vesoft.nebula.client.*) can migrate to NebulaGraph v5 with minimal changes.

A new module client-v3compat re-implements the v3 client's graph package under the com.vesoft.nebula.driver.v3client namespace and delegates internally to the v5 driver.

Why

The v5 SDK switched from Thrift/ngql to gRPC/ISO-GQL and dropped the v3 client package. This layer keeps the v3 API surface (class names + method signatures) so users only need to:

  1. swap the Maven dependency (client:3.xclient-v3compat:5.3-SNAPSHOT),
  2. rewrite imports (com.vesoft.nebula.client.com.vesoft.nebula.driver.v3client.),
  3. migrate their GQL from nGQL to ISO-GQL (not handled by this layer).

See migration_guide_v3.md for the full user-facing migration guide.

What's included

  • Module client-v3compat (depends on driver), registered in the root pom.xml.
  • Session/pool: NebulaPool, Session, SessionPool, NebulaSession, SessionsManager, plus config beans and the connection-level shims (Connection, SyncConnection, LoadBalancer, …).
  • Data model: ResultSet(+Record), ValueWrapper(+NullType), Node, Relationship, PathWrapper, date/time/duration/geography wrappers, HostAddress, SSL params, TimeUtil.
  • Exceptions + error codes: 8 v3 exceptions and a v3-style integer ErrorCode (full 200-entry enum) with a v5→v3 code mapping.

Key adaptation decisions

  • Session / NebulaSession wrap a v5 NebulaClient (one client = one server session).
  • NebulaPool lazily builds one v5 NebulaPool per username (v3 authenticates per getSession, v5 bakes credentials into the pool).
  • executeWithParameter inlines $param placeholders as GQL literals (value2GqlLiteral), since the v5 execute RPC takes no parameter map. Longest-key-first replacement avoids prefix collisions.
  • ResultSet eagerly materializes the v5 one-shot iterator into the v3 index-based accessors.
  • SessionPool binds the graph via SESSION SET GRAPH "…".

Declared differences (non-restorable in v5)

  • Node.getId() / Relationship.srcId()/dstId() return the v5 numeric id; string ids are no longer recoverable.
  • Thrift-coupled methods are adapted/removed: ResultSet.getRows() (removed), getPlanDesc() (returns v5 PlanInfoNode), getSpaceName()/getComment() (return ""), ValueWrapper.getValue() (returns the v5 wrapper).
  • v5 DECIMAL values are surfaced via ValueWrapper.isDouble()/asDouble().

Testing

  • Unit tests: ValueWrapperTest (value wrapping), SessionParameterTest (literal serialization + inline replacement) — 10 tests.
  • Integration test: V3IntegrationTest (disabled by default, -Dnebula.it=true), runs create-graph-type → create-graph → insert → MATCH node/edge/path → SessionPool → cleanup against a live v5 cluster; 5 tests passed.
  • Migration examples: V3CompatExample, V3SessionPoolExample.

Run locally:

mvn -pl client-v3compat test
# integration test against a live cluster:
mvn -pl client-v3compat test -Dnebula.it=true \
  -Dnebula.host=<host> -Dnebula.port=<port> \
  -Dnebula.user=root -Dnebula.password=<pwd> -Dtest=V3IntegrationTest

@xiajingchun
xiajingchun requested review from Nicole00 and a lite review from Copilot August 21, 2026 09:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds a new client-v3compat module that re-implements the NebulaGraph v3 Java client graph API under com.vesoft.nebula.driver.v3client.*, delegating execution to the v5 driver to ease migrations.

Changes:

  • Registers the new client-v3compat Maven module and wires it into examples.
  • Implements v3-compatible pool/session APIs, data wrappers, and v3-style error code mapping on top of the v5 driver.
  • Adds unit/integration tests plus migration examples and README migration guidance.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pom.xml Registers the new client-v3compat module in the multi-module build.
examples/pom.xml Adds a dependency on client-v3compat for runnable migration examples.
examples/src/main/java/com/vesoft/nebula/V3CompatExample.java New example showing v3-shaped NebulaPool + Session usage against v5.
examples/src/main/java/com/vesoft/nebula/V3SessionPoolExample.java New example showing v3-shaped SessionPool usage against v5.
client-v3compat/pom.xml Defines the new compatibility module and its dependencies.
README.md Documents migration steps and the compatibility layer scope/differences.
client-v3compat/src/test/java/com/vesoft/nebula/driver/v3client/graph/net/SessionParameterTest.java Unit tests for literal serialization and parameter inlining.
client-v3compat/src/test/java/com/vesoft/nebula/driver/v3client/graph/data/ValueWrapperTest.java Unit tests for v5→v3 value wrapping behavior.
client-v3compat/src/test/java/com/vesoft/nebula/driver/v3client/graph/V3IntegrationTest.java Disabled-by-default end-to-end test against a live v5 cluster.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Connection.java Adds v3 Connection type as a source-compat shim.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/SyncConnection.java Adds v3 SyncConnection shim; direct authenticate unsupported.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/LoadBalancer.java Adds v3 LoadBalancer interface for source compatibility.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/RoundRobinLoadBalancer.java Implements a minimal round-robin address selector shim.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/ConnObjectPool.java Adds v3 pool factory shim (unsupported create) for compatibility.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/AuthResult.java Adds v3 auth result DTO for compatibility.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Session.java Core v3-compatible session delegating to v5 NebulaClient (execute, JSON, param inlining, reconnect).
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/SessionState.java Adds v3 session lifecycle state enum for pooling.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/SessionWrapper.java Adds single-use wrapper type matching v3 behavior.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/SessionsManager.java Adds v3-style sessions manager implementation.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/NebulaPool.java Adds v3-compatible pool delegating to v5 pools (per-credential adaptation).
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/NebulaPoolConfig.java Adds v3 pool config bean and compatibility fields.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/SessionsManagerConfig.java Adds v3 sessions-manager config bean.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/SessionPoolConfig.java Adds v3 session-pool config bean.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/SessionPool.java Adds v3-compatible SessionPool delegating to v5 clients.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/NebulaSession.java Adds pooled session wrapper around a single v5 client.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/ErrorCode.java Adds v3 integer error code enum and v5→v3 mapping helper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/AuthFailedException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/BindSpaceFailedException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/ClientServerIncompatibleException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/IOErrorException.java Adds v3 exception type with v3-style error type integers.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/InvalidConfigException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/InvalidSessionException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/InvalidValueException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/exception/NotValidConnectionException.java Adds v3 exception type.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/BaseDataObject.java Adds base wrapper carrying decode type and timezone offset.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/HostAddress.java Adds v3 host address DTO + v5 conversion helpers.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/ResultSet.java Adds v3-compatible ResultSet that materializes v5 iterators.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/ValueWrapper.java Adds v3-style ValueWrapper API over v5 values.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/Node.java Adds v3 node wrapper over v5 node model.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/Relationship.java Adds v3 relationship wrapper over v5 edge model.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/PathWrapper.java Adds v3 path wrapper over v5 path model.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/DateWrapper.java Adds v3-compatible date wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/TimeWrapper.java Adds v3-compatible time wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/DateTimeWrapper.java Adds v3-compatible datetime wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/DurationWrapper.java Adds v3-compatible duration wrapper over v5 duration.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/GeographyWrapper.java Adds v3-compatible geography wrapper over v5 geography.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/CoordinateWrapper.java Adds v3-compatible coordinate wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/PointWrapper.java Adds v3-compatible point wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/LineStringWrapper.java Adds v3-compatible line string wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/PolygonWrapper.java Adds v3-compatible polygon wrapper.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/SSLParam.java Adds v3-compatible TLS param base class.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/SelfSignedSSLParam.java Adds v3-compatible self-signed TLS parameters.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/CASignedSSLParam.java Adds v3-compatible CA-signed TLS parameters.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/data/TimeUtil.java Adds timezone conversion helpers used by wrappers.
Suppressed comments (8)

client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Session.java:1

  • executeJson* currently serializes all row values as JSON strings because unquote() returns a String for non-quoted values too (e.g., numbers/booleans become "1"/"true"), and null becomes the literal string "NULL". This deviates from typical v3 JSON output expectations and breaks consumers parsing typed JSON. Consider building JSON values from ValueWrapper's type accessors (null → null, boolean → Boolean, ints → Long, doubles → Double, lists/maps → nested arrays/objects) rather than relying on toString().
    client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Session.java:1
  • Naive String.replace will substitute $key even when it appears inside string literals/comments or as a substring of a larger token (e.g., $p1 inside $p10 is handled by length-sort, but $p1 inside \"$p1\" would still be replaced). This can produce invalid or surprising GQL. A more robust approach is to replace only valid placeholder tokens (e.g., using a tokenizer or a regex with identifier boundaries and skipping quoted segments).
    client-v3compat/src/test/java/com/vesoft/nebula/driver/v3client/graph/net/SessionParameterTest.java:1
  • This test is order-dependent but uses HashMap, whose iteration order is unspecified in Java. It can become flaky if the map iterates as {b: true, a: 1}. Use an insertion-ordered map (e.g., LinkedHashMap) or assert in an order-insensitive way (e.g., accept either ordering).
    client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Session.java:1
  • IPv6 bracket parsing assumes \"]:<port>\" exists and blindly reads host.substring(close + 2). For inputs like [::1] (no port) or [::1]: this throws StringIndexOutOfBoundsException / NumberFormatException. Add validation for the post-] portion (length + : presence) and fall back to port 0 (or throw a clearer IllegalArgumentException) when absent/invalid.
    client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/RoundRobinLoadBalancer.java:1
  • Math.abs(int) overflows for Integer.MIN_VALUE and remains negative, which can produce a negative index after % addresses.size() and throw IndexOutOfBoundsException. Use Math.floorMod(pos.getAndIncrement(), addresses.size()) (or mask with & Integer.MAX_VALUE) to ensure a non-negative index.
    client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/SessionsManager.java:1
  • pool can still be null if close() is called before a successful init() (or if init() throws). pool.close() would then throw NullPointerException. Guard with if (pool != null) before closing.
    client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/NebulaPool.java:1
  • The v5 pool cache key uses only user, ignoring password. If the same username is used with different passwords over the application's lifetime, the cached pool will silently reuse the first password, which is surprising and can cause cross-tenant credential confusion. Consider keying by a composite of username+password (or username+password hash) or explicitly detecting password mismatches and failing fast.
    examples/src/main/java/com/vesoft/nebula/V3CompatExample.java:1
  • This address parsing breaks for IPv6 (contains multiple :) and also repeats split(\":\") twice. Consider using the shared parsing logic (Session.parseHost(...) or a small helper like toAddresses(...) in the other example) and validating that a port is present.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread client-v3compat/pom.xml
Comment thread README.md Outdated
case OUT_OF_RANGE:
return "OUT_OF_RANGE";
default:
return "Unknown type: " + nullType;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return value.getDataTypeString();

}
}

private com.vesoft.nebula.driver.graph.net.NebulaPool buildPool(String user, String password)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的差异是 v3中pool里的连接最多就是max个,多用户共享这max个connection; 此处的改造是一个用户最多max个session,n个用户最多n*max个session。

Re-implement the NebulaGraph v3 Java client's graph API under the
com.vesoft.nebula.driver.v3client namespace, delegating to the v5 driver,
so existing v3 applications can migrate with minimal changes.

- New module client-v3compat (depends on driver): Session / NebulaPool /
  SessionPool / SessionsManager, ResultSet / ValueWrapper / Node /
  Relationship / PathWrapper, date/time/geography wrappers, exceptions and
  a v3-style integer ErrorCode enum.
- Session.executeWithParameter inlines $param placeholders as GQL literals
  (the v5 execute RPC takes no parameter map); NebulaPool builds one v5 pool
  per username since v3 authenticates per session.
- Unit tests for value wrapping and parameter serialization, plus a live
  cluster integration test (V3IntegrationTest, disabled by default).
- Migration examples V3CompatExample and V3SessionPoolExample.
- Docs: migration_guide_v3.md (user-facing migration guide) and a
  "Migrate from the v3 Java client" section in README.md.
@xiajingchun
xiajingchun force-pushed the feature/v3client-compat branch from 1791961 to bfbd941 Compare August 21, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants