Skip to content

Commit 16894da

Browse files
Adding AWS Parameter Store Configuration Provider (#172)
1 parent 4a1ed4c commit 16894da

File tree

11 files changed

+515
-4
lines changed

11 files changed

+515
-4
lines changed

ojdbc-provider-aws/README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Provider</a></dt>
1212
<dt><a href="#aws-secrets-manager-config-provider">AWS Secrets Manager Configuration
1313
Provider</a></dt>
1414
<dd>Provides connection properties managed by the Secrets Manager service</dd>
15+
<dt><a href="#aws-parameter-store-config-provider">AWS Parameter Store Configuration
16+
Provider</a></dt>
17+
<dd>Provides connection properties managed by the Systems Manager Parameter Store</dd>
1518
<dt><a href="#common-parameters-for-centralized-config-providers">Common Parameters for Centralized Config Providers</a></dt>
1619
<dd>Common parameters supported by the config providers</dd>
1720
<dt><a href="#caching-configuration">Caching configuration</a></dt>
@@ -121,7 +124,7 @@ The sample code below executes as expected with the previous configuration.
121124

122125
### Password JSON Object
123126

124-
For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) the password is an object itself with the following spec:
127+
For the JSON type of provider (AWS S3, AWS Secrets Manager, AWS Parameter Store, HTTP/HTTPS, File) the password is an object itself with the following spec:
125128

126129
- `type`
127130
- Mandatory
@@ -130,6 +133,7 @@ For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) th
130133
- `azurevault` (Azure Key Vault)
131134
- `base64` (Base64)
132135
- `awssecretsmanager` (AWS Secrets Manager)
136+
- `awsparameterstore` (AWS Parameter Store)
133137
- `hcpvaultdedicated` (HCP Vault Dedicated)
134138
- `hcpvaultsecret` (HCP Vault Secrets)
135139
- `gcpsecretmanager` (GCP Secret Manager)
@@ -140,6 +144,7 @@ For the JSON type of provider (AWS S3, AWS Secrets Manager, HTTP/HTTPS, File) th
140144
- Azure Key Vault URI (if azurevault)
141145
- Base64 Encoded password (if base64)
142146
- AWS Secret name (if awssecretsmanager)
147+
- AWS Parameter name (if awsparameterstore)
143148
- Secret path (if hcpvaultdedicated)
144149
- Secret name (if hcpvaultsecret)
145150
- Secret name (if gcpsecretmanager)
@@ -191,6 +196,16 @@ jdbc:oracle:thin:@config-awssecretsmanager://{secret-name}
191196

192197
The JSON Payload retrieved by AWS Secrets Manager Provider follows the same format in [AWS S3 Configuration Provider](#json-payload-format).
193198

199+
## AWS Parameter Store Config Provider
200+
Apart from AWS S3 and Secrets Manager, users can also store JSON payload in AWS Systems Manager Parameter Store.
201+
To use it, specify the name of the parameter:
202+
203+
<pre>
204+
jdbc:oracle:thin:@config-awsparameterstore://{parameter-name}
205+
</pre>
206+
207+
The JSON payload stored in the parameter should follow the same format as described in [AWS S3 Configuration Provider](#json-payload-format).
208+
194209
## Common Parameters for Centralized Config Providers
195210
AWS S3 Configuration Provider and AWS Secrets Manager Configuration Provider
196211
share the same sets of parameters for authentication configuration.

ojdbc-provider-aws/example-test.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ AWS_S3_URL=jdbc:oracle:thin:@config-awss3://...
8787
# The URL to test with the AWS Secrets Manager Configuration Provider
8888
AWS_SECRETS_MANAGER_URL=jdbc:oracle:thin:@config-awssecretsmanager://...
8989

90+
# The URL to test with the AWS Parameter Store Configuration Provider
91+
AWS_PARAMETER_STORE_URL=jdbc:oracle:thin:@config-awsparameterstore://...
9092
# The name of an AWS Secrets Manager secret
9193
AWS_USERNAME_SECRET_NAME=example-name
9294

ojdbc-provider-aws/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
<groupId>software.amazon.awssdk</groupId>
6767
<artifactId>secretsmanager</artifactId>
6868
</dependency>
69+
<dependency>
70+
<groupId>software.amazon.awssdk</groupId>
71+
<artifactId>ssm</artifactId>
72+
</dependency>
6973
<!-- TEST DEPENDENCIES -->
7074
<dependency>
7175
<groupId>com.oracle.database.jdbc</groupId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
** Copyright (c) 2025 Oracle and/or its affiliates.
3+
**
4+
** The Universal Permissive License (UPL), Version 1.0
5+
**
6+
** Subject to the condition set forth below, permission is hereby granted to any
7+
** person obtaining a copy of this software, associated documentation and/or data
8+
** (collectively the "Software"), free of charge and under any and all copyright
9+
** rights in the Software, and any and all patent rights owned or freely
10+
** licensable by each licensor hereunder covering either (i) the unmodified
11+
** Software as contributed to or provided by such licensor, or (ii) the Larger
12+
** Works (as defined below), to deal in both
13+
**
14+
** (a) the Software, and
15+
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
** one is included with the Software (each a "Larger Work" to which the Software
17+
** is contributed by such licensors),
18+
**
19+
** without restriction, including without limitation the rights to copy, create
20+
** derivative works of, display, perform, and distribute the Software and make,
21+
** use, sell, offer for sale, import, export, have made, and have sold the
22+
** Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
** either these or other terms.
24+
**
25+
** This license is subject to the following condition:
26+
** The above copyright notice and either this complete permission notice or at
27+
** a minimum a reference to the UPL must be included in all copies or
28+
** substantial portions of the Software.
29+
**
30+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
** SOFTWARE.
37+
*/
38+
39+
package oracle.jdbc.provider.aws.configuration;
40+
41+
import oracle.jdbc.provider.aws.parameterstore.ParameterStoreFactory;
42+
import oracle.jdbc.provider.parameter.ParameterSet;
43+
import oracle.jdbc.spi.OracleConfigurationSecretProvider;
44+
45+
import java.util.Base64;
46+
import java.util.Map;
47+
48+
import static oracle.jdbc.provider.aws.configuration.AwsParameterStoreConfigurationProvider.PARAMETER_SET_PARSER;
49+
50+
public class AwsJsonParameterStoreProvider
51+
implements OracleConfigurationSecretProvider {
52+
53+
/**
54+
* {@inheritDoc}
55+
* <p>
56+
* Returns the value of the parameter retrieved from AWS Systems Manager
57+
* Parameter Store.
58+
* </p>
59+
* <p>
60+
* The {@code jsonObject} is expected to be in the following form:
61+
* </p>
62+
*
63+
* <pre>{@code
64+
* "password": {
65+
* "type": "awsparameterstore",
66+
* "value": "/my-app/database-password"
67+
* }
68+
* }</pre>
69+
*
70+
* <p>
71+
* The provider retrieves the parameter specified by the {@code value} field
72+
* from AWS Parameter Store, then encodes it as a Base64 string.
73+
* The encoded value is returned as a {@code char[]} for use with Oracle JDBC's
74+
* centralized configuration.
75+
* </p>
76+
*
77+
* @param map Map object containing key-value pairs parsed from the JSON configuration.
78+
* @return Base64-encoded {@code char[]} representing the retrieved secret value.
79+
*/
80+
@Override
81+
public char[] getSecret(Map<String, String> map) {
82+
ParameterSet parameterSet = PARAMETER_SET_PARSER.parseNamedValues(map);
83+
84+
String parameterValue = ParameterStoreFactory.getInstance()
85+
.request(parameterSet)
86+
.getContent();
87+
88+
return Base64.getEncoder()
89+
.encodeToString(parameterValue.getBytes())
90+
.toCharArray();
91+
}
92+
93+
@Override
94+
public String getSecretType() {
95+
return "awsparameterstore";
96+
}
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
** Copyright (c) 2025 Oracle and/or its affiliates.
3+
**
4+
** The Universal Permissive License (UPL), Version 1.0
5+
**
6+
** Subject to the condition set forth below, permission is hereby granted to any
7+
** person obtaining a copy of this software, associated documentation and/or data
8+
** (collectively the "Software"), free of charge and under any and all copyright
9+
** rights in the Software, and any and all patent rights owned or freely
10+
** licensable by each licensor hereunder covering either (i) the unmodified
11+
** Software as contributed to or provided by such licensor, or (ii) the Larger
12+
** Works (as defined below), to deal in both
13+
**
14+
** (a) the Software, and
15+
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
** one is included with the Software (each a "Larger Work" to which the Software
17+
** is contributed by such licensors),
18+
**
19+
** without restriction, including without limitation the rights to copy, create
20+
** derivative works of, display, perform, and distribute the Software and make,
21+
** use, sell, offer for sale, import, export, have made, and have sold the
22+
** Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
** either these or other terms.
24+
**
25+
** This license is subject to the following condition:
26+
** The above copyright notice and either this complete permission notice or at
27+
** a minimum a reference to the UPL must be included in all copies or
28+
** substantial portions of the Software.
29+
**
30+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36+
** SOFTWARE.
37+
*/
38+
39+
package oracle.jdbc.provider.aws.configuration;
40+
41+
import oracle.jdbc.driver.configuration.OracleConfigurationParsableProvider;
42+
import oracle.jdbc.provider.aws.parameterstore.ParameterStoreFactory;
43+
import oracle.jdbc.provider.parameter.Parameter;
44+
import oracle.jdbc.provider.parameter.ParameterSet;
45+
import oracle.jdbc.provider.parameter.ParameterSetParser;
46+
import oracle.jdbc.util.OracleConfigurationCache;
47+
48+
import java.io.ByteArrayInputStream;
49+
import java.io.InputStream;
50+
import java.util.HashMap;
51+
import java.util.Map;
52+
53+
import static oracle.jdbc.provider.aws.configuration.AwsConfigurationParameters.KEY;
54+
import static oracle.jdbc.provider.aws.configuration.AwsConfigurationParameters.REGION;
55+
56+
/**
57+
* A provider for JSON payload which contains configuration from AWS Systems
58+
* Manager Parameter Store.
59+
* See {@link #getInputStream(String)} for the spec of the JSON payload.
60+
**/
61+
public class AwsParameterStoreConfigurationProvider
62+
extends OracleConfigurationParsableProvider {
63+
64+
static final ParameterSetParser PARAMETER_SET_PARSER =
65+
AwsConfigurationParameters.configureBuilder(
66+
ParameterSetParser.builder()
67+
.addParameter("value", ParameterStoreFactory.PARAMETER_NAME)
68+
.addParameter("key", KEY)
69+
.addParameter("type", Parameter.create())
70+
.addParameter("AWS_REGION", REGION)
71+
).build();
72+
73+
/**
74+
* {@inheritDoc}
75+
* <p>
76+
* Returns the JSON payload stored in AWS Systems Manager Parameter Store.
77+
* </p>
78+
*
79+
* @param parameterName name of the secret
80+
* @return JSON payload
81+
*/
82+
@Override
83+
public InputStream getInputStream(String parameterName) {
84+
// The JSON “value” field holds the Parameter Store name
85+
final String VALUE = "value";
86+
Map<String, String> opts = new HashMap<>(options);
87+
opts.put(VALUE, parameterName);
88+
89+
ParameterSet params = PARAMETER_SET_PARSER.parseNamedValues(opts);
90+
String json = ParameterStoreFactory.getInstance()
91+
.request(params)
92+
.getContent();
93+
94+
return new ByteArrayInputStream(json.getBytes());
95+
}
96+
97+
@Override
98+
public String getType() {
99+
return "awsparameterstore";
100+
}
101+
102+
/**
103+
* {@inheritDoc}
104+
* @return cache of this provider which is used to store configuration
105+
*/
106+
@Override
107+
public OracleConfigurationCache getCache() {
108+
return CACHE;
109+
}
110+
111+
/**
112+
* {@inheritDoc}
113+
* @return the parser type
114+
*/
115+
@Override
116+
public String getParserType(String location) {
117+
return "json";
118+
}
119+
}

0 commit comments

Comments
 (0)