oracle-r2dbc
oracle-r2dbc copied to clipboard
LDAP URI it does not work
oracle-r2dbc version: 0.2.0 spring-boot: 2.5.2 Database: Oracle 19c
r2dbc:oracle:thin:@ldap://server:port/database,cn=OracleContext,dc=WORLD
Error:
reactor.core.Exceptions$ErrorCallbackNotImplemented: io.r2dbc.spi.R2dbcTransientResourceException: [17002] [08006] Error de E/S: Invalid connection string format, a valid format is: "host:port:sid" (CONNECTION_ID=qyq8AuNhQreSmex/HBjgiA==) Caused by: io.r2dbc.spi.R2dbcTransientResourceException: Error de E/S: Invalid connection string format, a valid format is: "host:port:sid" (CONNECTION_ID=qyq8AuNhQreSmex/HBjgiA==) at oracle.r2dbc.impl.OracleR2dbcExceptions.toR2dbcException(OracleR2dbcExceptions.java:211) at oracle.r2dbc.impl.OracleReactiveJdbcAdapter$$Lambda$1262/00000000A3888C30.apply(Unknown Source) at reactor.core.publisher.Flux.lambda$onErrorMap$29(Flux.java:6720) at reactor.core.publisher.Flux$$Lambda$1264/000000008D4CE270.apply(Unknown Source)
code for test:
ConnectionFactory connectionFactory = ConnectionFactories.get(
"r2dbc:oracle:thin:@ldap://server:port/database,cn=OracleContext,dc=WORLD");
Mono.from(connectionFactory.create())
.flatMapMany(connection ->
Flux.from(connection.createStatement(
"SELECT 'Hello, Oracle' FROM sys.dual")
.execute())
.flatMap(result ->
result.map((row, metadata) -> row.get(0, String.class)))
.doOnNext(System.out::println)
.thenMany(connection.close()))
.subscribe();
thanks
Hi @raenjamio, LDAP is not supported by Oracle R2DBC currently.
I believe that Oracle JDBC would use blocking network I/O to communicate with the LDAP server. So if we were to support this with the R2DBC driver, then it would require new functionality in the JDBC driver to perform non-blocking I/O with the LDAP server.
It's something to consider supporting with a future release, so I'll leave this issue open.
Where are we with this issue. Any plans for support . Most of enterprise uses LDAP based URLs.
I've not had any spare cycles to work on non-blocking LDAP requests in Oracle JDBC.
Just taking a moment to see how JDBC implements this, it looks to be built on top of the javax.naming package. I haven't worked with that package before, but after a quick scan I'm not seeing any kind of non-blocking API in there. I could very well be missing something; If anyone knows if whether javax.naming supports non-blocking requests, then please point me in the right direction.
As a stop-gap, it might be possible to support this with the existing blocking API call happening in JDBC. This would mean that threads would become blocked upon connection creation as JDBC makes a request to the LDAP server.
Would this feature still be valuable if threads become blocked when creating a new connection?
What do you mean by existing blocking API call. The connection initialization would be one time . If you could guide me to the right classes; i would like to help.
The blocking API I see Oracle JDBC call is javax.naming.DirContext.getAttributes(String, String[]) https://docs.oracle.com/en/java/javase/17/docs/api/java.naming/javax/naming/directory/DirContext.html#getAttributes(java.lang.String,java.lang.String%5B%5D)
I get the sense that this getAttributes method will make a blocking network request (but I'm not familiar with javax.naming, so I could be wrong).
If support for LDAP with blocking I/O is still useful, then we'd want to have Oracle R2DBC compose the jdbc:oracle:thin:@ldap:
URL when it creates an OracleDataSource:
https://github.com/oracle/oracle-r2dbc/blob/c35a1dd480c51146cf8762090efd81f9914999e1/src/main/java/oracle/r2dbc/impl/OracleReactiveJdbcAdapter.java#L443
And we'd also want to declare any extended Options needed for LDAP: https://github.com/oracle/oracle-r2dbc/blob/main/src/main/java/oracle/r2dbc/OracleR2dbcOptions.java
On the getAttributes(..) i read the spec from Oracle and i believe you are right . I think the changes to the adapter and option should do it but we need to think about the CN and DC as well . CN is always OracleContext but dc changes as per client . Would it be possible to talk that would ease up this back and forth. Very interested to contribute on this
One more thing as per the r2dbc spec we have a protocol option which we could use in this case . So we would not have to add anything in the Option class just get the value and create the URL.
I'm finishing up another project at the moment, but I'll want to come back to this in the next week. LDAP support is now the top feature request.
We will want to support this using the R2DBC URL format https://r2dbc.io/spec/1.0.0.RELEASE/spec/html/#overview.connection.url Using the protocol component to specify LDAP seems like the right idea. I think the CN,DC,etc can be specified in the path component as well.
Yes that would be the best . Sure would wait for your message and then we could start.
I've made some progress on this and would like to check in with @umangsingh123, @raenjamio, or anyone else who may be interested in this feature.
Below is a working draft of the documentation for this feature. I went for consistency with the Oracle JDBC URL, but please let me know if you've got an alternative approach in mind. Overall, I'd like to know if the proposed functionality will satisfy your use case. If I'm missing something, please let me know.
Finally, I'll note that all of Oracle JDBC's LDAP connection properties would be declared as extended options. This would allow the properties to be configured on a per-connection basis, rather than just as JVM system properties.
Looking forward to your feedback!
(Documentation follows)
Configuring an LDAP URL
Use ldap
or ldaps
as the URL protocol to have an Oracle Net Descriptor
retrieved from an LDAP server:
r2dbc:oracle:ldap://ldap.example.com:7777/sales,cn=OracleContext,dc=com
r2dbc:oracle:ldaps://ldap.example.com:7778/sales,cn=OracleContext,dc=com
Use a space separated list of LDAP URIs for fail over and load balancing:
r2dbc:oracle:ldap://ldap1.example.com:7777/sales,cn=OracleContext,dc=com%20ldap://ldap2.example.com:7777/sales,cn=OracleContext,dc=com%20ldap://ldap3.example.com:7777/sales,cn=OracleContext,dc=com
Space characters in a URL must be percent encoded as
%20
An LDAP server request will block a thread for network I/O when Oracle R2DBC creates a new connection.
This looks ok to me.l and the implementation would be on the url base correct not giving options.I am saying this because connection is one part to it but then comes pooling , security etc. .
@Michael-A-McMahon where are we on this did you get any time to work on this . Kindly let me know if i can help anywhere .
I've been pulled into some unrelated work for the last few days. I think I'll come back to this today or tomorrow though.
One thing that would be helpful is to test with an actual LDAP server, having an actual configuration. I don't have that, so I'm planning to just test with with a mock up. But if you have an LDAP server set up, it would be great if to try out the changes before I merge them.
I'll share the pull request and build instructions when ready.
To be clear: Do not share your LDAP server info here. I'm only suggesting that you could test out the changes in your own environment.
Which branch should i clone to test it .
I've pushed the branch just now: https://github.com/oracle/oracle-r2dbc/tree/40-ldap-support
I pulled the code and was compiling to create a jar but the tests fail
Running oracle.r2dbc.impl.OracleRowMetadataImplTest java.io.FileNotFoundException: config.properties resource not found. Check if it exists under src/test/resources/
I see the code is looking for config.properties
but i find example-config.properties
can i change that file and build the artifact.
Yes, you can create a config.properties file if you'd like. Or, you can build without tests by add -DskipTests=true to the mvn command line.
I have tried that but would skip the tests now
I haven't been able to send the created artifact to my actual env it rejects the email. So still trying it .
Thanks for the update. Your effort is appreciated.
LDAP URL support is merged and will be available in the next release.