diff --git a/sample/build.gradle b/sample/build.gradle index f1234d6..8a3e598 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -36,7 +36,7 @@ dependencies { sourceCompatibility = 1.11 targetCompatibility = 1.11 -mainClassName = 'TcpsConnectDemo' +mainClassName = 'oracle.r2dbc.samples.TcpsConnectDemo' run { // To enable network debugging: diff --git a/sample/example-config.properties b/sample/example-config.properties index edb2e36..e03375c 100644 --- a/sample/example-config.properties +++ b/sample/example-config.properties @@ -11,7 +11,7 @@ HOST=db.host.example.com PORT=1521 # Service name of a test database -DATABASE=db.service.name +SERVICE_NAME=db.service.name # User name authenticated by a test database USER=db_user diff --git a/sample/src/main/java/oracle/r2dbc/samples/DatabaseConfig.java b/sample/src/main/java/oracle/r2dbc/samples/DatabaseConfig.java new file mode 100644 index 0000000..58b1246 --- /dev/null +++ b/sample/src/main/java/oracle/r2dbc/samples/DatabaseConfig.java @@ -0,0 +1,75 @@ +/* + Copyright (c) 2020, 2021, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package oracle.r2dbc.samples; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +/** + *

+ * Configuration for connecting code samples to an Oracle Database instance. + *

+ * The configuration is read from a properties file in the current directory + * by default, or from a file specified as + * -DCONFIG_FILE=/path/to/your/config.properties + *

+ */ +public class DatabaseConfig { + + /** Path to a configuration file: config.properties */ + private static final Path CONFIG_PATH = + Path.of(System.getProperty("CONFIG_FILE", "config.properties")); + + /** Configuration that is read from a file at {@link #CONFIG_PATH} */ + private static final Properties CONFIG; + static { + try (var fileStream = Files.newInputStream(CONFIG_PATH)) { + CONFIG = new Properties(); + CONFIG.load(fileStream); + } + catch (IOException readFailure) { + throw new UncheckedIOException(readFailure); + } + } + + /** Host name where an Oracle Database instance is running */ + static final String HOST = CONFIG.getProperty("HOST"); + + /** Port number where an Oracle Database instance is listening */ + static final int PORT = Integer.parseInt(CONFIG.getProperty("PORT")); + + /** Service name of an Oracle Database */ + static final String SERVICE_NAME = CONFIG.getProperty("SERVICE_NAME"); + + /** User name that connects to an Oracle Database */ + static final String USER = CONFIG.getProperty("USER"); + + /** Password of the user that connects to an Oracle Database */ + static final String PASSWORD = CONFIG.getProperty("PASSWORD"); + + /** The file system path of a wallet directory */ + static final String WALLET_LOCATION = + CONFIG.getProperty("WALLET_LOCATION"); +} diff --git a/sample/src/main/java/oracle/r2dbc/samples/DescriptorURL.java b/sample/src/main/java/oracle/r2dbc/samples/DescriptorURL.java new file mode 100644 index 0000000..5002630 --- /dev/null +++ b/sample/src/main/java/oracle/r2dbc/samples/DescriptorURL.java @@ -0,0 +1,93 @@ +/* + Copyright (c) 2020, 2021, Oracle and/or its affiliates. + + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package oracle.r2dbc.samples; + +import io.r2dbc.spi.ConnectionFactories; +import io.r2dbc.spi.ConnectionFactoryOptions; +import reactor.core.publisher.Mono; + +import static oracle.r2dbc.samples.DatabaseConfig.HOST; +import static oracle.r2dbc.samples.DatabaseConfig.PORT; +import static oracle.r2dbc.samples.DatabaseConfig.SERVICE_NAME; +import static oracle.r2dbc.samples.DatabaseConfig.USER; +import static oracle.r2dbc.samples.DatabaseConfig.PASSWORD; + +/** + * This code example shows how to use TNS descriptor URLs with Oracle R2DBC. + * The TNS descriptor has the form: + *
+ *   (DESCRIPTION=...)
+ * 
+ * The full syntax of the TNS descriptor is described in the + * + * Oracle Net Services Administrator's Guide + * + */ +public class DescriptorURL { + + /** + * A TNS descriptor specifying the HOST, PORT, and SERVICE_NAME read from + * {@link DatabaseConfig}. + */ + private static final String DESCRIPTOR = "(DESCRIPTION=" + + "(ADDRESS=(HOST="+HOST+")(PORT="+PORT+")(PROTOCOL=tcp))" + + "(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; + Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.parse(r2dbcUrl) + .mutate() + .option(ConnectionFactoryOptions.USER, USER) + .option(ConnectionFactoryOptions.PASSWORD, PASSWORD) + .build()) + .create()) + .flatMapMany(connection -> + Mono.from(connection.createStatement( + "SELECT 'Connected with TNS descriptor' FROM sys.dual") + .execute()) + .flatMapMany(result -> + result.map((row, metadata) -> row.get(0, String.class))) + .concatWith(Mono.from(connection.close()).cast(String.class))) + .toStream() + .forEach(System.out::println); + + // A descriptor may also be specified as the value of + // ConnectionFactoryOptions.HOST + Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.builder() + .option(ConnectionFactoryOptions.DRIVER, "oracle") + .option(ConnectionFactoryOptions.HOST, DESCRIPTOR) + .option(ConnectionFactoryOptions.USER, USER) + .option(ConnectionFactoryOptions.PASSWORD, PASSWORD) + .build()) + .create()) + .flatMapMany(connection -> + Mono.from(connection.createStatement( + "SELECT 'Connected with TNS descriptor' FROM sys.dual") + .execute()) + .flatMapMany(result -> + result.map((row, metadata) -> row.get(0, String.class))) + .concatWith(Mono.from(connection.close()).cast(String.class))) + .toStream() + .forEach(System.out::println); + } +} diff --git a/sample/src/main/java/TcpsConnectDemo.java b/sample/src/main/java/oracle/r2dbc/samples/TcpsConnectDemo.java similarity index 82% rename from sample/src/main/java/TcpsConnectDemo.java rename to sample/src/main/java/oracle/r2dbc/samples/TcpsConnectDemo.java index 1ae6645..1a242be 100644 --- a/sample/src/main/java/TcpsConnectDemo.java +++ b/sample/src/main/java/oracle/r2dbc/samples/TcpsConnectDemo.java @@ -19,6 +19,8 @@ limitations under the License. */ +package oracle.r2dbc.samples; + import io.r2dbc.spi.ConnectionFactories; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.ConnectionFactoryOptions; @@ -28,14 +30,16 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.io.IOException; -import java.io.UncheckedIOException; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.Files; -import java.nio.file.Path; import java.time.Duration; -import java.util.Properties; + +import static oracle.r2dbc.samples.DatabaseConfig.HOST; +import static oracle.r2dbc.samples.DatabaseConfig.PASSWORD; +import static oracle.r2dbc.samples.DatabaseConfig.PORT; +import static oracle.r2dbc.samples.DatabaseConfig.SERVICE_NAME; +import static oracle.r2dbc.samples.DatabaseConfig.USER; +import static oracle.r2dbc.samples.DatabaseConfig.WALLET_LOCATION; /** * Sample code that uses an Oracle Wallet to authenticate with an Oracle @@ -67,40 +71,6 @@ */ public class TcpsConnectDemo { - /** Path to a configuration file: config.properties */ - private static final Path CONFIG_PATH = - Path.of(System.getProperty("CONFIG_FILE", "config.properties")); - - /** Configuration that is read from a file at {@link #CONFIG_PATH} */ - private static final Properties CONFIG; - static { - try (var fileStream = Files.newInputStream(CONFIG_PATH)) { - CONFIG = new Properties(); - CONFIG.load(fileStream); - } - catch (IOException readFailure) { - throw new UncheckedIOException(readFailure); - } - } - - /** Host name where an Oracle Database instance is running */ - private static final String HOST = CONFIG.getProperty("HOST"); - - /** Port number where an Oracle Database instance is listening */ - private static final int PORT = Integer.parseInt(CONFIG.getProperty("PORT")); - - /** Service name of an Oracle Database */ - private static final String SERVICE_NAME = CONFIG.getProperty("SERVICE_NAME"); - - /** User name that connects to an Oracle Database */ - private static final String USER = CONFIG.getProperty("USER"); - - /** Password of the user that connects to an Oracle Database */ - private static final String PASSWORD = CONFIG.getProperty("PASSWORD"); - - /** The file system path of a wallet directory */ - private static final String WALLET_LOCATION = - CONFIG.getProperty("WALLET_LOCATION"); public static void main(String[] args) throws URISyntaxException {