Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(java/driver/flight-sql): add basic auth #572

Closed
wants to merge 1 commit into from

Conversation

tokoko
Copy link
Contributor

@tokoko tokoko commented Apr 2, 2023

@lidavidm I want a quick feedback on some of the changes.

  • Removed unused FlightClient from FlightSqlDatabase
  • FlightClient creation moved from FlightSqlDatabase to FlightSqlConnection. In the existing version after connect() is called a new client object is created, but all of them shared the same allocator. That was probably a bug, right?
  • username/password passed as parameters named adbc.username and adbc.password (to be added in AdbcDriver). Are there any plans to have some sort of connection string syntax like JDBC?
  • As there can be more than one FlightClients, I wanted to avoid keeping track of auth token, so added a middleware that does both: extract an auth token and pass it on future calls. It's functionally similar to the go example, but I couldn't use authenticateBasicToken because I couldn't find a way to extract bearer value from CredenialCallOption. Maybe there's a simpler way to accomplish this???
  • I'd like to keep FlightClient creation logic contained in clientCache. Right now the main FlightClient is created independently and only Endpoint clients are obtained from cache. If changed, main client will always have to be obtained from cache before usage, otherwise it might have expired.

@lidavidm
Copy link
Member

lidavidm commented Apr 3, 2023

Hey - it's gonna be a few weeks before I can review

just fyi, C/Go use just "username" and "password" so best to stick to that if possible

@tokoko
Copy link
Contributor Author

tokoko commented Apr 3, 2023

Okay, I'll push ahead with dremio suite then and you can review it at the end

@lidavidm
Copy link
Member

lidavidm commented Apr 7, 2023

In the existing version after connect() is called a new client object is created, but all of them shared the same allocator. That was probably a bug, right?

See some recent Java commits/issues that change up how allocators are handled (the current implementation had leaks): e69723a, #563, #564

username/password passed as parameters named adbc.username and adbc.password (to be added in AdbcDriver). Are there any plans to have some sort of connection string syntax like JDBC?

Only URIs for now (C/Go have settled on "uri" as the standard parameter, Java needs to align with that too)

It's functionally similar to the go example, but I couldn't use authenticateBasicToken because I couldn't find a way to extract bearer value from CredenialCallOption. Maybe there's a simpler way to accomplish this???

I will have to dig later but possibly/probably upstream needs to be fixed first; I don't think any of that was implemented to really do anything other than support the JDBC driver specifically

I'd like to keep FlightClient creation logic contained in clientCache. Right now the main FlightClient is created independently and only Endpoint clients are obtained from cache. If changed, main client will always have to be obtained from cache before usage, otherwise it might have expired.

It seems you could factor out a factory function that can be used to create a one-off main client as well as cached clients?

Copy link
Member

@lidavidm lidavidm left a comment

Choose a reason for hiding this comment

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

Things look good here generally, thanks!

FWIW, the Go driver also supports just supplying the value of the Authorization header itself (in case you're integrating with some token-based auth scheme) - possibly worth keeping in mind.

@@ -48,6 +50,8 @@ public AdbcDatabase initDatabase(BufferAllocator allocator) throws AdbcException

final Map<String, Object> parameters = new HashMap<>();
parameters.put(AdbcDriver.PARAM_URL, url);
parameters.put("adbc.username", System.getenv(FLIGHT_SQL_USER_ENV_VAR));
Copy link
Member

Choose a reason for hiding this comment

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

As mentioned, let's use just "username" for consistency with other implementations

FlightClient flightClient =
FlightClient.builder(allocator, loc)
.intercept(
new FlightClientMiddleware.Factory() {
Copy link
Member

Choose a reason for hiding this comment

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

nit: could we pull this out into a static inner class instead of having it inline here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would make Factory a doubly nested inner class, probably best if I split it into an entirely separate file.

Copy link
Member

Choose a reason for hiding this comment

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

That would be fine IMO. Once the code starts creeping too much to the right it gets a little hard to read.

Comment on lines +71 to +72
(String) parameters.get("adbc.username"),
(String) parameters.get("adbc.password"));
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be better to pass the parameters instead. The FlightSqlDatabase will need to know about all the params to decide how to build the FlightClient. For example, all the TLS options.

It would also be nice to have dataclasses or static objects with all the option values https://arrow.apache.org/adbc/main/driver/go/flight_sql.html#client-options

@jduo
Copy link
Member

jduo commented Jan 22, 2024

@tokoko , this issue hasn't been updated since May. May I help finish getting this one merged?

@jduo
Copy link
Member

jduo commented Jan 23, 2024

FYI the JDBC Flight SQL Driver implements optional sharing of the bearer token on spawned connections. It does so when building the driver -- it reads the token from the middle ware then on subsequent FlightClients appends it as a header parameter to the request.

@jduo
Copy link
Member

jduo commented Feb 6, 2024

Completed in #1487

@jduo jduo closed this Feb 6, 2024
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.

4 participants