diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index 576022c5..665ec417 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -33,11 +33,16 @@ jobs: - name: Install dependencies run: mvn install -DskipTests + + - name: Set GCP environment variables + run : | + echo "GOOGLE_APPLICATION_CREDENTIALS=$HOME/.gcp/config.json" >> $GITHUB_ENV - name: Prepare certificate and properties files run: | mkdir -p $HOME/.azure mkdir -p $HOME/.oci + mkdir -p $HOME/.gcp # Prepare certificate echo "${{ secrets.TEST_AZURE_CERTIFICATE }}" > $HOME/.azure/ojdbc-plugin-test-app.pem @@ -131,6 +136,9 @@ jobs: AWS_SECRETS_MANAGER_URL=${{ secrets.TEST_AWS_SECRETS_MANAGER_URL }}\n " >> ojdbc-provider-aws/test.properties + # Generate GCP config + echo "${{ secrets.TEST_GCP_CONFIG }}" > $HOME/.gcp/config.json + echo "${{ secrets.GCP_TEST_PROPERTIES }}" > ojdbc-provider-gcp/test.properties # Generate ojdbc-provider-hashicorp/test.properties echo -e "VAULT_ADDR=${{ secrets.TEST_VAULT_ADDR }}\n @@ -165,6 +173,9 @@ jobs: rm ojdbc-provider-azure/ojdbc-provider-test-app.pfx rm ojdbc-provider-azure/test.properties + rm $HOME/.gcp/config.json + rm ojdbc-provider-gcp/test.properties + rm ojdbc-provider-jackson-oson/test.properties rm ojdbc-provider-aws/test.properties diff --git a/README.md b/README.md index 7e582c7c..e8443118 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Each module of this project contains a set of providers.
+jdbc:oracle:thin:@config-gcpstorage://project={project};bucket={bucket};object={object} ++ +### JSON Payload format + +There are 3 fixed values that are looked at the root level. + +- connect_descriptor (required) +- user (optional) +- password (optional) + +The rest are dependent on the driver, in our case `/jdbc`. The key-value pairs that are with sub-prefix `/jdbc` will be applied to a DataSource. The key values are constant keys which are equivalent to the properties defined in the [OracleConnection](https://docs.oracle.com/en/database/oracle/oracle-database/23/jajdb/oracle/jdbc/OracleConnection.html) interface. + +For example, let's suppose an url like: + +
+jdbc:oracle:thin:@config-gcpstorage://project=myproject;bucket=mybucket;object=payload_ojdbc_objectstorage.json ++ +And the JSON Payload for the file **payload_ojdbc_objectstorage.json** in the **mybucket** which belongs to the project **myproject** is as following: + +```json +{ + "connect_descriptor": "(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=adb.us-phoenix-1.oraclecloud.com))(connect_data=(service_name=xsxsxs_dbtest_medium.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))", + "user": "scott", + "password": { + "type": "gcpsecretmanager", + "value": "projects/138028249883/secrets/test-secret/versions/1" + }, + "jdbc": { + "oracle.jdbc.ReadTimeout": 1000, + "defaultRowPrefetch": 20, + "autoCommit": "false" + } +} +``` + +The sample code below executes as expected with the previous configuration. + +```java + OracleDataSource ds = new OracleDataSource(); + ds.setURL("jdbc:oracle:thin:@config-gcpstorage://project=myproject;bucket=mybucket;object=payload_ojdbc_objectstorage.json"); + Connection cn = ds.getConnection(); + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("select sysdate from dual"); + if (rs.next()) + System.out.println("select sysdate from dual: " + rs.getString(1)); +``` + +### Password JSON Object + +For the JSON type of provider (GCP Object Storage, HTTP/HTTPS, File) the password is an object itself with the following spec: + +- type + - Mandatory + - Possible values + - ocivault + - azurevault + - base64 + - gcpsecretmanager +- value + - Mandatory + - Possible values + - OCID of the secret (if ocivault) + - Azure Key Vault URI (if azurevault) + - Base64 Encoded password (if base64) + - GCP resource name (if gcpsecretmanager) + - Text +- authentication + - Optional + - Possible Values + - method + - optional parameters (depends on the cloud provider). + +## GCP Secret Manager Config Provider +Apart from GCP Cloud Storage, users can also store JSON Payload in the content of GCP Secret Manager secret. Users need to indicate the resource name: + +
+jdbc:oracle:thin:@config-gcpsecretmanager:{resource-name} ++ +The JSON Payload retrieved by GCP Vault Config Provider follows the same format in [GCP Object Storage Config Provider](#json-payload-format). + +## Caching configuration + +Config providers in this module store the configuration in caches to minimize +the number of RPC requests to remote location. See +[Caching configuration](../ojdbc-provider-azure/README.md#caching-configuration) for more +details of the caching mechanism. + +## Vault Password Provider +The Vault Password Provider provides Oracle JDBC with a password that is managed +by the GCP Secret Manager service. This is a Resource Provider identified by the +name `ojdbc-provider-gcp-secret-password`. + +This provider requires the parameters listed below. +
Parameter Name | +Description | +Accepted Values | +Default Value | +
---|---|---|---|
secretVersionName | +Identifies the secret that is provided. | +The resource name of the secret. | +No default value. A value must be configured for this parameter. | +
Parameter Name | +Description | +Accepted Values | +Default Value | +
---|---|---|---|
secretVersionName | +Identifies the secret that is provided. | +The resource name of the secret. | +No default value. A value must be configured for this parameter. | +
Parameter Name | +Description | +Accepted Values | +Default Value | +
---|---|---|---|
secretVersionName | +The name of the secret version in GCP Secret Manager that contains the TCPS wallet file. | + The GCP Secret Manager Secret Version, typically in the form:
+projects/{project-id}/secrets/{secret-id}/versions/{version-id}+ |
++No default value. A value must be configured for this parameter. + | +
walletPassword | ++Optional password for PKCS12 or protected PEM files. If omitted, the file is assumed to be SSO or a non-protected PEM file. + | +Any valid password for the wallet | ++No default value. PKCS12 and password-protected PEM files require a password. + | +
type | ++Specifies the type of the file being used. + | +SSO, PKCS12, PEM | ++No default value. The file type must be specified. + | +
Parameter Name | +Description | +Accepted Values | +Default Value | +
---|---|---|---|
secretVersionName | +The name of the secret version in GCP Secret Manager that contains the SEPS wallet file. | + The GCP Secret Manager Secret Version, typically in the form:
+projects/{project-id}/secrets/{secret-id}/versions/{version-id}+ |
++No default value. A value must be configured for this parameter. + | +
walletPassword | ++Optional password for wallets stored as PKCS12 keystores. If omitted, the wallet is assumed to be an SSO wallet. + | +Any valid password for the SEPS wallet | ++No default value. PKCS12 wallets require a password. + | +
connectionStringIndex | ++Optional parameter to specify the index of the connection string to use when retrieving credentials from the wallet. + | +A positive integer representing the index of the desired credential set (e.g., 1, 2, 3, etc.). | ++No default value. If not specified, the provider follows the default behavior as described above. + | +
Parameter Name | +Description | +Accepted Values | +Default Value | +
---|---|---|---|
secretVersionName |
+ The version name of the secret in GCP Secret Manager that contains the tnsnames.ora file. |
+ The GCP Secret Manager Secret Version, typically in the form:projects/{project-id}/secrets/{secret-id}/versions/{version-id} |
+ No default value. A value must be configured for this parameter. | +
tnsAlias |
+ Specifies the alias to retrieve the appropriate connection string from the tnsnames.ora file. |
+ Any valid alias present in your tnsnames.ora file. |
+ No default value. A value must be configured for this parameter. | +
+ * Returns the JSON payload stored in GCP Cloud Storage. + *
+ * + * @param location semi-colon separated list of key value pairs + * containing the following keys: + *+ * A parser that recognizes parameters of key/value pairs received by + * {@link GcpCloudStorageConfigurationProvider}, and resource names received + * by {@link GcpSecretManagerConfigurationProvider}. + *
+ */ + private static final ParameterSetParser PARAMETER_SET_PARSER = ParameterSetParser.builder() + .addParameter("value", SECRET_VERSION_NAME) + .addParameter("secretVersionName", SECRET_VERSION_NAME) + .addParameter( + GcpCloudStorageConfigurationProvider.PROJECT_PARAMETER, GcpCloudStorageFactory.PROJECT) + .addParameter( + GcpCloudStorageConfigurationProvider.BUCKET_PARAMETER, GcpCloudStorageFactory.BUCKET) + .addParameter( + GcpCloudStorageConfigurationProvider.OBJECT_PARAMETER, GcpCloudStorageFactory.OBJECT) + .addParameter("type", Parameter.create()) + .build(); + + /** + * @return A parser that recognizes parameters of URIs received by + * {@link GcpCloudStorageConfigurationProvider}, and JSON objects + * received by + * {@link GcpSecretManagerConfigurationProvider}. + */ + public static ParameterSetParser getParser() { + return PARAMETER_SET_PARSER; + } +} diff --git a/ojdbc-provider-gcp/src/main/java/oracle/jdbc/provider/gcp/configuration/GcpJsonSecretManagerProvider.java b/ojdbc-provider-gcp/src/main/java/oracle/jdbc/provider/gcp/configuration/GcpJsonSecretManagerProvider.java new file mode 100644 index 00000000..8d4b7c16 --- /dev/null +++ b/ojdbc-provider-gcp/src/main/java/oracle/jdbc/provider/gcp/configuration/GcpJsonSecretManagerProvider.java @@ -0,0 +1,86 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.configuration; + +import com.google.protobuf.ByteString; + +import java.util.Base64; +import java.util.Map; + +import oracle.jdbc.provider.gcp.secrets.GcpSecretManagerFactory; +import oracle.jdbc.provider.parameter.ParameterSet; +import oracle.jdbc.spi.OracleConfigurationSecretProvider; + +public class GcpJsonSecretManagerProvider implements OracleConfigurationSecretProvider { + + /** + * {@inheritDoc} + *+ * Returns the password of the Secret that is retrieved from GCP Secrets. + *
+ *+ * The JSON object has the following form: + *
+ * + *{@code + * "password": { + * "type": "gcpsecretmanager", + * "value": "projects/+ * + * @param secretProperties a map containing the flattened key/value pairs of + * the JSON object. + * @return encoded char array in base64 format that represents the retrieved + * Secret. + */ + @Override + public char[] getSecret(Map/secrets/ /versions/ ", + * } + * }
+ * Returns the JSON payload stored in GCP Secret Manager secret. + *
+ * + * @param location resource name of the secret version (to obtain the resource + * name, click on "Actions" and "Copy resource name") + * @return JSON payload + */ + @Override + public InputStream getInputStream(String location) throws SQLException { + Map+ * A provider for securely retrieving the connection string from a tnsnames.ora + * file stored in GCP Secret Manager for use with an Oracle Autonomous Database. + * The tnsnames.ora file can be stored either as a base64-encoded secret or in + * raw binary format in GCP Secret Manager. This provider automatically + * detects and decodes base64-encoded content as needed before parsing the + * file to retrieve connection strings based on specified aliases. + *
+ *+ * This class implements the {@link ConnectionStringProvider} SPI defined by + * Oracle JDBC. It is designed to be instantiated via {@link java.util.ServiceLoader}. + *
+ */ +public class GcpSecretManagerConnectionStringProvider + extends GcpSecretManagerProvider + implements ConnectionStringProvider { + + private static final ResourceParameter[] TNS_NAMES_PARAMETERS = { + new ResourceParameter("tnsAlias", TNS_ALIAS) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public GcpSecretManagerConnectionStringProvider() { + super("secretmanager-tnsnames", TNS_NAMES_PARAMETERS); + } + + /** + * Retrieves a database connection string from the tnsnames.ora file stored + * in GCP Secret Manager. + *+ * This method accesses the file in GCP Secret Manager, detects if the content + * is base64-encoded, and decodes it if necessary. The tnsnames.ora content is + * then parsed to locate the connection string associated with the specified + * alias. + *
+ * + * @param parameterValues The parameters required to access the tnsnames.ora + * file in GCP Secret Manager, including the secret name and the tns-alias. + * @return The connection string associated with the specified alias + * in the tnsnames.ora file. + * @throws IllegalStateException If there is an error reading the tnsnames.ora + * file or accessing the GCP Secret Manager. + * @throws IllegalArgumentException If the specified alias is invalid or + * does not exist in the tnsnames.ora file. + */ + @Override + public String getConnectionString(Map+ * A provider of passwords from the GCP Secret Manager service. + *
+ *+ * This class implements the {@link PasswordProvider} SPI defined by + * Oracle JDBC. It is designed to be located and instantiated by + * {@link java.util.ServiceLoader}. + *
+ */ +public class GcpSecretManagerPasswordProvider extends GcpSecretManagerProvider implements PasswordProvider { + + public GcpSecretManagerPasswordProvider() { + super("secretmanager-password"); + } + + @Override + public char[] getPassword(Map+ * Retrieves a secret from GCP Secret Manager based on parameters provided + * in {@code parameterValues}. This method centralizes secret retrieval logic + *
+ *+ * The method uses the {@code getResource} method to parse the + * {@code parameterValues} and request the secret from GCP Secret Manager + * via the {@link GcpSecretManagerFactory} instance. + * The secret is returned as a {@code ByteString}. + *
+ *+ * This method is designed to be called from subclasses which implement an + * {@link oracle.jdbc.spi.OracleResourceProvider} SPI. + *
+ * + * @param parameterValues Text values of parameters. Not null. + * @return The identified secret. Not null. + */ + protected final ByteString getSecret( + Map+ * A provider for retrieving both the username and password from a Secure + * External Password Store (SEPS) wallet stored in Google Cloud Platform (GCP) + * Secret Manager. The wallet can be in either SSO or PKCS12 format. If a + * password is provided, the wallet is treated as PKCS12, otherwise, it + * is assumed to be in SSO format. + *
+ *+ * This class implements the {@link UsernameProvider} and + * {@link PasswordProvider} SPIs defined by Oracle JDBC. + * It is designed to be located and instantiated by + * {@link java.util.ServiceLoader}. + *
+ * + *+ * The SEPS wallet is stored in GCP Secret Manager as a base64-encoded string, + * or it may be stored in binary format. This provider decodes the wallet if it + * is base64-encoded and retrieves the username and password required for + * database authentication. + *
+ */ +public class GcpSecretManagerSEPSProvider + extends GcpSecretManagerProvider + implements UsernameProvider, PasswordProvider { + + private static final ResourceParameter[] SEPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("connectionStringIndex", CONNECTION_STRING_INDEX) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public GcpSecretManagerSEPSProvider() { + super("secretmanager-seps", SEPS_PARAMETERS); + } + + @Override + public String getUsername(Map+ * A provider for TCPS/TLS files used to establish secure TLS communication + * with an Autonomous Database. The file is retrieved from GCP Secret Manager, + * where it is stored either as a base64-encoded string or directly in binary + * format (e.g., a wallet imported as a file). This provider supports + * different file types, including SSO, PKCS12, and PEM formats. + *
+ *+ * The type of the file must be explicitly specified using the {@code type} + * parameter. Based on the type, the file may contain private keys and + * certificates for establishing secure communication. A password is only + * required for PKCS12 or encrypted PEM files. + *
+ *+ * This class implements the {@link TlsConfigurationProvider} SPI defined by + * Oracle JDBC and is designed to be instantiated via + * {@link java.util.ServiceLoader}. + *
+ */ +public class GcpSecretManagerTCPSProvider + extends GcpSecretManagerProvider + implements TlsConfigurationProvider { + + private static final ResourceParameter[] TCPS_PARAMETERS = { + new ResourceParameter("walletPassword", PASSWORD), + new ResourceParameter("type", TYPE) + }; + + /** + * A public no-arg constructor used by {@link java.util.ServiceLoader} to + * construct an instance of this provider. + */ + public GcpSecretManagerTCPSProvider() { + super("secretmanager-tls", TCPS_PARAMETERS); + } + + /** + * Retrieves an SSLContext by loading a file from GCP Secret Manager and + * configuring it for secure TLS communication with Autonomous Database. + *+ * The file is stored in GCP Secret Manager either as a base64-encoded string + * or in its raw binary format. + * The type of the file (SSO, PKCS12, or PEM) must be explicitly provided, + * and the method processes the file data accordingly, extracting keys and + * certificates, and creating an SSLContext. + *
+ * + * @param parameterValues The parameters required to access the file, + * including the secret version name, password (if applicable), and + * file type (SSO, PKCS12, PEM). + * @return An initialized SSLContext for establishing secure communications. + * @throws IllegalStateException If the SSLContext cannot be created due to + * errors during processing. + */ + @Override + public SSLContext getSSLContext(Map+ * A provider of usernames from the GCP Secret Manager service. + *
+ *+ * This class implements the {@link UsernameProvider} SPI defined by + * Oracle JDBC. It is designed to be located and instantiated by + * {@link java.util.ServiceLoader}. + *
+ */ +public class GcpSecretManagerUsernameProvider extends GcpSecretManagerProvider implements UsernameProvider { + + public GcpSecretManagerUsernameProvider() { + super("secretmanager-username"); + } + + @Override + public String getUsername(Map+ * Factory for requesting secrets from the Vault service. Secrets are + * represented as {@link SecretPayload} objects. Oracle JDBC can use the content + * of a secret as a database password, or any other security sensitive value. + *
+ */ +public class GcpSecretManagerFactory implements ResourceFactory+ * Requests the content of a secret bundle from the Vault service. The + * {@code parameterSet} is required to include a {@link #SECRET_VERSION_NAME}. + *
+ */ + @Override + public Resource+ * Connects to a database using connection properties retrieved from GCP + * Cloud Storage. + *
+ *+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + */ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@config-gcpstorage://" + OBJECT_PROPERTIES; + + // Standard JDBC code + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + + System.out.println("Connection URL: " + url); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } + +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SecretManagerExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SecretManagerExample.java new file mode 100644 index 00000000..93334e6b --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SecretManagerExample.java @@ -0,0 +1,110 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.configuration; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import oracle.jdbc.datasource.impl.OracleDataSource; +import oracle.jdbc.provider.Configuration; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from GCP Secret Manager. + */ +public class SecretManagerExample { + + /** + * An GCP SecretManager resource name configured as a JVM system property, + * environment variable, or configuration.properties file entry named + * "gcp_secret_version_name_config". + */ + private static final String RESOURCE_NAME = Configuration + .getRequired("gcp_secret_version_name_config"); + + /** + *+ * Simple example to retrieve connection properties from GCP Secret Manager. + *
+ *+ * To run this example, the payload needs to be stored in GCP Secret Manager. + * The payload examples can be found in + * {@link oracle.jdbc.spi.OracleConfigurationProvider}. + *
+ * Users need to indicate the resource name of the Secret with the following + * syntax: + * + *+ * jdbc:oracle:thin:@config-gcpsecretmanager:{resource-name} + *+ * + *
+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + **/ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@config-gcpsecretmanager://" + RESOURCE_NAME; + // Sample default URL if non present + if (args.length > 0) { + url = args[0]; + } + + // No changes required, configuration provider is loaded at runtime + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + + // Standard JDBC code + try (Connection cn = ds.getConnection()) { + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleCloudStorageExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleCloudStorageExample.java new file mode 100644 index 00000000..af2b2731 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleCloudStorageExample.java @@ -0,0 +1,100 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.configuration; + +import oracle.jdbc.datasource.impl.OracleDataSource; +import oracle.jdbc.provider.Configuration; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from OCI Cloud Storage. + */ +public class SimpleCloudStorageExample { + + /** + * An GCP Storage object properties as a JVM system property, + * environment variable, or configuration.properties file entry named + * "gcp_cloud_storage_properties". + */ + private static final String STORAGE_OBJECT = Configuration + .getRequired("gcp_cloud_storage_properties"); + + /** + *+ * Connects to a database using connection properties retrieved from GCP + * Object Storage. + *
+ *+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + */ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@config-gcpstorage://" + STORAGE_OBJECT; + + // Standard JDBC code + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + + System.out.println("Connection URL: " + url); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } + +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleSecretManagerExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleSecretManagerExample.java new file mode 100644 index 00000000..7e036c0a --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/configuration/SimpleSecretManagerExample.java @@ -0,0 +1,110 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.configuration; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import oracle.jdbc.datasource.impl.OracleDataSource; +import oracle.jdbc.provider.Configuration; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from GCP Secret Manager. + */ +public class SimpleSecretManagerExample { + + + /** + * An GCP SecretManager resource name configured as a JVM system property, + * environment variable, or configuration.properties file entry named + * "gcp_secret_version_name_config". + */ + private static final String SECRET_VERSION_NAME = Configuration + .getRequired("gcp_secret_version_name_config"); + + /** + *+ * Simple example to retrieve connection properties from GCP Secret Manager. + *
+ *+ * To run this example, the payload needs to be stored in GCP Secret Manager. + * The payload examples can be found in + * {@link oracle.jdbc.spi.OracleConfigurationProvider}. + *
+ * Users need to indicate the resource name of the Secret with the following + * syntax: + * + *+ * jdbc:oracle:thin:@config-gcpsecretmanager:{resource-name} + *+ *
+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + **/ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@config-gcpsecretmanager://" + SECRET_VERSION_NAME; + // Sample default URL if non present + if (args.length > 0) { + url = args[0]; + } + + // No changes required, configuration provider is loaded at runtime + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + + // Standard JDBC code + try (Connection cn = ds.getConnection()) { + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleConnectionStringProviderExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleConnectionStringProviderExample.java new file mode 100644 index 00000000..9b11e762 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleConnectionStringProviderExample.java @@ -0,0 +1,99 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * Example demonstrating how to configure Oracle JDBC with the GCP Secret Manager + * Connection String Provider to retrieve connection strings from a tnsnames.ora + * file stored in GCP Secret Manager. + */ +public class SimpleConnectionStringProviderExample { + public static void main(String[] args) throws SQLException { + try { + OracleDataSource ds = new OracleDataSource(); + ds.setURL("jdbc:oracle:thin:@"); + ds.setUser("DB_USERNAME"); + ds.setPassword("DB_PASSWORD"); + + Properties connectionProps = new Properties(); + + // Connection String Provider for retrieving tnsnames.ora content + // from GCP Secret Manager + connectionProps.put("oracle.jdbc.provider.connectionString", + "ojdbc-provider-gcp-secretmanager-tnsnames"); + + connectionProps.put("oracle.jdbc.provider.connectionString.secretVersionName", + "projects/your-project-id/secrets/your-tnsnames-secret/versions/1"); + + // Specify the tns-alias to retrieve the corresponding connection string + connectionProps.put("oracle.jdbc.provider.connectionString.tnsAlias", + "YOUR_TNS_ALIAS"); + + // TLS Configuration for secure connection + connectionProps.put("oracle.jdbc.provider.tlsConfiguration", + "ojdbc-provider-gcp-secretmanager-tls"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.secretVersionName", + "projects/your-project-id/secrets/your-wallet-secret/versions/1"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.type", "SSO"); + + ds.setConnectionProperties(connectionProps); + + try (Connection cn = ds.getConnection()) { + + String query = "SELECT 'Hello, db' FROM sys.dual"; + try (Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + if (rs.next()) { + System.out.println(rs.getString(1)); + } + } + } + } catch (SQLException e) { + throw new RuntimeException("Connection failed: ", e); + } + } +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderExample.java new file mode 100644 index 00000000..95dc02db --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderExample.java @@ -0,0 +1,108 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from a GCP Secret Manager SEPS Wallet. + *+ * This example demonstrates how to use the SEPS Wallet Provider with Oracle JDBC + * to connect to an Oracle Autonomous Database (ADB). + * It retrieves the database credentials from a Secure External Password Store + * (SEPS) wallet stored in GCP Secret Manager. + *
+ *+ * The SEPS wallet securely stores encrypted database credentials. + *
+ */ +public class SimpleSEPSWalletProviderExample { + private static final String DB_URL = "(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=your_db_host))(connect_data=(service_name=your_service_name))(security=(ssl_server_dn_match=yes)))"; + private static final String JDBC_URL = "jdbc:oracle:thin:@" + DB_URL; + + + public static void main(String[] args) { + try { + OracleDataSource ds = new OracleDataSource(); + ds.setURL(JDBC_URL); + + Properties connectionProps = new Properties(); + connectionProps.put("oracle.jdbc.provider.username", + "ojdbc-provider-gcp-secretmanager-seps"); + connectionProps.put("oracle.jdbc.provider.password", + "ojdbc-provider-gcp-secretmanager-seps"); + + // Set the secret version name of your SEPS wallet stored in GCP Secret Manager + connectionProps.put("oracle.jdbc.provider.username.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + connectionProps.put("oracle.jdbc.provider.password.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + + // TLS Configuration Provider + connectionProps.put("oracle.jdbc.provider.tlsConfiguration", + "ojdbc-provider-gcp-secretmanager-tls"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.type","SSO"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + + ds.setConnectionProperties(connectionProps); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} + + diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderWithIndexExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderWithIndexExample.java new file mode 100644 index 00000000..13b60d52 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSEPSWalletProviderWithIndexExample.java @@ -0,0 +1,114 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * A standalone example that configures Oracle JDBC to be provided with a + * specified connection string index to retrieve credentials from a GCP + * Secret Manager SEPS wallet. + *+ * This example demonstrates how to use the SEPS Wallet Provider with Oracle JDBC + * to connect to an Oracle Autonomous Database (ADB) using credentials stored + * in a Secure External Password Store (SEPS) wallet managed by GCP Secret Manager. + * It retrieves the database credentials from the SEPS wallet stored in GCP Secret Manager, + * specifying a connection string index to select a specific credential set. + *
+ *+ * The SEPS wallet securely stores encrypted database credentials. + *
+ * + */ +public class SimpleSEPSWalletProviderWithIndexExample { + private static final String DB_URL = "(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=your_db_host))(connect_data=(service_name=your_service_name))(security=(ssl_server_dn_match=yes)))"; + private static final String JDBC_URL = "jdbc:oracle:thin:@" + DB_URL; + + + public static void main(String[] args) { + try { + OracleDataSource ds = new OracleDataSource(); + ds.setURL(JDBC_URL); + + Properties connectionProps = new Properties(); + connectionProps.put("oracle.jdbc.provider.username", + "ojdbc-provider-gcp-secretmanager-seps"); + connectionProps.put("oracle.jdbc.provider.password", + "ojdbc-provider-gcp-secretmanager-seps"); + + // Set the secret version name of your SEPS wallet stored in GCP Secret Manager + connectionProps.put("oracle.jdbc.provider.username.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + connectionProps.put("oracle.jdbc.provider.password.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + + // Specify the connection string index + connectionProps.put("oracle.jdbc.provider.username.connectionStringIndex","1"); + connectionProps.put("oracle.jdbc.provider.password.connectionStringIndex","1"); + + connectionProps.put("oracle.jdbc.provider.tlsConfiguration", + "ojdbc-provider-gcp-secretmanager-tls"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.type","SSO"); + + ds.setConnectionProperties(connectionProps); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} + + diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSecretManagerUsernameProviderExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSecretManagerUsernameProviderExample.java new file mode 100644 index 00000000..6613b211 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleSecretManagerUsernameProviderExample.java @@ -0,0 +1,94 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * Example demonstrating how to use the Secret Manager Username Provider + * with Oracle JDBC to securely retrieve a database username from GCP Secret Manager. + *+ * This example shows how to configure Oracle JDBC to retrieve the username + * stored in GCP Secret Manager. + *
+ */ +public class SimpleSecretManagerUsernameProviderExample { + private static final String DB_URL = "(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=your_db_host))(connect_data=(service_name=your_service_name))(security=(ssl_server_dn_match=yes)))"; + private static final String JDBC_URL = "jdbc:oracle:thin:@" + DB_URL; + + + public static void main(String[] args) throws SQLException { + try { + OracleDataSource ds = new OracleDataSource(); + ds.setURL(JDBC_URL); + ds.setPassword("DB_PASSWORD"); + + Properties connectionProps = new Properties(); + connectionProps.put("oracle.jdbc.provider.username", + "ojdbc-provider-gcp-secretmanager-username"); + connectionProps.put("oracle.jdbc.provider.username.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + // TLS Configuration Provider + connectionProps.put("oracle.jdbc.provider.tlsConfiguration", + "ojdbc-provider-gcp-secretmanager-tls"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.type","SSO"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + ds.setConnectionProperties(connectionProps); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleTCPSWalletProviderExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleTCPSWalletProviderExample.java new file mode 100644 index 00000000..072155c5 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleTCPSWalletProviderExample.java @@ -0,0 +1,92 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ + +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * Example demonstrating how to configure Oracle JDBC with the TCPS Wallet + * Provider to establish a secure TLS connection to an Oracle Autonomous + * Database. + *+ * The wallet is retrieved from GCP Secret Manager to enable secure TLS communication. + *
+ */ +public class SimpleTCPSWalletProviderExample { + private static final String DB_URL = "(description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=your_db_host))(connect_data=(service_name=your_service_name))(security=(ssl_server_dn_match=yes)))"; + private static final String JDBC_URL = "jdbc:oracle:thin:@" + DB_URL; + private static final String USERNAME = "DB_USER"; + private static final String PASSWORD = "DB_PASSWORD"; + + + public static void main(String[] args) throws SQLException { + try { + OracleDataSource ds = new OracleDataSource(); + ds.setURL(JDBC_URL); + ds.setUser(USERNAME); + ds.setPassword(PASSWORD); + + Properties connectionProps = new Properties(); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration", + "ojdbc-provider-gcp-secretmanager-tls"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.secretVersionName", + "projects/{your-project-id}/secrets/{your-secret-name}/versions/{version-number}"); + connectionProps.put("oracle.jdbc.provider.tlsConfiguration.type","SSO"); + ds.setConnectionProperties(connectionProps); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleVaultSecretPasswordResourceExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleVaultSecretPasswordResourceExample.java new file mode 100644 index 00000000..a986dc28 --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/SimpleVaultSecretPasswordResourceExample.java @@ -0,0 +1,98 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from OCI Object Storage. + */ +public class SimpleVaultSecretPasswordResourceExample { + + private static final String DB_URL = "(description=(retry_count=2)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=adb.us-phoenix-1.oraclecloud.com))(connect_data=(service_name=gebqqvpozhjbqbs_awyonurbg0gp0smq_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))"; + private static final String RESOURCE_NAME = "projects/138028249883/secrets/test-secret/versions/2"; + + /** + *+ * Connects to a database using connection properties retrieved from GCP + * Object Storage. + *
+ *+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + */ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@" + DB_URL; + + // Standard JDBC code + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + ds.setUser("DB_USER"); + Properties properties = new Properties(); + properties.put("oracle.jdbc.provider.password", "ojdbc-provider-gcp-secretmanager-password"); + properties.put("oracle.jdbc.provider.password.secretVersionName", RESOURCE_NAME); + ds.setConnectionProperties(properties); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } + +} diff --git a/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/VaultSecretPasswordResourceExample.java b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/VaultSecretPasswordResourceExample.java new file mode 100644 index 00000000..57d74fed --- /dev/null +++ b/ojdbc-provider-samples/src/main/java/oracle/jdbc/provider/gcp/resource/VaultSecretPasswordResourceExample.java @@ -0,0 +1,105 @@ +/* + ** Copyright (c) 2024 Oracle and/or its affiliates. + ** + ** The Universal Permissive License (UPL), Version 1.0 + ** + ** Subject to the condition set forth below, permission is hereby granted to any + ** person obtaining a copy of this software, associated documentation and/or data + ** (collectively the "Software"), free of charge and under any and all copyright + ** rights in the Software, and any and all patent rights owned or freely + ** licensable by each licensor hereunder covering either (i) the unmodified + ** Software as contributed to or provided by such licensor, or (ii) the Larger + ** Works (as defined below), to deal in both + ** + ** (a) the Software, and + ** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + ** one is included with the Software (each a "Larger Work" to which the Software + ** is contributed by such licensors), + ** + ** without restriction, including without limitation the rights to copy, create + ** derivative works of, display, perform, and distribute the Software and make, + ** use, sell, offer for sale, import, export, have made, and have sold the + ** Software and the Larger Work(s), and to sublicense the foregoing rights on + ** either these or other terms. + ** + ** This license is subject to the following condition: + ** The above copyright notice and either this complete permission notice or at + ** a minimum a reference to the UPL must be included in all copies or + ** substantial portions of the Software. + ** + ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + ** SOFTWARE. + */ +package oracle.jdbc.provider.gcp.resource; + +import oracle.jdbc.datasource.impl.OracleDataSource; +import oracle.jdbc.provider.Configuration; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +/** + * A standalone example that configures Oracle JDBC to be provided with the + * connection properties retrieved from OCI Object Storage. + */ +public class VaultSecretPasswordResourceExample { + /** + * An GCP SecretManager resource name configured as a JVM system property, + * environment variable, or configuration.properties file entry named + * "gcp_secret_version_name". + */ + private static final String RESOURCE_NAME = Configuration + .getRequired("gcp_secret_version_name"); + + private static final String DB_URL = "(description=(retry_count=2)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=adb.us-phoenix-1.oraclecloud.com))(connect_data=(service_name=gebqqvpozhjbqbs_awyonurbg0gp0smq_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))"; + + /** + *+ * Connects to a database using connection properties retrieved from GCP + * Object Storage. + *
+ *+ * Providers use Google Cloud APIs which support Application Default + * Credentials; the libraries look for credentials in a set of defined + * locations and use those credentials to authenticate requests to the API. + *
+ * + * @see + * Application Default Credentials + * + * @param args the command line arguments + * @throws SQLException if an error occurs during the database calls + */ + public static void main(String[] args) throws SQLException { + String url = "jdbc:oracle:thin:@" + DB_URL; + + // Standard JDBC code + OracleDataSource ds = new OracleDataSource(); + ds.setURL(url); + ds.setUser("DB_USER"); + Properties properties = new Properties(); + properties.put("oracle.jdbc.provider.password", "ojdbc-provider-gcp-secretmanager-password"); + properties.put("oracle.jdbc.provider.password.secretVersionName", RESOURCE_NAME); + ds.setConnectionProperties(properties); + + try (Connection cn = ds.getConnection()) { + String connectionString = cn.getMetaData().getURL(); + System.out.println("Connected to: " + connectionString); + + Statement st = cn.createStatement(); + ResultSet rs = st.executeQuery("SELECT 'Hello, db' FROM sys.dual"); + if (rs.next()) + System.out.println(rs.getString(1)); + } + } + +} diff --git a/pom.xml b/pom.xml index d14264a2..2dc9d61c 100644 --- a/pom.xml +++ b/pom.xml @@ -62,6 +62,7 @@