Conversation
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
@greptile-apps anything else? |
|
The main critical issues have been covered — the two static field bugs are blocking and must be fixed before merge. A few additional notes: 1. No tests included — The PR adds JUnit/Mockito dependencies in 2. Resource cleanup — In try (Response response = httpClient.newCall(request).execute()) {
ResponseBody body = response.body();
// ... null check and read bytes
}3. Thread safety — Beyond the static field bugs, once those are fixed to instance fields, the driver should be thread-safe (OkHttp's client is thread-safe), but this hasn't been documented or tested. Bottom line: Fix the two critical static field bugs first — they break multi-driver usage entirely. The other issues are important but secondary. |
There was a problem hiding this comment.
Pull request overview
This PR adds an initial Java SDK/driver for the NeuG graph database, including a public API surface, internal HTTP/protobuf plumbing, Maven build configuration, and accompanying tests/docs.
Changes:
- Introduces core driver APIs (
Driver,Session,ResultSet) and factory entry point (GraphDatabase) backed by internal implementations. - Adds utility components for request/response handling over HTTP (OkHttp) with JSON serialization and protobuf response parsing.
- Adds a standalone Maven module (
tools/java_driver) with unit tests and a usage guide.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/java_driver/src/test/java/org/alibaba/neug/driver/QuerySerializerTest.java | Adds unit tests covering query JSON serialization permutations. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/JsonUtilTest.java | Adds tests to validate singleton ObjectMapper access. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/InternalResultSetTest.java | Adds tests for protobuf-to-Java type mapping, cursoring, and null bitmap handling. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/GraphDatabaseTest.java | Adds basic factory creation tests and multi-driver instantiation check. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/ConfigTest.java | Adds tests for default/custom config builder behavior. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/ClientTest.java | Adds tests around Client lifecycle and basic connectivity failure behavior. |
| tools/java_driver/src/test/java/org/alibaba/neug/driver/AccessModeTest.java | Adds enum sanity tests for AccessMode. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/ResponseParser.java | Adds protobuf response parsing helper returning ResultSet. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/QuerySerializer.java | Adds JSON request serializer for query/params/access mode. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/JsonUtil.java | Adds shared Jackson ObjectMapper singleton holder. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/Config.java | Adds driver configuration object + builder for timeouts/pool sizing. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/Client.java | Adds OkHttp-based synchronous POST client to /cypher. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/utils/AccessMode.java | Adds access mode enum used in requests. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/internal/InternalSession.java | Implements Session by serializing, posting, and parsing results. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/internal/InternalResultSet.java | Implements ResultSet cursoring and typed getters over protobuf arrays. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/internal/InternalDriver.java | Implements Driver to create sessions and manage the underlying client. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/Session.java | Defines the Session API for executing queries. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/ResultSet.java | Defines the ResultSet cursor and typed access API. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/GraphDatabase.java | Adds factory methods for driver creation with URI/config validation. |
| tools/java_driver/src/main/java/org/alibaba/neug/driver/Driver.java | Defines the top-level Driver interface and lifecycle methods. |
| tools/java_driver/pom.xml | Adds Maven module build, dependencies, protobuf generation, formatting, and test setup. |
| tools/java_driver/USAGE.md | Documents installation and example usage of the new Java driver. |
| proto/response.proto | Adds Java protobuf generation options (java_package, java_outer_classname). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalDriver.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/org/alibaba/neug/driver/Session.java
Outdated
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/utils/AccessMode.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/org/alibaba/neug/driver/internal/InternalResultSet.java
Outdated
Show resolved
Hide resolved
tools/java_driver/src/main/java/org/alibaba/neug/driver/internal/InternalResultSet.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalSession.java
Show resolved
Hide resolved
tools/java_driver/src/test/java/com/alibaba/neug/driver/InternalResultSetTest.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalDriver.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/test/java/org/alibaba/neug/driver/InternalResultSetTest.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…alResultSetTest.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@greptile |
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalDriver.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
…al/InternalDriver.java Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
@greptile |
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Outdated
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
…al/InternalResultSet.java Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…al/InternalResultSet.java Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
@greptile |
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/utils/Client.java
Show resolved
Hide resolved
|
@greptile |
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.java
Show resolved
Hide resolved
|
@greptile |
This pull request introduces a new Java driver for the NeuG graph database, including the initial implementation, build configuration, and usage documentation. The main changes establish the driver’s interface, provide factory methods for creating driver instances, set up Maven build and dependency management, and document how to use and integrate the driver in other projects.
Java driver implementation:
Driverinterface inDriver.java, defining methods for session creation, connectivity verification, resource cleanup, and closed-state checking.GraphDatabaseclass inGraphDatabase.javaas the entry point for creating driver instances, including URI validation and support for custom configuration via theConfigclass.Build and dependency configuration:
pom.xmlto manage dependencies (OkHttp, Protocol Buffers, Jackson, SLF4J, JUnit, Mockito), plugins for compilation, testing, code formatting, and Protocol Buffers code generation.Documentation:
USAGE.md, including installation instructions, dependency details, and example code for connecting, querying, and using configuration and parameters.Protocol Buffers integration:
response.protowithjava_packageandjava_outer_classnameoptions to support Java code generation for the driver.Greptile Summary
This PR introduces a complete Java driver for the NeuG graph database, covering HTTP transport (
Client/OkHttp), query serialization (JSON via Jackson), response parsing (protobuf), and the public API (Driver,Session,ResultSet). CI workflows are updated to build, format-check, and run unit and E2E tests. Several issues flagged in prior review rounds have been resolved (closed-state checks inInternalSessionandInternalDriver,next()/previous()sentinel positions,FLOAT_ARRAYingetObject(),first()on an empty result set). Two new logic bugs remain inInternalResultSet:relative()doesn't apply before-first/after-last sentinels — when the computed target is out of bounds,relative()delegates toabsolute()which returnsfalsewithout moving the cursor. Unlikenext()(which advances torowCount) andprevious()(which retreats to-1), a failedrelative()call leaves the cursor at its current position. A reverse-iteration loop callingrelative(-1)from row 0 will never seeisBeforeFirst()becometrue.BYTES_ARRAYunhandled ingetObject()andgetMetaData()— the proto schema definesBytesArray, andTypes.BYTESexists in the enum, but thegetObject()switch falls to thedefaultbranch and throwsUnsupportedOperationException. ThegetMetaData()switch similarly falls todefaultand reportsTypes.OTHERinstead ofTypes.BYTES. This is the same class of issue as theFLOAT_ARRAYgap that was fixed in this round.Confidence Score: 3/5
relative()sentinel bug and the missingBYTES_ARRAYcase ingetObject()andgetMetaData().next()/previous()sentinels,FLOAT_ARRAY). However,relative()leaves the cursor in an inconsistent state on out-of-bounds navigation (breaking reverse-iteration patterns), andBYTES_ARRAYcolumns will throwUnsupportedOperationExceptionat runtime — an omission symmetric to the already-fixedFLOAT_ARRAYgap. Both issues will surface in normal usage and should be addressed before merge.tools/java_driver/src/main/java/com/alibaba/neug/driver/internal/InternalResultSet.javaneeds attention for both therelative()sentinel fix and theBYTES_ARRAYdispatch cases.Important Files Changed
relative()doesn't advance the cursor to before-first/after-last sentinels on out-of-bounds navigation (unlikenext()/previous()), andBYTES_ARRAYis unhandled in bothgetObject()(throwsUnsupportedOperationException) andgetMetaData()(reportsTypes.OTHERinstead ofTypes.BYTES). Several previously-flagged issues are now fixed (next()/previous()sentinels,FLOAT_ARRAYingetObject(),first()on empty result set,getRow()afterafterLast()still returnsrowCountnot -1).run()throwsIllegalStateExceptionwhen the session is closed. Clean implementation.session()now checks if the client is closed and throwsIllegalStateException.verifyConnectivity()correctly uses try-with-resources. Clean and correct.syncPost(). MissingContent-Type: application/jsonheader on the request body (previously noted).closedfield is notvolatilebut driver doesn't advertise thread-safety.s4u/setup-maven-action@v1.19.0to configure Java 17 and Maven 3.9.6 cleanly — no redundantapt install mavenstep is present. Java format checking viamvn spotless:checkadded correctly.assumeTrueto skip when the server URI env-var is absent. Covers basic query and parameterized query paths correctly.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Client Code] --> B[GraphDatabase.driver uri, config] B --> |URI validation| C[InternalDriver] C --> D[Client OkHttp] A --> E[driver.session] E --> |checks client.isClosed| F[InternalSession] A --> G[session.run query, params, mode] G --> |checks closed flag| H[QuerySerializer.serialize] H --> I[Client.syncPost JSON bytes] I --> J[HTTP POST /cypher] J --> K[NeuG Server] K --> L[protobuf bytes] L --> M[ResponseParser.parse] M --> N[InternalResultSet] N --> O{Cursor Navigation} O --> |next / previous| P[Advance/Retreat cursor] O --> |absolute row| Q[Set cursor directly] O --> |relative rows ⚠️| R[Delegates to absolute - no sentinel fix] O --> |afterLast / beforeFirst| S[Set to rowCount or -1] N --> T{Data Access} T --> |getInt / getLong / getString etc.| U[getValues currentIndex] T --> |getObject| V{switch on ArrayType} V --> |BYTES_ARRAY ⚠️| W[UnsupportedOperationException] V --> |other types| X[Return typed value]Last reviewed commit: d23081c
Greptile Summary
This PR adds a complete Java driver for the NeuG graph database, covering HTTP transport (OkHttp), query serialization (JSON via Jackson), response parsing (protobuf), and the public API (
Driver,Session,ResultSet). CI workflows are updated to build, format-check, and run unit and E2E tests. Several issues flagged in prior review rounds have been resolved in this iteration: closed-state checks inInternalSessionandInternalDriver,next()/previous()sentinel positions,FLOAT_ARRAYingetObject(), andfirst()on an empty result set.Key observations in this round:
Types.BYTESis now orphaned —BytesArraywas removed fromresponse.protoin this PR (both the message and thebytes_array = 9field inArray), butTypes.BYTESremains inTypes.java. It is now a dead enum constant with no proto type to back it, and callers can never receive it fromgetMetaData().tools/java_driver/**was added to the C++ ccache hash inneug-test.yml. Java sources have no effect on C++ artifacts; including them in the key means Java-only PRs will always miss the primary ccache entry and fall back to incremental recompilation unnecessarily.testRelativevalidates unfixed behavior — the test is written to pass against the current (broken)relative()cursor semantics; it would fail if therelative()sentinel bug were fixed in a future PR, making the test an implicit obstacle to that fix.Confidence Score: 4/5
Types.BYTESdead enum constant and the ccache key over-expansion; the two pre-existing open issues (relative()sentinels,getRow()afterafterLast()) are carryovers from prior rounds and do not block this iteration.relative()sentinel andgetRow()afterafterLast()) are carryovers from prior review rounds. New issues introduced in this iteration are minor: a deadTypes.BYTESenum constant left behind afterBytesArraywas removed from the proto, and an unnecessarily broad ccache key in CI. Neither blocks correctness in production.tools/java_driver/src/main/java/com/alibaba/neug/driver/utils/Types.java(deadBYTESconstant) and.github/workflows/neug-test.yml(ccache key over-expansion).Important Files Changed
next()/previous()sentinels,FLOAT_ARRAYingetObject(), andfirst()on empty result set. Two pre-existing issues from prior review rounds remain open:relative()does not advance the cursor to before-first/after-last on out-of-bounds navigation, andgetRow()returnsrowCountinstead of-1afterafterLast().Types.BYTESis now a dead enum constant: the PR removesBytesArrayfromresponse.protobut leaves this entry in place. Minor inconsistency introduced by this PR.syncPost().closedfield is notvolatileandclose()is not synchronized, so concurrent use could see stale state — but the driver does not advertise thread-safety. MissingContent-Type: application/jsonheader remains (flagged in prior round).tools/java_driver/**is unnecessarily included in the ccache hash key, causing C++ cache misses on Java-only changes.testRelativeis written against the current (unfixed)relative()sentinel behavior — the test would fail if therelative()bug were corrected.java_packageandjava_outer_classnameoptions added for Java code generation.BytesArraymessage andbytes_array = 9field removed from theArrayoneof — intentional, but leavesTypes.BYTESorphaned inTypes.java.Sequence Diagram
sequenceDiagram participant App as Client Code participant GDB as GraphDatabase participant DRV as InternalDriver participant CLI as Client (OkHttp) participant SES as InternalSession participant SRV as NeuG Server participant RS as InternalResultSet App->>GDB: driver(uri, config) GDB->>GDB: validate URI (null/empty/scheme) GDB->>DRV: new InternalDriver(uri, config) DRV->>CLI: new Client(uri, config) GDB-->>App: Driver App->>DRV: session() DRV->>DRV: check client.isClosed() DRV->>SES: new InternalSession(client) DRV-->>App: Session App->>SES: run(query, params, mode) SES->>SES: check closed flag SES->>SES: QuerySerializer.serialize(query, params, mode) SES->>CLI: syncPost(jsonBytes) CLI->>CLI: check closed flag CLI->>SRV: HTTP POST /cypher (JSON body) SRV-->>CLI: protobuf bytes CLI-->>SES: responseBytes SES->>RS: ResponseParser.parse(responseBytes) Note over RS: cursor starts at -1 (before-first) SES-->>App: ResultSet App->>RS: next() / absolute() / relative() RS-->>App: boolean (row available) App->>RS: getInt() / getString() / getObject() RS-->>App: typed value App->>RS: wasNull() RS-->>App: boolean App->>SES: close() App->>DRV: close() DRV->>CLI: close() → evictAll + shutdown executorLast reviewed commit: "remove bytearray"