Skip to content

Commit a6a8038

Browse files
committed
Open source the Data Cloud JDBC driver
1 parent c7a1302 commit a6a8038

File tree

202 files changed

+28086
-256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+28086
-256
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* text=auto eol=lf
2+
*.java text diff=java

.github/workflows/build.yml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Build and test
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 2
16+
- name: Set up JDK 11
17+
uses: actions/setup-java@v4
18+
with:
19+
java-version: '11'
20+
distribution: 'temurin'
21+
cache: maven
22+
- name: Get hyperd version
23+
id: evaluate-property
24+
run: |
25+
echo "HYPER_VERSION=$(mvn help:evaluate -Dexpression=hyperapi.version -q -DforceStdout)" >> $GITHUB_ENV
26+
- name: Cache hyperd
27+
uses: actions/cache@v3
28+
with:
29+
path: |
30+
target/.cache
31+
key: ${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
32+
restore-keys: |
33+
${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
34+
- name: Maven package
35+
run: mvn --batch-mode --no-transfer-progress clean package --file pom.xml

.github/workflows/release.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Release to staging
2+
3+
on:
4+
release:
5+
types: [ "created" ]
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Set up JDK 11
14+
uses: actions/setup-java@v4
15+
with:
16+
java-version: '11'
17+
distribution: 'temurin'
18+
server-id: ossrh
19+
server-username: 'MAVEN_USERNAME'
20+
server-password: 'MAVEN_PASSWORD'
21+
gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }}
22+
gpg-passphrase: 'MAVEN_GPG_PASSPHRASE'
23+
- name: Get hyperd version
24+
id: evaluate-property
25+
run: |
26+
echo "HYPER_VERSION=$(mvn help:evaluate -Dexpression=hyperapi.version -q -DforceStdout)" >> $GITHUB_ENV
27+
- name: Cache hyperd
28+
uses: actions/cache@v3
29+
with:
30+
path: |
31+
target/.cache
32+
key: ${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
33+
restore-keys: |
34+
${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
35+
- name: Set version
36+
run: mvn versions:set --no-transfer-progress -DnewVersion=${{ github.event.release.tag_name }}
37+
- name: Build with Maven
38+
run: mvn --batch-mode --no-transfer-progress clean deploy -P release --file pom.xml
39+
env:
40+
MAVEN_USERNAME: ${{ secrets.CENTRAL_TOKEN_USERNAME }}
41+
MAVEN_PASSWORD: ${{ secrets.CENTRAL_TOKEN_PASSWORD }}
42+
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }}

.gitignore

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.idea
2+
!.idea/externalDependencies.xml
3+
!.idea/palantir-java-format.xml
4+
5+
.DS_Store
6+
7+
target/
8+
pom.xml.tag
9+
pom.xml.releaseBackup
10+
pom.xml.versionsBackup
11+
pom.xml.next
12+
release.properties
13+
dependency-reduced-pom.xml
14+
buildNumber.properties
15+
.mvn/timing.properties
16+
.mvn/wrapper/maven-wrapper.jar
17+
.project
18+
.classpath
19+
src/main/resources/config/config.properties
20+
21+
*.iml
22+
pom.xml.bak

.hooks/pre-commit

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
echo '[git pre-commit] mvn spotless:apply sortpom:sort'
5+
MAVEN_OPTS='-Dorg.slf4j.simpleLogger.defaultLogLevel=error' mvn spotless:apply sortpom:sort
6+
git add --update

.idea/externalDependencies.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/palantir-java-format.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CODEOWNERS

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# Comment line immediately above ownership line is reserved for related other information. Please be careful while editing.
2-
#ECCN:Open Source
3-
#GUSINFO:Open Source,Open Source Workflow
2+
#ECCN: 5D002.c.1
3+
#GUSINFO:Open Source,Open Source Workflow
4+
* datacloud-query-connector-owners@salesforce.com

CONTRIBUTING.md

+6-25
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,27 @@
1-
*This is a suggested `CONTRIBUTING.md` file template for use by open sourced Salesforce projects. The main goal of this file is to make clear the intents and expectations that end-users may have regarding this project and how/if to engage with it. Adjust as needed (especially look for `{project_slug}` which refers to the org and repo name of your project) and remove this paragraph before committing to your repo.*
1+
# Contributing Guide For Data Cloud JDBC Driver
22

3-
# Contributing Guide For {NAME OF PROJECT}
4-
5-
This page lists the operational governance model of this project, as well as the recommendations and requirements for how to best contribute to {PROJECT}. We strive to obey these as best as possible. As always, thanks for contributing – we hope these guidelines make it easier and shed some light on our approach and processes.
3+
This page lists the operational governance model of this project, as well as the recommendations and requirements for how to best contribute to Data Cloud JDBC Driver. We strive to obey these as best as possible. As always, thanks for contributing – we hope these guidelines make it easier and shed some light on our approach and processes.
64

75
# Governance Model
8-
> Pick the most appropriate one
9-
10-
## Community Based
11-
12-
The intent and goal of open sourcing this project is to increase the contributor and user base. The governance model is one where new project leads (`admins`) will be added to the project based on their contributions and efforts, a so-called "do-acracy" or "meritocracy" similar to that used by all Apache Software Foundation projects.
13-
14-
> or
156

167
## Salesforce Sponsored
178

189
The intent and goal of open sourcing this project is to increase the contributor and user base. However, only Salesforce employees will be given `admin` rights and will be the final arbitrars of what contributions are accepted or not.
1910

20-
> or
21-
22-
## Published but not supported
23-
24-
The intent and goal of open sourcing this project is because it may contain useful or interesting code/concepts that we wish to share with the larger open source community. Although occasional work may be done on it, we will not be looking for or soliciting contributions.
25-
26-
# Getting started
27-
28-
Please join the community on {Here list Slack channels, Email lists, Glitter, Discord, etc... links}. Also please make sure to take a look at the project [roadmap](ROADMAP.md) to see where are headed.
29-
3011
# Issues, requests & ideas
3112

3213
Use GitHub Issues page to submit issues, enhancement requests and discuss ideas.
3314

3415
### Bug Reports and Fixes
35-
- If you find a bug, please search for it in the [Issues](https://github.com/{project_slug}/issues), and if it isn't already tracked,
36-
[create a new issue](https://github.com/{project_slug}/issues/new). Fill out the "Bug Report" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still
16+
- If you find a bug, please search for it in the [Issues](https://github.com/forcedotcom/datacloud-jdbc/issues), and if it isn't already tracked,
17+
[create a new issue](https://github.com/forcedotcom/datacloud-jdbc/issues/new). Fill out the "Bug Report" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still
3718
be reviewed.
3819
- Issues that have already been identified as a bug (note: able to reproduce) will be labelled `bug`.
3920
- If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number.
4021
- Include tests that isolate the bug and verifies that it was fixed.
4122

4223
### New Features
43-
- If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/{project_slug}/issues/new).
24+
- If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/forcedotcom/datacloud-jdbc/issues/new).
4425
- Issues that have been identified as a feature request will be labelled `enhancement`.
4526
- If you'd like to implement the new feature, please wait for feedback from the project
4627
maintainers before spending too much time writing the code. In some cases, `enhancement`s may
@@ -51,7 +32,7 @@ Use GitHub Issues page to submit issues, enhancement requests and discuss ideas.
5132
alternative implementation of something that may have advantages over the way its currently
5233
done, or you have any other change, we would be happy to hear about it!
5334
- If its a trivial change, go ahead and [send a Pull Request](#creating_a_pull_request) with the changes you have in mind.
54-
- If not, [open an Issue](https://github.com/{project_slug}/issues/new) to discuss the idea first.
35+
- If not, [open an Issue](https://github.com/forcedotcom/datacloud-jdbc/issues/new) to discuss the idea first.
5536

5637
If you're new to our project and looking for some way to make your first contribution, look for
5738
Issues labelled `good first contribution`.

LICENSE.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ Apache License
191191
same "printed page" as the copyright notice for easier
192192
identification within third-party archives.
193193

194-
Copyright {yyyy} {name of copyright owner}
194+
Copyright 2024 Salesforce
195195

196196
Licensed under the Apache License, Version 2.0 (the "License");
197197
you may not use this file except in compliance with the License.

README.md

+172-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,178 @@
1-
# README
1+
# Salesforce DataCloud JDBC Driver
22

3-
A repo containing all the basic file templates and general guidelines for any open source project at Salesforce.
3+
With the Salesforce Data Cloud JDBC driver you can efficiently query millions of rows of data with low latency, and perform bulk data extractions.
4+
This driver is read-only and forward-only.
5+
It requires Java 11 or greater.
6+
7+
8+
## Getting started
9+
10+
To add the driver to your project, add the following Maven dependency:
11+
12+
```xml
13+
<dependency>
14+
<groupId>com.salesforce.datacloud</groupId>
15+
<artifactId>jdbc</artifactId>
16+
<version>${jdbc.version}</version>
17+
</dependency>
18+
```
19+
20+
The class name for this driver is:
21+
22+
```
23+
com.salesforce.datacloud.jdbc.DataCloudJDBCDriver
24+
```
25+
26+
## Building the driver:
27+
28+
Use the following command to build and test the driver:
29+
30+
```shell
31+
mvn clean install
32+
```
433

534
## Usage
635

7-
It's required that all files must be placed at the top level of your repository.
36+
### Connection string
37+
38+
Use `jdbc:salesforce-datacloud://login.salesforce.com`
39+
40+
### JDBC Driver class
41+
42+
Use `com.salesforce.datacloud.jdbc.DataCloudJDBCDriver` as the driver class name for the JDBC application.
43+
44+
### Authentication
45+
46+
We support three of the [OAuth authorization flows][oauth authorization flows] provided by Salesforce.
47+
All of these flows require a connected app be configured for the driver to authenticate as, see the documentation here: [connected app overview][connected app overview].
48+
Set the following properties appropriately to establish a connection with your chosen OAuth authorization flow:
49+
50+
| Parameter | Description |
51+
|--------------|----------------------------------------------------------------------------------------------------------------------|
52+
| user | The login name of the user. |
53+
| password | The password of the user. |
54+
| clientId | The consumer key of the connected app. |
55+
| clientSecret | The consumer secret of the connected app. |
56+
| privateKey | The private key of the connected app. |
57+
| coreToken | OAuth token that a connected app uses to request access to a protected resource on behalf of the client application. |
58+
| refreshToken | Token obtained from the web server, user-agent, or hybrid app token flow. |
59+
60+
61+
#### username and password authentication:
62+
63+
The documentation for username and password authentication can be found [here][username flow].
64+
65+
To configure username and password, set properties like so:
66+
67+
```java
68+
Properties properties = new Properties();
69+
properties.put("user", "${userName}");
70+
properties.put("password", "${password}");
71+
properties.put("clientId", "${clientId}");
72+
properties.put("clientSecret", "${clientSecret}");
73+
```
74+
75+
#### jwt authentication:
76+
77+
The documentation for jwt authentication can be found [here][jwt flow].
78+
79+
Instuctions to generate a private key can be found [here](#generating-a-private-key-for-jwt-authentication)
80+
81+
```java
82+
Properties properties = new Properties();
83+
properties.put("privateKey", "${privateKey}");
84+
properties.put("clientId", "${clientId}");
85+
properties.put("clientSecret", "${clientSecret}");
86+
```
87+
88+
#### refresh token authentication:
89+
90+
The documentation for refresh token authentication can be found [here][refresh token flow].
91+
92+
```java
93+
Properties properties = new Properties();
94+
properties.put("coreToken", "${coreToken}");
95+
properties.put("refreshToken", "${refreshToken}");
96+
properties.put("clientId", "${clientId}");
97+
properties.put("clientSecret", "${clientSecret}");
98+
```
99+
100+
### Connection settings
101+
102+
See this page on available [connection settings][connection settings].
103+
These settings can be configured in properties by using the prefix `serverSetting.`
104+
105+
For example, to control locale set the following property:
106+
107+
```java
108+
properties.put("serverSetting.lc_time", "en_US");
109+
```
110+
111+
---
112+
113+
### Generating a private key for jwt authentication
114+
115+
To authenticate using key-pair authentication you'll need to generate a certificate and register it with your connected app.
116+
117+
```shell
118+
# create a key pair:
119+
openssl genrsa -out keypair.key 2048
120+
# create a digital certificate, follow the prompts:
121+
openssl req -new -x509 -nodes -sha256 -days 365 -key keypair.key -out certificate.crt
122+
# create a private key from the key pair:
123+
openssl pkcs8 -topk8 -nocrypt -in keypair.key -out private.key
124+
```
125+
126+
### Optional configuration
127+
128+
- `dataspace`: The data space to query, defaults to "default"
129+
- `User-Agent`: The User-Agent string identifies the JDBC driver and, optionally, the client application making the database connection. <br />
130+
By default, the User-Agent string will end with "salesforce-datacloud-jdbc/{version}" and we will prepend any User-Agent provided by the client application. <br />
131+
For example: "User-Agent: ClientApp/1.2.3 salesforce-datacloud-jdbc/1.0"
132+
133+
134+
### Usage sample code
135+
136+
```java
137+
public static void executeQuery() throws ClassNotFoundException, SQLException {
138+
Class.forName("com.salesforce.datacloud.jdbc.DataCloudJDBCDriver");
139+
140+
Properties properties = new Properties();
141+
properties.put("user", "${userName}");
142+
properties.put("password", "${password}");
143+
properties.put("clientId", "${clientId}");
144+
properties.put("clientSecret", "${clientSecret}");
145+
146+
try (var connection = DriverManager.getConnection("jdbc:salesforce-datacloud://login.salesforce.com", properties);
147+
var statement = connection.createStatement()) {
148+
var resultSet = statement.executeQuery("${query}");
149+
150+
while (resultSet.next()) {
151+
// Iterate over the result set
152+
}
153+
}
154+
}
155+
```
156+
157+
## Generated assertions
158+
159+
Some of our classes are tested using assertions generated with [the assertj assertions generator][assertion generator].
160+
Due to some transient test-compile issues we experienced, we checked in generated assertions for some of our classes.
161+
If you make changes to any of these classes, you will need to re-run the assertion generator to have the appropriate assertions available for that class.
162+
163+
To find examples of these generated assertions, look for files with the path `**/test/**/*Assert.java`.
164+
165+
To re-generate these assertions execute the following command:
166+
167+
```shell
168+
mvn assertj:generate-assertions
169+
```
8170

9-
> **NOTE** Your README should contain detailed, useful information about the project!
10171

172+
[oauth authorization flows]: https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_flows.htm&type=5
173+
[username flow]: https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5
174+
[jwt flow]: https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_jwt_flow.htm&type=5
175+
[refresh token flow]: https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_refresh_token_flow.htm&type=5
176+
[connection settings]: https://tableau.github.io/hyper-db/docs/hyper-api/connection#connection-settings
177+
[assertion generator]: https://joel-costigliola.github.io/assertj/assertj-assertions-generator-maven-plugin.html#configuration
178+
[connected app overview]: https://help.salesforce.com/s/articleView?id=sf.connected_app_overview.htm&type=5

0 commit comments

Comments
 (0)