Skip to content

Commit 6ce72a9

Browse files
committed
Rebase the branch and update the README.md
1 parent 6253891 commit 6ce72a9

File tree

12 files changed

+364
-258
lines changed

12 files changed

+364
-258
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Each module of this project contains a set of providers.
3030
<dt><a href="ojdbc-provider-jackson-oson/README.md">Oracle JDBC Jackson OSON</a></dt>
3131
<dd>Provider for <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/json-in-oracle-database.html#GUID-A8A58B49-13A5-4F42-8EA0-508951DAE0BB">OSON</a> through the JACKSON APIs.
3232
This provider can be used for seamless integration of applications that use the JACKSON APIs with the Oracle JSON type.</dd>
33+
<dt><a href="ojdbc-provider-pkl/README.md">Oracle JDBC Pkl Parser</a></dt>
34+
<dd>Parser for integration with Pkl that can be used by providers</dd>
3335
</dl>
3436
Visit any of the links above to learn about providers which are available for
3537
a particular platform.
@@ -144,6 +146,8 @@ this project:
144146

145147
[ojdbc-provider-jackson-oson](ojdbc-provider-jackson-oson/README.md#installation)
146148

149+
[ojdbc-provider-pkl](ojdbc-provider-pkl/README.md#installation)
150+
147151

148152
Each module listed above is distributed on the Maven Central Repository as a
149153
separate jar file. Coordinates can be found by visiting the links above.

ojdbc-provider-pkl/README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Oracle JDBC Configuration Provider Parser for Pkl
2+
3+
This module provides a parser that integrates **Oracle JDBC** with **Pkl**, a modern configuration language.
4+
It implements the `OracleConfigurationParser` interface to parse and read `.pkl` files for database configuration.
5+
6+
With the Oracle JDBC Pkl Parser, developers can store JDBC configurations in `.pkl` files and load them dynamically through Oracle JDBC Driver Extensions.
7+
8+
> **Note:** This parser works only with providers that extend `OracleConfigurationParsableProvider`, such as `file`, `https`, `ociobject`, `awss3`, and others.
9+
>
10+
## Installation
11+
12+
All providers in this module are distributed as single jar on the Maven Central
13+
Repository. The jar is compiled for JDK 8, and is forward compatible with later
14+
JDK versions. The coordinates for the latest release are:
15+
16+
```xml
17+
<dependency>
18+
<groupId>com.oracle.database.jdbc</groupId>
19+
<artifactId>ojdbc-provider-pkl</artifactId>
20+
<version>1.0.6</version>
21+
</dependency>
22+
```
23+
24+
## Usage
25+
26+
To use the Oracle JDBC Pkl Parser:
27+
28+
1. Prepare a .pkl configuration file (see examples below).
29+
2. Add this artifact to your application's classpath.
30+
3. Reference the .pkl file in the JDBC URL.
31+
32+
The parser type is inferred from the file extension. In this case, it’s "pkl".
33+
If the file name doesn’t include an extension, you can specify the parser explicitly using the parser option.
34+
All other options (like key, label, etc.) follow the same format as other providers.
35+
36+
Example using the file configuration provider:
37+
38+
```java
39+
jdbc:oracle:thin:@config-file://{pkl-file-name}[?parser=pkl&key=prefix&label=value&option1=value1&option2=value2...]
40+
```
41+
42+
## Writing .pkl Configuration
43+
44+
There are two approaches to filling out a template: **amends** and **import**.
45+
46+
### 1. Using `amends`
47+
48+
#### myJdbcConfig.pkl
49+
50+
```yaml
51+
amends "https://raw.githubusercontent.com/oracle/ojdbc-extensions/ojdbc-provider-pkl/src/main/resources/JdbcConfig.pkl"
52+
53+
connect_descriptor = "dbhost:1521/orclpdb1"
54+
user = "scott"
55+
56+
password {
57+
type = "ocivault"
58+
value = "ocid1.vaultsecret..."
59+
authentication {
60+
["method"] = "OCI_DEFAULT"
61+
}
62+
}
63+
64+
jdbc {
65+
autoCommit = false
66+
`oracle.jdbc.loginTimeout` = 60.s
67+
}
68+
```
69+
70+
#### URL (using file provider):
71+
72+
```java
73+
jdbc:oracle:thin:@config-file://myJdbcConfig.pkl
74+
```
75+
76+
### 2. Using `import`
77+
78+
#### myJdbcConfig.pkl
79+
80+
```yaml
81+
import "https://raw.githubusercontent.com/oracle/ojdbc-extensions/ojdbc-provider-pkl/src/main/resources/JdbcConfig.pkl"
82+
83+
config1 = (JdbcConfig) {
84+
connect_descriptor = "dbhost:1521/orclpdb1"
85+
86+
user = "scott"
87+
88+
password {
89+
type = "ocivault"
90+
value = "ocid1.vaultsecret..."
91+
authentication {
92+
["method"] = "OCI_DEFAULT"
93+
}
94+
}
95+
96+
jdbc {
97+
autoCommit = false
98+
`oracle.jdbc.loginTimeout` = 60.s
99+
}
100+
}
101+
```
102+
103+
#### URL (using file provider):
104+
105+
```java
106+
jdbc:oracle:thin:@config-file://myJdbcConfig.pkl?key=config1
107+
```

ojdbc-provider-pkl/pom.xml

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
<parent>
1111
<groupId>com.oracle.database.jdbc</groupId>
1212
<artifactId>ojdbc-extensions</artifactId>
13-
<version>${extensions-version}</version>
13+
<version>1.0.6</version>
1414
</parent>
1515

1616
<properties>
17-
<pkl.version>0.27.0</pkl.version>
17+
<pkl.version>0.30.0</pkl.version>
1818
<maven.compiler.source>17</maven.compiler.source>
1919
<maven.compiler.target>17</maven.compiler.target>
2020
</properties>
@@ -47,6 +47,13 @@
4747
<groupId>org.junit.jupiter</groupId>
4848
<artifactId>junit-jupiter-engine</artifactId>
4949
</dependency>
50+
<!-- TEST DEPENDENCIES -->
51+
<dependency>
52+
<groupId>com.oracle.database.jdbc</groupId>
53+
<artifactId>ojdbc-provider-common</artifactId>
54+
<classifier>tests</classifier>
55+
<type>test-jar</type>
56+
</dependency>
5057
</dependencies>
5158

5259
<build>
@@ -69,34 +76,16 @@
6976
</execution>
7077
</executions>
7178
</plugin>
72-
<!-- <plugin>-->
73-
<!-- &lt;!&ndash; Comment out this plugin for now. We only need to generate the Java class from pkl template only once. &ndash;&gt;-->
74-
<!-- &lt;!&ndash; There are some changes being made manually in the generated Java class. For example, replacing &ndash;&gt;-->
75-
<!-- &lt;!&ndash; dots (.) in variable names with double dollar sign ($$), since dot is illegal in Java variable names. &ndash;&gt;-->
76-
<!-- <groupId>org.codehaus.mojo</groupId>-->
77-
<!-- <artifactId>exec-maven-plugin</artifactId>-->
78-
<!-- <version>3.3.0</version>-->
79-
<!-- <executions>-->
80-
<!-- <execution>-->
81-
<!-- <goals>-->
82-
<!-- <goal>java</goal>-->
83-
<!-- </goals>-->
84-
<!-- <phase>initialize</phase>-->
85-
<!-- </execution>-->
86-
<!-- </executions>-->
87-
<!-- <configuration>-->
88-
<!-- <mainClass>org.pkl.codegen.java.Main</mainClass>-->
89-
<!-- <arguments>-->
90-
<!-- <argument>&#45;&#45;generate-javadoc</argument>-->
91-
<!-- <argument>-w</argument>-->
92-
<!-- <argument>${maven.multiModuleProjectDirectory}/ojdbc-provider-pkl</argument>-->
93-
<!-- <argument>-o</argument>-->
94-
<!-- <argument>${maven.multiModuleProjectDirectory}/ojdbc-provider-pkl/src/main</argument>-->
95-
<!-- <argument>src/main/resources/OjdbcConfig.pkl</argument>-->
96-
<!-- </arguments>-->
97-
<!-- </configuration>-->
98-
<!-- </plugin>-->
9979
</plugins>
80+
<resources>
81+
<resource>
82+
<directory>src/main/resources</directory>
83+
<includes>
84+
<include>**/*.pkl</include>
85+
<include>META-INF/services/oracle.jdbc.spi.*</include>
86+
</includes>
87+
</resource>
88+
</resources>
10089
</build>
10190

10291
</project>
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package oracle.jdbc.provider.pkl.configuration.parser;
1+
package oracle.jdbc.provider.pkl.configuration;
22

3-
import oracle.jdbc.provider.pkl.configuration.parser.generated.OjdbcConfig;
3+
import oracle.jdbc.provider.pkl.configuration.generated.JdbcConfig;
44
import oracle.jdbc.spi.OracleConfigurationParser;
55
import oracle.jdbc.spi.OracleConfigurationSecretProvider;
66
import org.pkl.config.java.Config;
@@ -10,15 +10,18 @@
1010
import org.pkl.core.ModuleSource;
1111
import org.pkl.core.PNull;
1212

13+
import java.io.BufferedReader;
1314
import java.io.IOException;
1415
import java.io.InputStream;
16+
import java.io.InputStreamReader;
1517
import java.lang.reflect.Field;
1618
import java.nio.charset.StandardCharsets;
1719
import java.sql.SQLException;
1820
import java.util.Base64;
1921
import java.util.HashMap;
2022
import java.util.Map;
2123
import java.util.Properties;
24+
import java.util.stream.Collectors;
2225

2326
import static oracle.jdbc.OracleConnection.CONNECTION_PROPERTY_PASSWORD;
2427
import static oracle.jdbc.OracleConnection.CONNECTION_PROPERTY_WALLET_LOCATION;
@@ -31,11 +34,12 @@ public Properties parse(
3134
Config pklConfig;
3235

3336
// Parse Pkl config from String
34-
try (ConfigEvaluator evaluator = ConfigEvaluator.preconfigured()) {
35-
String fileString = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
37+
try (ConfigEvaluator evaluator = ConfigEvaluator.preconfigured();
38+
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
39+
String fileString = reader.lines().collect(Collectors.joining("\n"));
3640
pklConfig = evaluator.evaluate(ModuleSource.text(fileString));
3741
} catch (IOException e) {
38-
throw new SQLException(e);
42+
throw new SQLException("Failed to parse input stream", e);
3943
}
4044

4145
// If key is present, we parse that pkl class
@@ -50,7 +54,7 @@ public Properties parse(
5054
}
5155

5256
// User common connect_descriptor as the URL
53-
OjdbcConfig ojdbcConfig = pklConfig.as(OjdbcConfig.class);
57+
JdbcConfig ojdbcConfig = pklConfig.as(JdbcConfig.class);
5458

5559
if (ojdbcConfig.connect_descriptor != null)
5660
properties.put("URL",
@@ -130,7 +134,7 @@ private Config getOptional(Config node, String s) {
130134
return null;
131135
}
132136

133-
private Map<String, String> toSecretMap(OjdbcConfig.Secret secretConfig) {
137+
private Map<String, String> toSecretMap(JdbcConfig.Secret secretConfig) {
134138
// Convert Pkl config to map
135139
Map<String, String> options = new HashMap<>();
136140
options.put("value", secretConfig.value);
@@ -145,7 +149,7 @@ private Map<String, String> toSecretMap(OjdbcConfig.Secret secretConfig) {
145149
return options;
146150
}
147151

148-
private Properties toJdbcProperties(OjdbcConfig.Jdbc ojdbcConfig)
152+
private Properties toJdbcProperties(JdbcConfig.Jdbc ojdbcConfig)
149153
throws IllegalAccessException {
150154

151155
Properties properties = new Properties();
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package oracle.jdbc.provider.pkl.configuration.parser.generated;
1+
package oracle.jdbc.provider.pkl.configuration.generated;
22

33
import java.lang.Boolean;
44
import java.lang.Long;
@@ -20,7 +20,7 @@
2020
* Generator so the changes are made manually for now. The good thing is that
2121
* this is a one-time process.
2222
*/
23-
public final class OjdbcConfig {
23+
public final class JdbcConfig {
2424
public final @NonNull String connect_descriptor;
2525

2626
public final String user;
@@ -33,10 +33,10 @@ public final class OjdbcConfig {
3333

3434
public final Duration config_time_to_live;
3535

36-
public OjdbcConfig(@Named("connect_descriptor") @NonNull String connect_descriptor,
37-
@Named("user") String user, @Named("password") Secret password,
38-
@Named("wallet_location") Secret wallet_location, @Named("jdbc") Jdbc jdbc,
39-
@Named("config_time_to_live") Duration config_time_to_live) {
36+
public JdbcConfig(@Named("connect_descriptor") @NonNull String connect_descriptor,
37+
@Named("user") String user, @Named("password") Secret password,
38+
@Named("wallet_location") Secret wallet_location, @Named("jdbc") Jdbc jdbc,
39+
@Named("config_time_to_live") Duration config_time_to_live) {
4040
this.connect_descriptor = connect_descriptor;
4141
this.user = user;
4242
this.password = password;
@@ -45,36 +45,36 @@ public OjdbcConfig(@Named("connect_descriptor") @NonNull String connect_descript
4545
this.config_time_to_live = config_time_to_live;
4646
}
4747

48-
public OjdbcConfig withConnect_descriptor(@NonNull String connect_descriptor) {
49-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
48+
public JdbcConfig withConnect_descriptor(@NonNull String connect_descriptor) {
49+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
5050
}
5151

52-
public OjdbcConfig withUser(String user) {
53-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
52+
public JdbcConfig withUser(String user) {
53+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
5454
}
5555

56-
public OjdbcConfig withPassword(Secret password) {
57-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
56+
public JdbcConfig withPassword(Secret password) {
57+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
5858
}
5959

60-
public OjdbcConfig withWallet_location(Secret wallet_location) {
61-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
60+
public JdbcConfig withWallet_location(Secret wallet_location) {
61+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
6262
}
6363

64-
public OjdbcConfig withJdbc(Jdbc jdbc) {
65-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
64+
public JdbcConfig withJdbc(Jdbc jdbc) {
65+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
6666
}
6767

68-
public OjdbcConfig withConfig_time_to_live(Duration config_time_to_live) {
69-
return new OjdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
68+
public JdbcConfig withConfig_time_to_live(Duration config_time_to_live) {
69+
return new JdbcConfig(connect_descriptor, user, password, wallet_location, jdbc, config_time_to_live);
7070
}
7171

7272
@Override
7373
public boolean equals(Object obj) {
7474
if (this == obj) return true;
7575
if (obj == null) return false;
7676
if (this.getClass() != obj.getClass()) return false;
77-
OjdbcConfig other = (OjdbcConfig) obj;
77+
JdbcConfig other = (JdbcConfig) obj;
7878
if (!Objects.equals(this.connect_descriptor, other.connect_descriptor)) return false;
7979
if (!Objects.equals(this.user, other.user)) return false;
8080
if (!Objects.equals(this.password, other.password)) return false;
@@ -99,7 +99,7 @@ public int hashCode() {
9999
@Override
100100
public String toString() {
101101
StringBuilder builder = new StringBuilder(350);
102-
builder.append(OjdbcConfig.class.getSimpleName()).append(" {");
102+
builder.append(JdbcConfig.class.getSimpleName()).append(" {");
103103
appendProperty(builder, "connect_descriptor", this.connect_descriptor);
104104
appendProperty(builder, "user", this.user);
105105
appendProperty(builder, "password", this.password);
@@ -126,8 +126,9 @@ public static final class Secret {
126126

127127
public final Map<@NonNull String, @NonNull String> authentication;
128128

129-
public Secret(@Named("type") @NonNull String type, @Named("value") @NonNull String value,
130-
@Named("authentication") Map<@NonNull String, @NonNull String> authentication) {
129+
public Secret(@Named("type") @NonNull String type,
130+
@Named("value") @NonNull String value,
131+
@Named("authentication") Map<@NonNull String, @NonNull String> authentication) {
131132
this.type = type;
132133
this.value = value;
133134
this.authentication = authentication;

0 commit comments

Comments
 (0)