Skip to content

Commit

Permalink
Open source the Data Cloud JDBC driver
Browse files Browse the repository at this point in the history
  • Loading branch information
jschneidereit committed Nov 20, 2024
1 parent c7a1302 commit a6a8038
Show file tree
Hide file tree
Showing 202 changed files with 28,086 additions and 256 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto eol=lf
*.java text diff=java
35 changes: 35 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Get hyperd version
id: evaluate-property
run: |
echo "HYPER_VERSION=$(mvn help:evaluate -Dexpression=hyperapi.version -q -DforceStdout)" >> $GITHUB_ENV
- name: Cache hyperd
uses: actions/cache@v3
with:
path: |
target/.cache
key: ${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
restore-keys: |
${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
- name: Maven package
run: mvn --batch-mode --no-transfer-progress clean package --file pom.xml
42 changes: 42 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Release to staging

on:
release:
types: [ "created" ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
server-id: ossrh
server-username: 'MAVEN_USERNAME'
server-password: 'MAVEN_PASSWORD'
gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }}
gpg-passphrase: 'MAVEN_GPG_PASSPHRASE'
- name: Get hyperd version
id: evaluate-property
run: |
echo "HYPER_VERSION=$(mvn help:evaluate -Dexpression=hyperapi.version -q -DforceStdout)" >> $GITHUB_ENV
- name: Cache hyperd
uses: actions/cache@v3
with:
path: |
target/.cache
key: ${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
restore-keys: |
${{ runner.os }}-hyper-${{ env.HYPER_VERSION }}
- name: Set version
run: mvn versions:set --no-transfer-progress -DnewVersion=${{ github.event.release.tag_name }}
- name: Build with Maven
run: mvn --batch-mode --no-transfer-progress clean deploy -P release --file pom.xml
env:
MAVEN_USERNAME: ${{ secrets.CENTRAL_TOKEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.CENTRAL_TOKEN_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_KEY_PASSWORD }}
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.idea
!.idea/externalDependencies.xml
!.idea/palantir-java-format.xml

.DS_Store

target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.project
.classpath
src/main/resources/config/config.properties

*.iml
pom.xml.bak
6 changes: 6 additions & 0 deletions .hooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e

echo '[git pre-commit] mvn spotless:apply sortpom:sort'
MAVEN_OPTS='-Dorg.slf4j.simpleLogger.defaultLogLevel=error' mvn spotless:apply sortpom:sort
git add --update
6 changes: 6 additions & 0 deletions .idea/externalDependencies.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/palantir-java-format.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Comment line immediately above ownership line is reserved for related other information. Please be careful while editing.
#ECCN:Open Source
#GUSINFO:Open Source,Open Source Workflow
#ECCN: 5D002.c.1
#GUSINFO:Open Source,Open Source Workflow
* [email protected]
31 changes: 6 additions & 25 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,27 @@
*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.*
# Contributing Guide For Data Cloud JDBC Driver

# Contributing Guide For {NAME OF PROJECT}

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.
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.

# Governance Model
> Pick the most appropriate one
## Community Based

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.

> or

## Salesforce Sponsored

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.

> or
## Published but not supported

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.

# Getting started

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.

# Issues, requests & ideas

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

### Bug Reports and Fixes
- 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,
[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
- 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,
[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
be reviewed.
- Issues that have already been identified as a bug (note: able to reproduce) will be labelled `bug`.
- If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number.
- Include tests that isolate the bug and verifies that it was fixed.

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

If you're new to our project and looking for some way to make your first contribution, look for
Issues labelled `good first contribution`.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright {yyyy} {name of copyright owner}
Copyright 2024 Salesforce

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
176 changes: 172 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,178 @@
# README
# Salesforce DataCloud JDBC Driver

A repo containing all the basic file templates and general guidelines for any open source project at Salesforce.
With the Salesforce Data Cloud JDBC driver you can efficiently query millions of rows of data with low latency, and perform bulk data extractions.
This driver is read-only and forward-only.
It requires Java 11 or greater.


## Getting started

To add the driver to your project, add the following Maven dependency:

```xml
<dependency>
<groupId>com.salesforce.datacloud</groupId>
<artifactId>jdbc</artifactId>
<version>${jdbc.version}</version>
</dependency>
```

The class name for this driver is:

```
com.salesforce.datacloud.jdbc.DataCloudJDBCDriver
```

## Building the driver:

Use the following command to build and test the driver:

```shell
mvn clean install
```

## Usage

It's required that all files must be placed at the top level of your repository.
### Connection string

Use `jdbc:salesforce-datacloud://login.salesforce.com`

### JDBC Driver class

Use `com.salesforce.datacloud.jdbc.DataCloudJDBCDriver` as the driver class name for the JDBC application.

### Authentication

We support three of the [OAuth authorization flows][oauth authorization flows] provided by Salesforce.
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].
Set the following properties appropriately to establish a connection with your chosen OAuth authorization flow:

| Parameter | Description |
|--------------|----------------------------------------------------------------------------------------------------------------------|
| user | The login name of the user. |
| password | The password of the user. |
| clientId | The consumer key of the connected app. |
| clientSecret | The consumer secret of the connected app. |
| privateKey | The private key of the connected app. |
| coreToken | OAuth token that a connected app uses to request access to a protected resource on behalf of the client application. |
| refreshToken | Token obtained from the web server, user-agent, or hybrid app token flow. |


#### username and password authentication:

The documentation for username and password authentication can be found [here][username flow].

To configure username and password, set properties like so:

```java
Properties properties = new Properties();
properties.put("user", "${userName}");
properties.put("password", "${password}");
properties.put("clientId", "${clientId}");
properties.put("clientSecret", "${clientSecret}");
```

#### jwt authentication:

The documentation for jwt authentication can be found [here][jwt flow].

Instuctions to generate a private key can be found [here](#generating-a-private-key-for-jwt-authentication)

```java
Properties properties = new Properties();
properties.put("privateKey", "${privateKey}");
properties.put("clientId", "${clientId}");
properties.put("clientSecret", "${clientSecret}");
```

#### refresh token authentication:

The documentation for refresh token authentication can be found [here][refresh token flow].

```java
Properties properties = new Properties();
properties.put("coreToken", "${coreToken}");
properties.put("refreshToken", "${refreshToken}");
properties.put("clientId", "${clientId}");
properties.put("clientSecret", "${clientSecret}");
```

### Connection settings

See this page on available [connection settings][connection settings].
These settings can be configured in properties by using the prefix `serverSetting.`

For example, to control locale set the following property:

```java
properties.put("serverSetting.lc_time", "en_US");
```

---

### Generating a private key for jwt authentication

To authenticate using key-pair authentication you'll need to generate a certificate and register it with your connected app.

```shell
# create a key pair:
openssl genrsa -out keypair.key 2048
# create a digital certificate, follow the prompts:
openssl req -new -x509 -nodes -sha256 -days 365 -key keypair.key -out certificate.crt
# create a private key from the key pair:
openssl pkcs8 -topk8 -nocrypt -in keypair.key -out private.key
```

### Optional configuration

- `dataspace`: The data space to query, defaults to "default"
- `User-Agent`: The User-Agent string identifies the JDBC driver and, optionally, the client application making the database connection. <br />
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 />
For example: "User-Agent: ClientApp/1.2.3 salesforce-datacloud-jdbc/1.0"


### Usage sample code

```java
public static void executeQuery() throws ClassNotFoundException, SQLException {
Class.forName("com.salesforce.datacloud.jdbc.DataCloudJDBCDriver");

Properties properties = new Properties();
properties.put("user", "${userName}");
properties.put("password", "${password}");
properties.put("clientId", "${clientId}");
properties.put("clientSecret", "${clientSecret}");

try (var connection = DriverManager.getConnection("jdbc:salesforce-datacloud://login.salesforce.com", properties);
var statement = connection.createStatement()) {
var resultSet = statement.executeQuery("${query}");

while (resultSet.next()) {
// Iterate over the result set
}
}
}
```

## Generated assertions

Some of our classes are tested using assertions generated with [the assertj assertions generator][assertion generator].
Due to some transient test-compile issues we experienced, we checked in generated assertions for some of our classes.
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.

To find examples of these generated assertions, look for files with the path `**/test/**/*Assert.java`.

To re-generate these assertions execute the following command:

```shell
mvn assertj:generate-assertions
```

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

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

0 comments on commit a6a8038

Please sign in to comment.