Salesforce via SQL - Preparations
Last Update: 20.11.2024 |
Introduction
This documentation describes how to access a Salesforce CRM system via Lobster Integration (version > 4.6.11) using a JDBC/SQL interface.
Note: It does not describe the inner functionality of the HTTP/SOAP access provided by Salesforce.
SQL access requires the purchase of an additional license. A particular JDBC driver by company CDATA - which is provided via the additional license - must be installed.
Important note: This JDBC driver converts SQL statements sent by Lobster Integration into webservice requests to the Salesforce HTTP/SOAP interface. It is important to ensure that the SQL statements are kept simple and not too complex (e.g. complicated join conditions etc.). There is a high probability that conversion of complex statements into webservice requests will fail.
Salesforce setup
Two steps are neccessary to access Salesforce via SQL statements:
1) JBDC driver
Once the license has been activated, the JDBC driver is automatically displayed in the Update Center.
After downloading the driver, the Integration Server must be restarted, then you can continue with the next step.
Linux:
Restart the Integration Server.
Windows:
The following sequence must be followed:
Stop the Integration Server
Start script ./bin/hub.bat
End script ./bin/hub.bat with Ctrl+c
Start the Integration Server
Note: It is advisable to take a look at the Update Center from time to time, as updates can be displayed and carried out there.
2) Configuration of two additional database aliases
Two aliases are necessary because the jdbc driver cannot execute bulk and normal operations via one alias.
The bulk alias is used for access to Salesforce in phase 5 (SQLBulkUnit), the non-bulk alias for all other accesses (phases 1, 3 and 4). Reason: this separation prevents large bulk operations from being blocked by long running select statements.
The aliases are created in Administration → Databases/Connectors. Below you will find two templates that you can import. You can then adjust their values.
Alternatively, an alias can also be created via Templates → Presets → Salesforce.
a) Bulk alias
<?
xml
version
=
"1.0"
encoding
=
"ISO-8859-1"
?>
<!DOCTYPE Configure PUBLIC "-//Lobster//DTD Configure 1.0//EN" "
http://www.lobster.de/dtd/configure_1_1.dtd
">
<
Configure
class
=
"com.ebd.hub.services.database.ConnectionService"
>
<
Call
name
=
"initPool"
>
<
Arg
>
<
New
class
=
"com.ebd.hub.services.database.DatabaseSettings"
>
<
Set
name
=
"alias"
>salesforce</
Set
>
<
Set
name
=
"allowGrowing"
>True</
Set
>
<
Set
name
=
"database"
>jdbc:lobster:sforce2:</
Set
>
<
Set
name
=
"user"
>(your salesforce login username)</
Set
>
<
Set
name
=
"password"
>(your salesforce login password)</
Set
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Security Token</
Arg
>
<
Arg
>(your security token)</
Arg
>
</
Call
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Use Bulk API</
Arg
>
<
Arg
>true</
Arg
>
</
Call
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Bulk API Version</
Arg
>
<
Arg
>v2</
Arg
>
</
Call
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Logfile</
Arg
>
<
Arg
>"C:\Lobster\IS\logs\salesforce_jdbc\sf.log"</
Arg
>
</
Call
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Verbosity</
Arg
>
<
Arg
>0</
Arg
>
</
Call
>
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Max Log File Size</
Arg
>
<
Arg
>10MB</
Arg
>
</
Call
>
<
Set
name
=
"catalogName"
></
Set
>
<
Set
name
=
"driver"
>de.lobster.jdbc.jdbc.sforce.SForceDriver</
Set
>
<
Set
name
=
"minSize"
>0</
Set
>
<
Set
name
=
"maxSize"
>0</
Set
>
<
Set
name
=
"idleTime"
>300000</
Set
>
<
Set
name
=
"sqlCommand"
></
Set
>
<
Set
name
=
"rollback"
>True</
Set
>
<
Set
name
=
"caching"
>True</
Set
>
</
New
>
</
Arg
>
</
Call
>
</
Configure
>
Parameter |
Description |
Example |
alias |
Alias name |
<Set name="alias">salesforce</Set> |
database |
The connection string for the jdbc driver is specified here. For an overview, all parameters are specified in the database.xml as "addNamedProperty" so that they are displayed in the "JDBC Properties" tab, during import. |
<Set name="database">jdbc:lobster:sforce2:</Set> ("2" und colon at the end required!) |
user |
Username Salesforce login |
<Set name="user">(your salesforce login username)</Set> |
password |
Password Salesforce login |
<Set name="password">(your salesforce login password)</Set> |
Security Token |
Fixed security token generated within Salesforce. Token creation, password change, etc causes the token to be sent to the user per mail. A new token can be created within Salesforce via View Profile → Settings → Reset my Security token. The token does not expire automatically. |
<Call name="addNamedProperty"> <Arg>Security Token</Arg> <Arg>(your security token)</Arg> </Call> |
Use Bulk API |
Enables usage of Salesforce's Bulk API via the jdbcdriver. Must be true in the bulk alias configuration. |
<Call name="addNamedProperty"> <Arg>Use Bulk API</Arg> <Arg>true</Arg> </Call> |
Bulk API Version |
Two versions exist (v1 and v2) - default is v1. Using v1, select queries are counted as well against the limit of max 15000 batches. Many selects can thus cause that limit to be quickly exceeded. Those jobs are processed with priority, causing long running select statements to possibly block other running jobs. For this reason the regular alias is used for select statements - no Salesforce jobs are created this way, the objects are directly accessed instead. |
<Call name="addNamedProperty"> <Arg>Bulk API Version</Arg> <Arg>v2</Arg> </Call> |
minSize, maxSize |
must be 0, otherwise the Salesforce bulk jobs are not closed. |
<Set name="minSize">0</Set> <Set name="maxSize">0</Set> |
driver |
Used Java driver class |
<Set name="driver">de.lobster.jdbc.jdbc.sforce.SForceDriver</Set> |
Use Connection Pooling |
Activates ConnectionPooling of the jdbc driver. If this is set to true, then the jdbc driver attempts to hang the generated bulks from two independent Lobster Integration jobs in a Salesforce job for as long as the connection is maintained. |
|
allowGrowing, catalogName, idleTime, sqlCommand, rollback, caching |
Those parameters are without meaning for Salesforce alias configuration. These are in every database alias by default. |
|
b) Regular alias
<?xml version=
"1.0"
encoding=
"ISO-8859-1"
?>
<!DOCTYPE Configure PUBLIC
"-//Lobster//DTD Configure 1.0//EN"
"http://www.lobster.de/dtd/configure_1_1.dtd"
>
<Configure
class
=
"com.ebd.hub.services.database.ConnectionService"
>
<Call name=
"initPool"
>
<Arg>
<New
class
=
"com.ebd.hub.services.database.DatabaseSettings"
>
<Set name=
"alias"
>salesforce_nobulk</Set>
<Set name=
"allowGrowing"
>True</Set>
<Set name=
"database"
>jdbc:lobster:sforce2:</Set>
<Set name=
"user"
>(your salesforce login username)</Set>
<Set name=
"password"
>(your salesforce login password)</Set>
<Call name=
"addNamedProperty"
>
<Arg>Security Token</Arg>
<Arg>(your security token)</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Use Bulk API</Arg>
<Arg>
false
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Use Connection Pooling</Arg>
<Arg>
true
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Logfile</Arg>
<Arg>
"C:\Lobster\IS\logs\salesforce_jdbc\sf.log"
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Verbosity</Arg>
<Arg>
0
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Max Log File Size</Arg>
<Arg>10MB</Arg>
</Call>
<Set name=
"catalogName"
></Set>
<Set name=
"driver"
>de.lobster.jdbc.jdbc.sforce.SForceDriver</Set>
<Set name=
"minSize"
>
0
</Set>
<Set name=
"maxSize"
>
0
</Set>
<Set name=
"idleTime"
>
300000
</Set>
<Set name=
"sqlCommand"
></Set>
<Set name=
"rollback"
>True</Set>
<Set name=
"caching"
>True</Set>
</New>
</Arg>
</Call>
</Configure>
Parameter |
Description |
Example |
alias, database, user, passwort, Security Token, minSize, maxSize, driver |
see above |
|
Use Bulk API |
Enables usage of Salesforce's Bulk API via the jdbcdriver. Must be false in the regular alias configuration. |
<Call name="addNamedProperty"> <Arg>Use Bulk API</Arg> <Arg>false</Arg> </Call> |
Use Connection Pooling |
Enables Connection Pooling within the JDBC driver. Should always be true, otherwise the daily limit of Salesforce connections (3000/day) can be exceeded very quickly. |
<Call name="addNamedProperty"> <Arg>Use Connection Pooling</Arg> <Arg>true</Arg> </Call> |
allowGrowing, catalogName, idleTime, sqlCommand, rollback, caching |
see above |
|
c) Access onto other Salesforce instances
Production instances can be accessed via login.salesforce.com, sandbox instances (test system aka production clone) via test.salesforce.com. If a sandbox instance shall be accessed, the following extension must set in the according alias (default is "false"):
<
Call
name
=
"addNamedProperty"
>
<
Arg
>Use Sandbox</
Arg
>
<
Arg
>true</
Arg
>
</
Call
>
It is also possible to purchase custom Subdomains at Salesforce,
e.g.: companyname.my.salesforce.com.
To be able to access the Salesforce instance via this URL, the "LoginURL" parameter must be added. This applies to the sandbox and the production system. For the sandbox, the Use Sandbox parameter must also be set to "true".
<
Call
name
=
"addNamedProperty"
>
<
Arg
>LoginURL</
Arg
>
<
Arg
>
https://
<
mysubdomain
>.my.salesforce.com/services/Soap/c/60.0</
Arg
>
</
Call
>
Note: 60.0 is currently the Salesforce API version supported by the jdbc driver (as of 04/2024)
d) Proxy configuration
Please enter all parameters in the alias using "addNamedProperty".
Parameter |
Description |
Default |
Proxy Server |
Hostname or IP address of the proxy |
./. |
Proxy Port |
TCP port the proxy is running on |
80 |
Proxy User |
Username for authentication |
./. |
Proxy Password |
Password for authentication |
./. |
Proxy Auth Scheme |
Authentication type (BASIC, DIGEST, NEGOTIATE, PROPRIETARY) |
BASIC |
Proxy Auto Detect |
Use system proxy settings. Set to false if the settings specified here should be used |
false |
Proxy Exceptions |
semicolon-separated list of hostnames and IPs which should not use the proxy |
./. |
Proxy SSL Type |
AUTO, ALWAYS, NEVER, TUNNEL (see driver documentation) |
AUTO |
For further details see the driver documentation: https://cdn.cdata.com/help/RFK/jdbc/Connection.htm
Configure OAuth2 (optional, if required/desired)
Requirements for using OAuth2 in conjunction with the Salesforce JDBC driver:
a) a corresponding app must be created on the Salesforce side
b) the values for Client Id(Consumer Key) and Cliend Secret(Consumer Secret) must be known.
If you have any questions, please consult the official Salesforce documentation or contact your Salesforce consultant.
Various steps are necessary to enable the process for automatically renewing the token. In any case, a Lobster Integration is required that already has access to Salesforce - initially with user/password authentication, as already described in this document.
Various procedures must be executed via the Admin Console or SQL console in the plugins.
The following is a step-by-step description of how to retrieve the access token and refresh token.
Note: None of the steps may be omitted, as they build on each other! The retrieval of the first access and refresh token can be done via an alias. However, all aliases must be configured for Oauth2 at the end.
Step 1 - Prepare Salesforce alias
The following properties must be added to the Salesforce alias in JDBC Properties. It is important that the callback URL in Salesforce and in Lobster Integration is http://localhost:33333. This is the standard callback URL for headless machines.
All placeholders in square brackets must still be replaced with the real values.
<Call name=
"addNamedProperty"
>
<Arg>AuthScheme</Arg>
<Arg>OAuth</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthClientId</Arg>
<Arg>[Client Id(Consumer Key)]</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthClientSecret</Arg>
<Arg>[Client Secret(Consumer Secret)]</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>CallbackURL</Arg>
<Arg>http:
//localhost:33333</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>InitiateOAuth</Arg>
<Arg>OFF</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthSettingsLocation</Arg>
<Arg>[<your_Lobster_home_directory>]/conf/Salesforce/OAuthSettings.txt</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>LoginURL</Arg>
<Arg>[LoginURL]</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthAccessTokenURL</Arg>
<Arg>[OAuthAccessTokenURL]</Arg>
</Call>
Parameter |
Description |
Example |
AuthScheme |
The schema with which the jdbc driver should authorize itself against Salesfoce. For OAuth, the value must be "OAuth". |
|
OAuthClientId |
The consumer key (see Salesforce description) is entered here |
<Call name="addNamedProperty">
|
OAuthClientSecret |
The Consumer Secret (see Salesforce description) is entered here |
<Call name="addNamedProperty">
|
CallbackURL |
The CallbackURL is required for the OAuth2 Granttype Authorization Code. The authorization for the user is returned to this URL when the token is renewed. |
|
InitiateOAuth |
The parameter specifies which procedure must be carried out. "OFF" is required to set up OAuth2. This retrieves the access token and the first refresh token. |
|
OAuthSettingsLocation |
The storage location in which the jdbc driver stores the latest token is specified here. It is recommended to specify a storage location in the ./conf directory. |
<Call name="addNamedProperty">
|
LoginURL |
The URL with which the driver login to Salesforce. This URL differs depending on the Salesforce instance: |
<Call name="addNamedProperty">
|
OAuthAccessTokenURL |
The URL with which the driver retrieves the AccessToken from Salesforce. This URL differs depending on the Salesforce instance: |
<Call name="addNamedProperty">
|
Step 2 - Get verifier from Salesforce
The first step is to retrieve the authorisation URL from Salesforce. To do this, open the Admin Console and navigate to Tools → SQL Monitor. The SQL Monitor is always mentioned in the process; alternatively, alternatively, you can always use the SQL console in the Plugins.
The Salesforce alias that was customised in step 1 is used as the database alias.
The following command must then be executed:
execute GetOAuthAuthorizationUrl
A URL is returned as the result. This must be called up in a browser. The browser does not have to be located on the Integration Server. For example:
https:
//login.salesforce.com/services/oauth2/authorize?state=aHR0cDovL2xvY2FsaG9zdDozMzMzMw%3D%3D&client_id=3MVG99Oxasdfasdfasdf0_eLiYU4FC2.NRn9htUmh2uIfNM.13BM33aZClit&response_type=code&redirect_uri=https%3A%2F%2Foauth.cdata.com%2Foauth%2F
The response from the server to the URL is a redirect. It is possible that an error is displayed in the browser because the URL with "http://localhost:33333" does not exist, but this is correct.
The redirect URL that appears in the address bar of the browser can look like this, for example:
http:
//localhost:33333/?code=YVByeDR5X0t6c2NXenl5easdfasdfkRmRyakxtNlNScEJNR2hFbG8wNTlJb2t2c1IzTVJ1UHU0Skg3aXdfYjMzYkRiM2NrZ1FZbWc9PQ==&state=YUhSMGNEb3ZMMnh2WTJGc2FHOXpkRG96TXpNek13PT0=&rssbus=true
The value of the "code" parameter is the verifier. This is required for the next step (in the example, it is the value YVByeDR5X0t6c2NXenl5easdfasdfkRmRyakxtNlNScEJNR2hFbG8wNTlJb2t2c1IzTVJ1UHU0Skg3aXdfYjMzYkRiM2NrZ1FZbWc9PQ== )
Step 3 - Get access and refresh token
The following procedure must now be called in the SQL Monitor with the value from step 2.
execute GetOAuthAccessToken Verifier=
'<your Verifier>'
This procedure returns a table with a data set.
The values for the access token and refresh token are required from this data set.
Step 4 - Store token in the alias
Now the Salesforce alias must be adjusted in Administration → Databases/Connectors. The Access Token and Refresh Token from step 3 must be added once. The value for "InitialteOAuth" parameter must also be renamed to "REFESH".
<Call name=
"addNamedProperty"
>
<Arg>InitiateOAuth</Arg>
<Arg>REFRESH</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthAccessToken</Arg>
<Arg>[Access Token]</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>OAuthRefreshToken</Arg>
<Arg>[Refresh Token]</Arg>
</Call>
Logging
Activation
To activate the logging of the jdbc driver, additional parameters are specified at the alias of the JDBC driver:
<Call name=
"addNamedProperty"
>
<Arg>Logfile</Arg>
<Arg>
"C:\Lobster\IS\logs\salesforce_jdbc\sf.log"
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Max Log File Size</Arg>
<Arg>
"10MB"
</Arg>
</Call>
<Call name=
"addNamedProperty"
>
<Arg>Verbosity</Arg>
<Arg>
0
</Arg>
</Call>
Parameter |
Description |
Logfile |
The log file's absolute path |
Verbosity |
Log level; von 1 (sparse) bis 5 (very high); should be set to 0 (= off) by default |
Max Log File Size |
maximum file size - a new file is opened if exceeded |
The log file contains the communication between Salesforce and the jdbcdriver (details depending on verbosity level) in plain text. Created SQL as well as sent HTTP requests/responses are logged.
As a rule, "Verbosity" = 3 on a test system is sufficient for troubleshooting. If logging is no longer required, it should be deactivated again.
The log file is not created immediately on startup of the Integration Server, but at the first access on the alias.
Important note: On production systems logging shall only be activated with great care as log file size can spiral out of control very quickly!
Log file rollover
If "Max Log File Size" is reached, a rollover takes place: the current log file contains a timestamp in its file name (yyyyMMddHH-mmss) and a new log file (with the name specified in parameter "Logfile") is created. Logging always continues in this file.
Technical features in Salesforce
Following a few technical features are described relevant for the usage of the Lobster jdbcinterface to Salesforce.
Metadata cache
On first access to a Salesforce object after JDBC startup its metadata is requested and stored in an internal cache ("MetaCache").This speeds up future calls to this object and requires rebuilding the cache after every change made to this object (e.g. adding or removing a property).
To rebuild the cache, however, the Integration Server must be restarted.
Salesforce Bulk API
Bulk jobs provide the advantage that big amounts of data are processed way more quickly via insert or update. Within Salesfcore there exist limitations (depending on the licensed Salesforce Edition) regarding connections per day and batches per day. Thus it is also useful to send big data amounts in bulk.
Note: Bulk jobs in Salesforce are only created if the bulk alias is used (Use Bulk API = true) AND the SQLBulkUnit is used in Phase 5. So no bulk job is created if the bulk alias is used but the statement has a different origin like Phase 3 (filter/function) or Phase 4 (database node). If the regular alias is used, the following error message appears in Phase 5: "Got no salesforce job-ID".
A list of currently operated and finished bulk jobs can be viewed in the Salesforce GUI via Setup → Environment → Jobs → Bulk Data Load Jobs. A bulk job consists of 1 - n batches, each batch can contain 1 - 9999 (max) records.
|
Attribute |
Description |
Head data |
Job ID Object External ID Field Content Type ... |
Head data of bulk job |
Batch 1 |
Record 1 |
First record in batch 1 |
Record 2 |
Second record in batch 1 |
|
... |
... |
|
Record 9999 |
Last record in batch 1 |
|
Batch 2 |
Record 1 |
First record in batch 2 |
Record 2 |
Second record in batch 2 |
|
... |
... |
Per database node one Salesforce bulk job is created (even with several data sheets/records within Lobster Integration only one bulk job per node is created - all data from each sheet is merged). The bulk jobs are processed serially by Lobster Integration. Each batch in a bulk job then gets processed in parallel within Salesforce.
Important note: "delete before insert" cannot be used by the SQLBulkUnit in connection with Salesforce!
Objects/Fields
Within Salesforce there are standard objects (Type = "Standard Object", provided by Salesforce like e.g. "Account") and custom defined objects (Type = "Custom Object"). Eeach object has a label for GUI access and an API name for API access. The API distinguishes between standard and custom objects - for custom objects it ends with "__c". An object possesses 1 - n fields. Fields possess a field label for GUI access and a field name for API access. Customized field names end with "__c" as well. Via the Salesforce GUI's Object Manager (Setup → Object Manager) details for each object's structure and its fields can be inspected. Standard objects cannot be deleted, but new fields or objects can be added to it. Standard fields cannot be deleted nor modified.
Object relations
Within Salesforce relations can be defined between objects. There are two main types of relations: lookup-relations and master-detail-relations. Their usage is described in section Salesforce via SQL - Tutorial.
Lookup relation
Lookup-relations are generally used if objects are only related in some cases. Examples from the Salesforce standard objects are "Account" and "Contact". This is a "loose" coupling - a contact can belong to an account but does not have to; it can exist only by itself. To connect a contact object to an account object, the field "AccountId" in contact (which is of type "Lookup(Account)") has to be filled with the internal ID of an account object.
Master detail relation
Within a master-detail-relation, the above is not possible. If a record is deleted from a master object, all related detail records are deleted as well. On creation of master-detail-relations the relation field is always created for the detail object. An example from the Salesforce standard objects cannot be provided for this scenario as a standard object can never be a detail object.