Skip to content

Commit

Permalink
Merge pull request #23 from oracle/descriptor-option
Browse files Browse the repository at this point in the history
Add oracle-net-descriptor option
  • Loading branch information
jeandelavarene authored Apr 15, 2021
2 parents e7189e4 + f522a36 commit 527b7e1
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 108 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ Options. For Options having any of the following names, a CharSequence value may
- [oracle.net.ssl_context_protocol](https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html?is-external=true#CONNECTION_PROPERTY_SSL_CONTEXT_PROTOCOL)
- [oracle.jdbc.fanEnabled](https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html?is-external=true#CONNECTION_PROPERTY_FAN_ENABLED)
- [oracle.jdbc.implicitStatementCacheSize](https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/jdbc/OracleConnection.html?is-external=true#CONNECTION_PROPERTY_IMPLICIT_STATEMENT_CACHE_SIZE)
- Descriptor URLs of the form ```(DESCRIPTION=...)``` may be specified in a tnsnames.ora file.
- The directory containing the tnsnames.ora file may be specified as an ```Option``` having the name "TNS_ADMIN"
- An alias of a tnsnames.ora file may be specified as the value of ```ConnectionFactoryOptions.HOST```.
- An alias of a tnsnames.ora file may be specified with an R2DBC URL: ```r2dbc:oracle://my_alias?TNS_ADMIN=/path/to/tnsnames/```
- Oracle Net Descriptors of the form ```(DESCRIPTION=...)``` may be specified as an io.r2dbc.spi.Option having the name `oracleNetDescriptor`.
- If `oracleNetDescriptor` is specified, then it is invalid to specify any other options that might conflict with information in the descriptor, such as: `HOST`, `PORT`, `DATABASE`, and `SSL`.
- The `oracleNetDescriptor` option may appear in the query section of an R2DBC URL: `r2dbc:oracle://?oracleNetDescriptor=(DESCRIPTION=...)`
- The `oracleNetDescriptor` option may be provided programatically: `ConnectionFactoryOptions.builder().option(Option.valueOf("oracleNetDescriptor"), "(DESCRIPTION=...)")`
- The `oracleNetDescriptor` option may be set as the alias of a descriptor in a tnsnames.ora file. The directory of tnsnames.ora may be set using an io.r2dbc.spi.Option having the name `TNS_ADMIN`: `r2dbc:oracle://?oracleNetDescriptor=myAlias&TNS_ADMIN=/path/to/tnsnames/`


### Thread Safety and Parallel Execution
Expand Down
7 changes: 2 additions & 5 deletions sample/example-config.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# Values in this properties file configure how sample code connects to a
# database.

# This file contains example values. Create a copy named config.properties in
# Values in this properties file configure how sample code connects to a # database. # This file contains example values. Create a copy named config.properties in
# /sample and change the example values to actual values for your test database.

# Host name of a test database
Expand All @@ -11,7 +8,7 @@ HOST=db.host.example.com
PORT=1521

# Service name of a test database
SERVICE_NAME=db.service.name
DATABASE=db.service.name

# User name authenticated by a test database
USER=db_user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class DatabaseConfig {
static final int PORT = Integer.parseInt(CONFIG.getProperty("PORT"));

/** Service name of an Oracle Database */
static final String SERVICE_NAME = CONFIG.getProperty("SERVICE_NAME");
static final String SERVICE_NAME = CONFIG.getProperty("DATABASE");

/** User name that connects to an Oracle Database */
static final String USER = CONFIG.getProperty("USER");
Expand Down
10 changes: 5 additions & 5 deletions sample/src/main/java/oracle/r2dbc/samples/DescriptorURL.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import reactor.core.publisher.Mono;

import static oracle.r2dbc.samples.DatabaseConfig.HOST;
Expand Down Expand Up @@ -53,8 +54,8 @@ public class DescriptorURL {
"(CONNECT_DATA=(SERVICE_NAME="+SERVICE_NAME+")))";

public static void main(String[] args) {
// A descriptor may appear in the host section of an R2DBC URL:
String r2dbcUrl = "r2dbc:oracle://"+DESCRIPTOR;
// A descriptor may appear in the query section of an R2DBC URL:
String r2dbcUrl = "r2dbc:oracle://?oracleNetDescriptor="+DESCRIPTOR;
Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.parse(r2dbcUrl)
.mutate()
.option(ConnectionFactoryOptions.USER, USER)
Expand All @@ -71,11 +72,10 @@ public static void main(String[] args) {
.toStream()
.forEach(System.out::println);

// A descriptor may also be specified as the value of
// ConnectionFactoryOptions.HOST
// A descriptor may also be specified as an Option
Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, "oracle")
.option(ConnectionFactoryOptions.HOST, DESCRIPTOR)
.option(Option.valueOf("oracleNetDescriptor"), DESCRIPTOR)
.option(ConnectionFactoryOptions.USER, USER)
.option(ConnectionFactoryOptions.PASSWORD, PASSWORD)
.build())
Expand Down
59 changes: 44 additions & 15 deletions src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import reactor.core.publisher.Mono;

import javax.sql.DataSource;
import java.time.Duration;

/**
* <p>
Expand All @@ -48,21 +49,43 @@
* </p>
* <h3 id="required_options">Required Options</h3><p>
* This implementation requires the following options for connection creation:
* </p><ul>
* <li>{@link ConnectionFactoryOptions#DRIVER}</li>
* <li>{@link ConnectionFactoryOptions#HOST}</li>
* </ul>
* </p><dl>
* <dt>{@link ConnectionFactoryOptions#DRIVER}</dt>
* <dd>Must have the value "oracle"</dd>
* <dt>{@link ConnectionFactoryOptions#HOST}</dt>
* <dd>IP address or hostname of an Oracle Database</dd>
* </dl>
* <h3 id="supported_options">Supported Options</h3><p>
* This implementation supports the following well known options for connection
* creation:
* </p><ul>
* <li>{@link ConnectionFactoryOptions#PORT}</li>
* <li>{@link ConnectionFactoryOptions#DATABASE}</li>
* <li>{@link ConnectionFactoryOptions#USER}</li>
* <li>{@link ConnectionFactoryOptions#PASSWORD}</li>
* <li>{@link ConnectionFactoryOptions#CONNECT_TIMEOUT}</li>
* <li>{@link ConnectionFactoryOptions#SSL}</li>
* </ul>
* This implementation supports the following options for connection creation:
* </p><dl>
* <dt>{@link ConnectionFactoryOptions#PORT}</dt>
* <dd>Port number of an Oracle Database</dd>
* <dt>{@link ConnectionFactoryOptions#DATABASE}</dt>
* <dd>Service name (not an SID) of an Oracle Database</dd>
* <dt>{@link ConnectionFactoryOptions#USER}</dt>
* <dd>Name of an Oracle Database user</dd>
* <dt>{@link ConnectionFactoryOptions#PASSWORD}</dt>
* <dd>
* Password of an Oracle Database user. The value may be an instance
* of a mutable {@link CharSequence}, such {@link java.nio.CharBuffer},
* that may be cleared after creating an instance of
* {@code OracleConnectionFactoryImpl}.
* </dd>
* <dt>{@link ConnectionFactoryOptions#CONNECT_TIMEOUT}</dt>
* <dd>
* Maximum wait time when requesting a {@code Connection}. If the
* duration expires, a {@code Connection} {@code Subscriber} receives
* {@code onError} with an {@link io.r2dbc.spi.R2dbcTimeoutException}.
* The duration is rounded up to the nearest whole second. The query
* section of an R2DBC URL may provide a value in the format specified by
* {@link Duration#parse(CharSequence)}.
* </dd>
* <dt>{@link ConnectionFactoryOptions#SSL}</dt>
* <dd>
* If set to {@code true}, the driver connects to Oracle Database using
* TCPS (ie: SSL/TLS).
* </dd>
* </dl>
* <h3 id="extended_options">Supported Options</h3><p>
* This implementation supports extended options having the name of a
* subset of Oracle JDBC connection properties. The list of supported
Expand Down Expand Up @@ -117,10 +140,16 @@ final class OracleConnectionFactoryImpl implements ConnectionFactory {
* </p>
*
* @param options Options applied when opening a connection to a database.
*
* @throws IllegalArgumentException If the value of a required option is
* null.
*
* @throws IllegalStateException If the value of a required option is not
* specified.
*
* @throws IllegalArgumentException If the {@code oracleNetDescriptor}
* {@code Option} is provided with any other options that might have
* conflicting values, such as {@link ConnectionFactoryOptions#HOST}.
*/
OracleConnectionFactoryImpl(ConnectionFactoryOptions options) {
OracleR2dbcExceptions.requireNonNull(options, "options is null.");
Expand Down Expand Up @@ -170,4 +199,4 @@ public Publisher<Connection> create() {
public ConnectionFactoryMetadata getMetadata() {
return () -> "Oracle Database";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import java.util.ServiceLoader;

import static io.r2dbc.spi.ConnectionFactoryOptions.DRIVER;
import static oracle.r2dbc.impl.OracleR2dbcExceptions.requireNonNull;

/**
Expand Down Expand Up @@ -83,8 +84,13 @@ public OracleConnectionFactoryProviderImpl() { }
* {@code ConnectionFactory} that applies values specified by the {@code
* options} parameter, when opening connections to an Oracle Database.
* </p>
*
* @throws IllegalStateException If any option required by
* {@link OracleConnectionFactoryImpl} is not specified by {@code options}.
*
* @throws IllegalArgumentException If the {@code oracleNetDescriptor}
* {@code Option} is provided with any other options that might have
* conflicting values, such as {@link ConnectionFactoryOptions#HOST}.
*/
@Override
public ConnectionFactory create(ConnectionFactoryOptions options) {
Expand All @@ -103,8 +109,7 @@ public ConnectionFactory create(ConnectionFactoryOptions options) {
@Override
public boolean supports(ConnectionFactoryOptions options) {
requireNonNull(options, "options must not be null.");
return DRIVER_IDENTIFIER.equals(
options.getValue(ConnectionFactoryOptions.DRIVER));
return DRIVER_IDENTIFIER.equals(options.getValue(DRIVER));
}

/**
Expand All @@ -119,4 +124,4 @@ public String getDriver() {
return DRIVER_IDENTIFIER;
}

}
}
Loading

0 comments on commit 527b7e1

Please sign in to comment.