|
23 | 23 |
|
24 | 24 | import io.r2dbc.spi.Connection; |
25 | 25 | import io.r2dbc.spi.ConnectionFactories; |
| 26 | +import io.r2dbc.spi.ConnectionFactory; |
26 | 27 | import io.r2dbc.spi.ConnectionFactoryOptions; |
27 | 28 | import io.r2dbc.spi.Option; |
28 | 29 | import io.r2dbc.spi.R2dbcTimeoutException; |
|
31 | 32 | import oracle.jdbc.datasource.OracleDataSource; |
32 | 33 | import oracle.r2dbc.OracleR2dbcOptions; |
33 | 34 | import oracle.r2dbc.test.DatabaseConfig; |
| 35 | +import oracle.r2dbc.util.TestContextFactory; |
34 | 36 | import org.junit.jupiter.api.Test; |
35 | 37 | import reactor.core.publisher.Flux; |
36 | 38 | import reactor.core.publisher.Mono; |
37 | 39 |
|
| 40 | +import javax.naming.spi.NamingManager; |
38 | 41 | import java.io.IOException; |
39 | 42 | import java.nio.channels.ServerSocketChannel; |
40 | 43 | import java.nio.channels.SocketChannel; |
@@ -216,12 +219,7 @@ public void testCreateDataSource() throws SQLException { |
216 | 219 | public void testTnsAdmin() throws IOException { |
217 | 220 |
|
218 | 221 | // Create an Oracle Net Descriptor |
219 | | - String descriptor = format( |
220 | | - "(DESCRIPTION=(ADDRESS=(HOST=%s)(PORT=%d)(PROTOCOL=%s))" + |
221 | | - "(CONNECT_DATA=(SERVICE_NAME=%s)))", |
222 | | - host(), port(), |
223 | | - Objects.requireNonNullElse(protocol(), "tcp"), |
224 | | - serviceName()); |
| 222 | + String descriptor = createDescriptor(); |
225 | 223 |
|
226 | 224 | // Create a tnsnames.ora file with an alias for the descriptor |
227 | 225 | Files.writeString(Path.of("tnsnames.ora"), |
@@ -525,6 +523,102 @@ public void testVSessionOptions() { |
525 | 523 | tryAwaitNone(connection.close()); |
526 | 524 | } |
527 | 525 | } |
| 526 | + /** |
| 527 | + * Verifies the use of the LDAP protocol in an r2dbc:oracle URL. |
| 528 | + */ |
| 529 | + @Test |
| 530 | + public void testLdapUrl() throws Exception { |
| 531 | + |
| 532 | + // Configure Oracle R2DBC with an R2DBC URL having the LDAP protocol and the |
| 533 | + // given path. |
| 534 | + String ldapPath = "sales,cn=OracleContext,dc=com"; |
| 535 | + ConnectionFactory ldapConnectionFactory = ConnectionFactories.get( |
| 536 | + ConnectionFactoryOptions.parse(format( |
| 537 | + "r2dbc:oracle:ldap://ldap.example.com:9999/%s", ldapPath)) |
| 538 | + .mutate() |
| 539 | + .option(ConnectionFactoryOptions.USER, DatabaseConfig.user()) |
| 540 | + .option(ConnectionFactoryOptions.PASSWORD, DatabaseConfig.password()) |
| 541 | + .build()); |
| 542 | + |
| 543 | + // Set up the mock LDAP context factory. See JavaDoc of TestContextFactory |
| 544 | + // for details about this. |
| 545 | + NamingManager.setInitialContextFactoryBuilder(environment -> |
| 546 | + new TestContextFactory()); |
| 547 | + TestContextFactory.bind(ldapPath, createDescriptor()); |
| 548 | + |
| 549 | + // Now verify that the LDAP URL is resolved to the descriptor |
| 550 | + Connection ldapConnection = awaitOne(ldapConnectionFactory.create()); |
| 551 | + try { |
| 552 | + assertEquals( |
| 553 | + "Hello, LDAP", |
| 554 | + awaitOne( |
| 555 | + awaitOne(ldapConnection.createStatement( |
| 556 | + "SELECT 'Hello, LDAP' FROM sys.dual") |
| 557 | + .execute()) |
| 558 | + .map(row -> row.get(0)))); |
| 559 | + } |
| 560 | + finally { |
| 561 | + tryAwaitNone(ldapConnection.close()); |
| 562 | + } |
| 563 | + } |
| 564 | + |
| 565 | + /** |
| 566 | + * Verifies the use of the LDAP protocol in an r2dbc:oracle URL having |
| 567 | + * multiple LDAP endpoints |
| 568 | + */ |
| 569 | + @Test |
| 570 | + public void testMultiLdapUrl() throws Exception { |
| 571 | + |
| 572 | + // Configure Oracle R2DBC with an R2DBC URL having the LDAP protocol and |
| 573 | + // multiple LDAP endpoints. Only the last endpoint will contain the given |
| 574 | + // path, and so the previous endpoints are invalid. |
| 575 | + String ldapPath = "cn=salesdept,cn=OracleContext,dc=com/salesdb"; |
| 576 | + ConnectionFactory ldapConnectionFactory = ConnectionFactories.get( |
| 577 | + ConnectionFactoryOptions.parse(format( |
| 578 | + "r2dbc:oracle:" + |
| 579 | + "ldap://ldap1.example.com:7777/cn=salesdept0,cn=OracleContext,dc=com/salesdb" + |
| 580 | + "%%20ldap://ldap1.example.com:7777/cn=salesdept1,cn=OracleContext,dc=com/salesdb" + |
| 581 | + "%%20ldap://ldap3.example.com:7777/%s", ldapPath)) |
| 582 | + .mutate() |
| 583 | + .option(ConnectionFactoryOptions.USER, DatabaseConfig.user()) |
| 584 | + .option(ConnectionFactoryOptions.PASSWORD, DatabaseConfig.password()) |
| 585 | + .build()); |
| 586 | + |
| 587 | + // Set up the mock LDAP context factory. A descriptor is bound to the last |
| 588 | + // endpoint only. See JavaDoc of TestContextFactory for details about this. |
| 589 | + NamingManager.setInitialContextFactoryBuilder(environment -> |
| 590 | + new TestContextFactory()); |
| 591 | + TestContextFactory.bind("salesdb", createDescriptor()); |
| 592 | + |
| 593 | + // Now verify that the LDAP URL is resolved to the descriptor |
| 594 | + Connection ldapConnection = awaitOne(ldapConnectionFactory.create()); |
| 595 | + try { |
| 596 | + assertEquals( |
| 597 | + "Hello, LDAP", |
| 598 | + awaitOne( |
| 599 | + awaitOne(ldapConnection.createStatement( |
| 600 | + "SELECT 'Hello, LDAP' FROM sys.dual") |
| 601 | + .execute()) |
| 602 | + .map(row -> row.get(0)))); |
| 603 | + } |
| 604 | + finally { |
| 605 | + tryAwaitNone(ldapConnection.close()); |
| 606 | + } |
| 607 | + } |
| 608 | + |
| 609 | + /** |
| 610 | + * Returns an Oracle Net Descriptor having the values configured by |
| 611 | + * {@link DatabaseConfig} |
| 612 | + * @return An Oracle Net Descriptor for the test database. |
| 613 | + */ |
| 614 | + private static String createDescriptor() { |
| 615 | + return format( |
| 616 | + "(DESCRIPTION=(ADDRESS=(HOST=%s)(PORT=%d)(PROTOCOL=%s))" + |
| 617 | + "(CONNECT_DATA=(SERVICE_NAME=%s)))", |
| 618 | + host(), port(), |
| 619 | + Objects.requireNonNullElse(protocol(), "tcp"), |
| 620 | + serviceName()); |
| 621 | + } |
528 | 622 |
|
529 | 623 | /** |
530 | 624 | * Verifies that an attempt to connect with a {@code listeningChannel} |
|
0 commit comments