feat: add v3 client compatibility layer (client-v3compat) - #655
feat: add v3 client compatibility layer (client-v3compat)#655xiajingchun wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
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-v3compatMaven 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 becauseunquote()returns aStringfor 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 fromValueWrapper's type accessors (null →null, boolean →Boolean, ints →Long, doubles →Double, lists/maps → nested arrays/objects) rather than relying ontoString().
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/Session.java:1- Naive
String.replacewill substitute$keyeven when it appears inside string literals/comments or as a substring of a larger token (e.g.,$p1inside$p10is handled by length-sort, but$p1inside\"$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 readshost.substring(close + 2). For inputs like[::1](no port) or[::1]:this throwsStringIndexOutOfBoundsException/NumberFormatException. Add validation for the post-]portion (length +:presence) and fall back to port0(or throw a clearerIllegalArgumentException) when absent/invalid.
client-v3compat/src/main/java/com/vesoft/nebula/driver/v3client/graph/net/RoundRobinLoadBalancer.java:1 Math.abs(int)overflows forInteger.MIN_VALUEand remains negative, which can produce a negative index after% addresses.size()and throwIndexOutOfBoundsException. UseMath.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:1poolcan still benullifclose()is called before a successfulinit()(or ifinit()throws).pool.close()would then throwNullPointerException. Guard withif (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, ignoringpassword. 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 repeatssplit(\":\")twice. Consider using the shared parsing logic (Session.parseHost(...)or a small helper liketoAddresses(...)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.
| case OUT_OF_RANGE: | ||
| return "OUT_OF_RANGE"; | ||
| default: | ||
| return "Unknown type: " + nullType; |
There was a problem hiding this comment.
return value.getDataTypeString();
| } | ||
| } | ||
|
|
||
| private com.vesoft.nebula.driver.graph.net.NebulaPool buildPool(String user, String password) |
There was a problem hiding this comment.
这里的差异是 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.
1791961 to
bfbd941
Compare
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-v3compatre-implements the v3 client'sgraphpackage under thecom.vesoft.nebula.driver.v3clientnamespace and delegates internally to the v5driver.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:
client:3.x→client-v3compat:5.3-SNAPSHOT),com.vesoft.nebula.client.→com.vesoft.nebula.driver.v3client.),See
migration_guide_v3.mdfor the full user-facing migration guide.What's included
client-v3compat(depends ondriver), registered in the rootpom.xml.NebulaPool,Session,SessionPool,NebulaSession,SessionsManager, plus config beans and the connection-level shims (Connection,SyncConnection,LoadBalancer, …).ResultSet(+Record),ValueWrapper(+NullType),Node,Relationship,PathWrapper, date/time/duration/geography wrappers,HostAddress, SSL params,TimeUtil.ErrorCode(full 200-entry enum) with a v5→v3 code mapping.Key adaptation decisions
Session/NebulaSessionwrap a v5NebulaClient(one client = one server session).NebulaPoollazily builds one v5NebulaPoolper username (v3 authenticates pergetSession, v5 bakes credentials into the pool).executeWithParameterinlines$paramplaceholders as GQL literals (value2GqlLiteral), since the v5 execute RPC takes no parameter map. Longest-key-first replacement avoids prefix collisions.ResultSeteagerly materializes the v5 one-shot iterator into the v3 index-based accessors.SessionPoolbinds the graph viaSESSION SET GRAPH "…".Declared differences (non-restorable in v5)
Node.getId()/Relationship.srcId()/dstId()return the v5 numeric id; string ids are no longer recoverable.ResultSet.getRows()(removed),getPlanDesc()(returns v5PlanInfoNode),getSpaceName()/getComment()(return""),ValueWrapper.getValue()(returns the v5 wrapper).DECIMALvalues are surfaced viaValueWrapper.isDouble()/asDouble().Testing
ValueWrapperTest(value wrapping),SessionParameterTest(literal serialization + inline replacement) — 10 tests.V3IntegrationTest(disabled by default,-Dnebula.it=true), runs create-graph-type → create-graph → insert →MATCHnode/edge/path →SessionPool→ cleanup against a live v5 cluster; 5 tests passed.V3CompatExample,V3SessionPoolExample.Run locally: