public interface OracleResourceProvider
A provider of resources that are consumed by the Oracle JDBC Driver.
The OracleResourceProvider
interface defines methods that are common
to all resource providers. Interfaces in the oracle.jdbc.spi
package
extend OracleResourceProvider
to provide a particular type of
resource:
ConnectionStringProvider
UsernameProvider
PasswordProvider
TlsConfigurationProvider
AccessTokenProvider
TraceEventListenerProvider
Interfaces that extend OracleResourceProvider
define a Service
Provider Interface (SPI). Oracle JDBC locates implementations of these
interfaces using ServiceLoader
.
A provider is installed by including its implementation in the class
path or module path of a JVM. Programmers who implement a provider must
meet the requirements defined by ServiceLoader
for deploying service
providers on the class path or module path.
A provider is identified by setting one of the following connection properties to the name of a provider:
Connection Property | Provider Type |
---|---|
oracle.jdbc.provider.connectionString | Identifies a ConnectionStringProvider |
oracle.jdbc.provider.username | Identifies a UsernameProvider |
oracle.jdbc.provider.password | Identifies a PasswordProvider |
oracle.jdbc.provider.accessToken | Identifies an AccessTokenProvider |
oracle.jdbc.provider.tlsConfiguration | Identifies a TlsConfigurationProvider |
oracle.jdbc.provider.traceEventListener | Identifies a TraceEventListenerProvider |
A provider may support one or more parameters that configure its behavior.
Each individual implementation of OracleResourceProvider
defines the
set of parameters it supports, if any. These parameters may be queried by
calling getParameters()
.
A parameter is configured as a connection property by appending its name to the name of a connection property that identifies a provider. For example, the following connection properties would configure the "user_id" parameter of a password provider:
oracle.jdbc.provider.password=example-password-provider oracle.jdbc.provider.password.user_id=99The names of parameters are case-insensitive. In the example above, changing "user_id" to "USER_ID" would configure the same parameter.
Connection properties in the oracle.jdbc.provider
namespace may be
configured using any programmatic API that accepts connection properties, or
using an
connection properties file
. These properties can not be set as JVM system properties.
Tools and applications may call
OracleDriver.getPropertyInfo(String, Properties)
to retrieve
information about installed providers at runtime.
The getPropertyInfo
method returns a
DriverPropertyInfo
object for each
connection property that identifies a provider
.
The DriverPropertyInfo.choices
field of these objects
contains the name of each provider that is installed and
that may be identified by the property. If the Properties
argument to
getPropertyInfo
already contains an entry that identifies a provider,
a DriverPropertyInfo
object is returned for each connection property
that
configures a parameter of that provider
.
Oracle JDBC locates providers and requests resources from them
each time a Connection
is created. Providers are
located using the class loader of
the thread which creates a connection.
Oracle JDBC does not cache resources. Providers may implement their own caching strategy when it makes sense to do so.
If the request for a resource fails, Oracle JDBC throws a
SQLException
with the ORA-18726 error code. The
cause of the
SQLException
may convey additional information about the failure.
Oracle JDBC will often support alternative methods for configuring a
provided resource. For instance, a password may be configured with the
"oracle.jdbc.password" property, or may be passed as an argument to
DataSource.getConnection(String, String)
. A resource is
only requested from a provider if no alternative method has configured it.
The JavaDoc of each
connection property that identifies a provider
specifies any alternative configuration methods that will override a
provider.
Interfaces in the oracle.jdbc.spi
package that extend
OracleResourceProvider
are intended to have user
defined implementations. User defined implementations may provide resources
from a specialized process which Oracle JDBC does not support otherwise.
Programmers who implement these interfaces must adhere to their specification. The specification is defined by the class level and method level JavaDocs of these interfaces. Oracle JDBC will raise a error if a provider is not implemented according to this specification.
Thread safety is not strictly required. Oracle JDBC uses
ServiceLoader.load(Class)
to obtain an instance of
a provider each time a new Connection
is created.
The instance that ServiceLoader
locates is not shared with any other
thread that creates a Connection
. If each call to
ServiceLoader.load(Class)
returns a new instance, then concurrent
access to the same instance is not possible.
An example of a specialized process that a provider might implement is to
request a password from a password management service. In the following code
example, the PasswordProvider
interface is implemented using the SDK
of a fictional password management service:
import com.example.PasswordRequest; import com.example.PasswordService; import oracle.jdbc.spi.PasswordProvider; import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Objects; public class ExamplePasswordProvider implements PasswordProvider { @Override public String getName() { return "example-password-provider"; } @Override public Collection<Parameter> getParameters() { return Arrays.asList(ProviderParameter.values()); } @Override public char[] getPassword(Map<Parameter, CharSequence> parameters) { Objects.requireNonNull(parameters, "parameters is null"); PasswordRequest request = createRequest(parameters); char[] password = PasswordService.requestPassword(request); return password; } private PasswordRequest createRequest(Map<Parameter, CharSequence> parameters) { PasswordRequest.Builder requestBuilder = PasswordRequest.builder(); for (Map.Entry<Parameter, CharSequence> entry : parameters.entrySet()) { Parameter parameter = entry.getKey(); if (!(parameter instanceof ProviderParameter)) { throw new IllegalArgumentException( "Unrecognized parameter: " + parameter); } ProviderParameter providerParameter = (ProviderParameter)parameter; providerParameter.configureBuilder(requestBuilder, entry.getValue()); } return requestBuilder.build(); } private enum ProviderParameter implements Parameter { USER_ID { @Override public String description() { return "The ID of a user that accesses the password management service."; } @Override public boolean isSensitive() { return false; } @Override public boolean isRequired() { return true; } @Override void configureBuilder( PasswordRequest.Builder builder, CharSequence value) { String userId = value.toString(); builder.userId(userId); } }, IS_CACHE_ENABLED { @Override public String description() { return "Set to a value other than \"true\" to disable caching of passwords"; } @Override public boolean isSensitive() { return false; } @Override public String defaultValue() { return "true"; } @Override void configureBuilder(PasswordRequest.Builder builder, CharSequence value) { boolean isCacheEnabled = Boolean.parseBoolean(value.toString()); builder.isCacheEnabled(isCacheEnabled); } }; abstract void configureBuilder( PasswordRequest.Builder builder, CharSequence value); } }
The example above demonstrates the key functions of an
OracleResourceProvider
:
getName()
to
identify itself by the name "example-password-provider".
getParameters()
to define the parameters that configure it.
PasswordProvider.getPassword(Map)
by adapting a specialized
process to the PasswordProvider
interface. In this example,
the specialized process is the usage of an SDK for the password
management service.
The example provider implements the PasswordProvider
interface.
Oracle JDBC locates implementations of this interface by calling
ServiceLoader.load(PasswordProvider.class).
ServiceLoader
instantiates ExamplePasswordProvider
if the
class name is declared with a
META-INF/services/oracle.jdbc.spi.PasswordProvider
file, or with a
module-info.java
file having the
"provides oracle.jdbc.spi.PasswordProvider
" directive. A full
specification of how providers are located and instantiated can be found in
the JavaDoc of the ServiceLoader
class.
Implementations of OracleResourceProvider
may define parameters that
can be configured as connection properties. Defining parameters is optional.
A provider may implement getParameters()
to return an empty
Collection
if it does not support any parameters.
If a provider defines parameters, then it must implement the
Parameter
interface to describe the attributes of each parameter.
These attributes effect how Oracle JDBC will process the parameter, and may
also be utilized by database tools.
Parameter
must implement OracleResourceProvider.Parameter.name()
to identify the
parameter. The name may be used to configure the parameter as a connection
property. Where a connection property named "X" identifies a provider, and
the provider defines a parameter named "Y", a connection property named
"X.Y" configures that parameter. To illustrate, the example provider
implementation defines parameters named "user_id" and "is_cache_enabled".
When this provider is identified by the "oracle.jdbc.provider.password"
connection property, its parameters may be configured as shown below:
oracle.jdbc.provider.password=example-password-provider oracle.jdbc.provider.password.user_id=99 oracle.jdbc.provider.password.is_cache_enabled=false
Parameter
must implement OracleResourceProvider.Parameter.isSensitive()
to return
true
if the value of that parameter contains security sensitive
information. Oracle JDBC will handle the value of a security sensitive
parameter in the same way it handles a password: The value won't appear in
log messages, error messages, or memory dumps.
Parameter
may implement OracleResourceProvider.Parameter.description()
to return
a human readable summary of the parameter's effect, and the range of values
it may be set to. A database tool may display this description to a user.
OracleResourceProvider.Parameter.defaultValue()
to return its
default value. The default implementation of defaultValue
returns
null
, signifying that there is no default value for that parameter.
Oracle JDBC populates the Map<Parameter, CharSequence>
it passes to
a provider with the default value of any parameter that is not configured by
a connection property. Oracle JDBC will treat default values as security
sensitive if isSensitive()
returns true
.
OracleResourceProvider.Parameter.isRequired()
to return
true
if a provider requires that parameter to be set. The default
implementation of isRequired()
returns false
. Oracle JDBC
throws a SQLException
if no value is configured for a
required parameter, and that parameter has no default value.
Modifier and Type | Interface and Description |
---|---|
static interface |
OracleResourceProvider.Parameter
A parameter that configures an
OracleResourceProvider . |
Modifier and Type | Method and Description |
---|---|
java.lang.String |
getName()
Returns the name of this provider.
|
default java.util.Collection<? extends OracleResourceProvider.Parameter> |
getParameters()
Returns a collection of parameters that configure this provider, if any.
|
java.lang.String getName()
Returns the name of this provider.
default java.util.Collection<? extends OracleResourceProvider.Parameter> getParameters()
Returns a collection of parameters that configure this provider, if any.