The Salesforce CDP Java Database Connectivity (JDBC) driver allows for a JDBC connection to the Salesforce CDP ANSI SQL API. This connection lets you access and retrieve data using your favorite tools that are supported by JDBC.
The JDBC driver can be used with the tools like Tableau, DBeaver or independently with any Java JDBC client to connect to Salesforce CDP and retrieve the data.
Get the Driver from this repo.
To use JDBC driver, admins will have to create a connected app in the Salesforce org. Please follow the steps mentioned in Salesforce CDP setup in below link to create a connected app. If you create a connected app using below link, you need not pass client Id and secret mentioned in the code examples below. Or else please pass client Id and secret.
https://extensiongallery.tableau.com/connectors/270
Alternatively, if you want to use key pair authentication instead of username and password, please follow the below steps to generate a key pair and configure certificate with your connected app.
Open terminal and change directories to any folder and run the following commands:
openssl genrsa -out keypair.key 2048
openssl req -new -x509 -nodes -sha256 -days 365 -key keypair.key -out certificate.crt
Note: There will be a series of questions (Country, State, Org Name, etc) you need to complete.
openssl pkcs8 -topk8 -nocrypt -in keypair.key -out private.key
This creates keypair.key, private.key and certificate.crt files in that folder. Files private.key and certificate.crt will be used later in the setup.
This flow utilizes Salesforce's server to server JWT bearer flow for acquiring an access token. This portion of the setup will walk you through setting up the connected app.
Note: For more detailed instructions, please visit: Create a Connected App
- Login to Salesforce → Setup and Search "App Manager"
- In the Setup’s Quick Find search "App Manager"
- Select “New Connected App”
- Connected App Name: CDP API
- API Name: CDP_API (or whatever default value is pre-populated)
- Contact Email: Your email address
- Under API Heading, check the box for “Enable OAuth Settings”
- Callback URL: https://oauth.pstmn.io/v1/callback
Note: You can use your own callback url, which is nothing but the endpoint where redirect will happen after successful authorization. - Select the checkbox for “Use digital signatures”
- Select “Choose File” and select the certificate.crt file created in Create a Private Public Key Pair and a Digital x509 Certificate section
- Under “Selected OAuth Scopes” move the following from the “Available OAuth Scopes” to “Selected OAuth Scopes”
- Select Save (on the next screen select Continue)
- Make note of the Consumer Key value. This will be used as the “clientId” variable for establishing connection.
- At the top of your newly created connected app click “Manage”
- Select “Edit Policies”
- Change “IP Relaxation” to “Relax IP restrictions”
- Select Save
At this point your connected app has been configured however there is a one time setup requirement to authorize your user with the connected app.
The URL format will look like:
<YOUR_ORG_URL>/services/oauth2/authorize?response_type=code&client_id=<YOUR_CONSUMER_KEY>&scope=api refresh_token cdp_profile_api cdp_query_api&redirect_uri=<YOUR_CALLBACK_URL>
Notice the scope parameter in the above URL. It’s important that you select all the required custom CDP scopes in this request. All further JWT bearer flow requests will honor ONLY these scopes
YOUR_ORG_URL is the fully qualified instance URL.
YOUR_CONSUMER_KEY is the consumer key noted in step 3.x above.
Example URL:
-
Paste that URL in a browser window.
-
This prompts a consent dialog asking permission for each of the scopes requested above. Select Allow and you should be redirected back.
-
You may also get an alert from the callback. If you do, select Open Postman
-
Optional: If you want to verify everything is authorized correctly, in the Quick Find search for “Connected Apps OAuth Usage”. Here you will see your connected app and should see a user count of 1.
Load the Driver into your Java classPath
Create Connection with oAuth tokens
Class.forName("com.salesforce.cdp.queryservice.QueryServiceDriver");
Properties properties = new Properties();
properties.put("coreToken", <Core oAuth token>);
properties.put("refreshToken", <Refresh Token>);
properties.put("clientId", <Client Id of the connected App>);
properties.put("clientSecret", <Client Secret of the connected App>);
Connection connection = DriverManager.getConnection("jdbc:queryService-jdbc:https://login.salesforce.com", properties);
Create Connection with UserName and Password
Class.forName("com.salesforce.cdp.queryservice.QueryServiceDriver");
Properties properties = new Properties();
properties.put("user", <UserName>);
properties.put("password", <Password>);
properties.put("clientId", <Client Id of the connected App>);
properties.put("clientSecret", <Client Secret of the connected App>);
Connection connection = DriverManager.getConnection("jdbc:queryService-jdbc:https://login.salesforce.com", properties);
Create Connection with UserName, ClientId and Private Key (Key Pair authentication)
Class.forName("com.salesforce.cdp.queryservice.QueryServiceDriver");
Properties properties = new Properties();
properties.put("user", <UserName>);
properties.put("clientId", <Client Id of the connected App>);
properties.put("privateKey", <Private Key string corresponding to the digital x509 certificate configured in the connected App>);
Connection connection = DriverManager.getConnection("jdbc:queryService-jdbc:https://login.salesforce.com", properties);
Create Statements/ Prepared Statements to execute Query and get ResultSet
PreparedStatement preparedStatement = connection.prepareStatement("select FirstName__c, BirthDate__c, YearlyIncome__c from Individual__dlm where FirstName__c = ? and YearlyIncome__c > ?");
preparedStatement.setString(0, "Angella");
preparedStatement.setInt(1, 1000);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
log.info("FirstName : {}, BirthDate__c : {}, YearlyIncome__c : {}", resultSet.getString("FirstName__c"), resultSet.getTimestamp("BirthDate__c"), resultSet.getInt("YearlyIncome__c"));
The JDBC driver can also be used with python. We need JaydebeAPI wrapper on top of the JDBC driver to call JDBC methods.
Install JaydebeAPI using PIP
pip install JayDeBeApi
Sample Python Code
import jaydebeapi
// Sample properties with username and password flow.
properties = {
'user': "<UserName>",
'password': "<Password>",
'clientId': "<Client Id of the connected App>",
'clientSecret': "<Client Secret of the connected App>"
}
// Sample properties with key-pair authentication flow.
properties = {
'user': "<UserName>",
'clientId", "<Client Id of the connected App>",
'privateKey': "<Private Key string corresponding to the digital x509 certificate configured in the connected App>"
}
// Sample properties with oAuth (User agent) flow.
properties = {
'coreToken': "<CoreToken>",
'refreshToken': "<Refresh Token>",
'clientId", "<Client Id of the connected App>",
'clientSecret", "<Client Secret of the connected App>"
}
conn = jaydebeapi.connect("com.salesforce.cdp.queryservice.QueryServiceDriver", "jdbc:queryService-jdbc:https://login.salesforce.com", properties, "<Complete Path to JDBC driver>")
curs = conn.cursor()
curs.execute('SELECT * FROM ssot__Individual__dlm')
data = curs.fetchall()
Add order by clause in the query to fetch the paginated results for V1 API.