Skip to content

Commit

Permalink
Merge pull request #355 from ballerina-platform/reorgmodules
Browse files Browse the repository at this point in the history
Re-organize modules in ballerinax/salesforce package
  • Loading branch information
niveathika authored Jul 25, 2024
2 parents e9bc4ee + 9628979 commit 715f665
Show file tree
Hide file tree
Showing 25 changed files with 1,796 additions and 21 deletions.
8 changes: 4 additions & 4 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
distribution = "2201.8.0"
org = "ballerinax"
name = "salesforce"
version = "8.0.2"
export = ["salesforce", "salesforce.bulk", "salesforce.soap"]
version = "8.1.0"
export = ["salesforce", "salesforce.bulk", "salesforce.soap","salesforce.bulkv2", "salesforce.apex"]
license= ["Apache-2.0"]
authors = ["Ballerina"]
keywords = ["Sales & CRM/Customer Relationship Management", "Cost/Freemium"]
Expand All @@ -17,10 +17,10 @@ observabilityIncluded = true
graalvmCompatible = true

[[platform.java17.dependency]]
path = "../native/build/libs/salesforce-native-8.0.2.jar"
path = "../native/build/libs/salesforce-native-8.1.0-SNAPSHOT.jar"
groupId = "io.ballerinax"
artifactId = "salesforce"
version = "8.0.2"
version = "8.1.0-SNAPSHOT"

[[platform.java17.dependency]]
groupId = "com.opencsv"
Expand Down
58 changes: 57 additions & 1 deletion ballerina/client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

import ballerina/http;
import ballerina/io;
import ballerina/jballerina.java;
Expand All @@ -24,7 +25,6 @@ import ballerinax/salesforce.utils;
# Ballerina Salesforce connector provides the capability to access Salesforce REST API.
# This connector lets you to perform operations for SObjects, query using SOQL, search using SOSL, and describe SObjects
# and organizational data.

public isolated client class Client {
private final http:Client salesforceClient;
private map<string> sfLocators = {};
Expand Down Expand Up @@ -483,6 +483,10 @@ public isolated client class Client {
# + payload - Payload
# + returnType - The payload type, which is expected to be returned after data binding
# + return - `string|int|record{}` type if successful or else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.apex, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function apexRestExecute(string urlPath, http:Method methodType,
record {} payload = {}, typedesc<record {}|string|int?> returnType = <>)
returns returnType|error = @java:Method {
Expand Down Expand Up @@ -532,6 +536,10 @@ public isolated client class Client {
#
# + payload - The payload for the bulk job
# + return - `BulkJob` if successful or else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function createIngestJob(BulkCreatePayload payload) returns BulkJob|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST]);
return check self.salesforceClient->post(path, payload);
Expand All @@ -541,6 +549,10 @@ public isolated client class Client {
#
# + payload - The payload for the bulk job
# + return - `BulkJob` if successful or else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function createQueryJob(BulkCreatePayload payload) returns BulkJob|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, QUERY]);
return check self.salesforceClient->post(path, payload);
Expand All @@ -550,6 +562,10 @@ public isolated client class Client {
#
# + payload - The payload for the bulk job
# + return - `future<BulkJobInfo>` if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function createQueryJobAndWait(BulkCreatePayload payload) returns future<BulkJobInfo|error>|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, QUERY]);
http:Response response = check self.salesforceClient->post(path, payload);
Expand Down Expand Up @@ -582,6 +598,10 @@ public isolated client class Client {
# + bulkJobId - Id of the bulk job
# + bulkOperation - The processing operation for the job
# + return - `BulkJobInfo` if successful or else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function getJobInfo(string bulkJobId, BulkOperation bulkOperation) returns BulkJobInfo|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, bulkOperation, bulkJobId]);
return check self.salesforceClient->get(path);
Expand All @@ -592,6 +612,10 @@ public isolated client class Client {
# + bulkJobId - Id of the bulk job
# + content - CSV data to be added
# + return - `Nil` record if successful or `error` if unsuccessful
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function addBatch(string bulkJobId, string|string[][]|stream<string[], error?>|io:ReadableByteChannel content) returns error? {
string payload = "";
string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST, bulkJobId, BATCHES]);
Expand All @@ -612,6 +636,10 @@ public isolated client class Client {
#
# + jobType - Type of the job
# + return - `AllJobs` record if successful or `error` if unsuccessful
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function getAllJobs(JobType? jobType = ()) returns error|AllJobs {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST]) +
((jobType is ()) ? "" : string `?jobType=${jobType}`);
Expand All @@ -622,6 +650,10 @@ public isolated client class Client {
#
# + jobType - Type of the job
# + return - `AllJobs` if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function getAllQueryJobs(JobType? jobType = ()) returns error|AllJobs {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST]) +
((jobType is ()) ? "" : string `?jobType=${jobType}`);
Expand All @@ -633,6 +665,10 @@ public isolated client class Client {
# + status - Status of the job
# + bulkJobId - Id of the bulk job
# + return - `string[][]` if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function getJobStatus(string bulkJobId, Status status)
returns string[][]|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST, bulkJobId, status]);
Expand All @@ -657,6 +693,10 @@ public isolated client class Client {
# + bulkJobId - Id of the bulk job
# + maxRecords - The maximum number of records to retrieve per set of results for the query
# + return - The resulting string[][] if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function getQueryResult(string bulkJobId, int? maxRecords = ()) returns string[][]|error {

string path = "";
Expand Down Expand Up @@ -718,6 +758,10 @@ public isolated client class Client {
# + bulkJobId - Id of the bulk job
# + bulkOperation - The processing operation for the job
# + return - `()` if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function abortJob(string bulkJobId, BulkOperation bulkOperation) returns BulkJobInfo|error {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, bulkOperation, bulkJobId]);
record {} payload = {"state": "Aborted"};
Expand All @@ -729,6 +773,10 @@ public isolated client class Client {
# + bulkJobId - Id of the bulk job
# + bulkOperation - The processing operation for the job
# + return - `()` if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function deleteJob(string bulkJobId, BulkOperation bulkOperation) returns error? {
string path = utils:prepareUrl([API_BASE_PATH, JOBS, bulkOperation, bulkJobId]);
return check self.salesforceClient->delete(path);
Expand All @@ -738,6 +786,10 @@ public isolated client class Client {
#
# + bulkJobId - Id of the bulk job
# + return - future<BulkJobInfo> if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function closeIngestJobAndWait(string bulkJobId) returns error|future<BulkJobInfo|error> {
final string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST, bulkJobId]);
record {} payload = {"state": "UploadComplete"};
Expand Down Expand Up @@ -768,6 +820,10 @@ public isolated client class Client {
#
# + bulkJobId - Id of the bulk job
# + return - BulkJobInfo if successful else `error`
# # Deprecated
# This function is deprecated due to the introduction of the new submodule salesforce.bulkv2, which supports the same functionality.
# This API will be removed with the 9.0.0 release.
@deprecated
isolated remote function closeIngestJob(string bulkJobId) returns error|BulkJobCloseInfo {
final string path = utils:prepareUrl([API_BASE_PATH, JOBS, INGEST, bulkJobId]);
record {} payload = {"state": "UploadComplete"};
Expand Down
6 changes: 6 additions & 0 deletions ballerina/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

//Latest API Version
# Constant field `API_VERSION`. Holds the value for the Salesforce API version.
# # Deprecated
# This will be removed with the 9.0.0 release.
@deprecated
public const string API_VERSION = "v59.0";

// For URL encoding
Expand Down Expand Up @@ -111,6 +114,9 @@ const string QUESTION_MARK = "?";
const string EQUAL_SIGN = "=";

# Constant field `EMPTY_STRING`. Holds the value of "".
# # Deprecated
# This will be removed with the 9.0.0 release.
@deprecated
public const string EMPTY_STRING = "";

# Constant field `AMPERSAND`. Holds the value of "&".
Expand Down
10 changes: 9 additions & 1 deletion ballerina/errors.bal
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,19 @@ const string JSON_ACCESSING_ERROR_MSG = "Error occurred while accessing the JSON
const string XML_ACCESSING_ERROR_MSG = "Error occurred while accessing the XML payload of the response.";
const string TEXT_ACCESSING_ERROR_MSG = "Error occurred while accessing the Text payload of the response.";
const string HTTP_CLIENT_ERROR = "Failed to establish the communication with the upstream server or a data binding failure. Refer error.cause() for more details";
# # Deprecated
# This will be removed with the 9.0.0 release.
@deprecated
public const string HTTP_ERROR_MSG = "Error occurred while getting the HTTP response.";
const STATUS_CODE = "statusCode";
const HEADERS = "headers";
const BODY = "body";


# # Deprecated
# This will be removed with the 9.0.0 release.
@deprecated
public const string ERR_EXTRACTING_ERROR_MSG = "Error occured while extracting errors from payload.";
# # Deprecated
# This will be removed with the 9.0.0 release.
@deprecated
public const string INVALID_CLIENT_CONFIG = "Invalid values provided for client configuration parameters.";
92 changes: 92 additions & 0 deletions ballerina/modules/apex/Module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
## Overview

Salesforce Apex REST API enables you to expose your Apex classes and methods as RESTful web services. This module provides operations for executing custom Apex REST endpoints, allowing you to perform various HTTP operations on these endpoints and handle responses accordingly.

Ballerina Salesforce Apex REST API client supports the [Salesforce v59.0 APEX REST API](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest_intro.htm).

## Setup guide

1. Create a Salesforce account with the REST capability.

2. Go to Setup --> Apps --> App Manager

<img src=https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-sfdc/master/docs/setup/resources/side-panel.png alt="Setup Side Panel" width="40%" style="border:1px solid #000000">

3. Create a New Connected App.

<img src=https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-sfdc/master/docs/setup/resources/create-connected-apps.png alt="Create Connected Apps" width="50%" style="border:1px solid #000000">

- Here we will be using https://test.salesforce.com as we are using sandbox environment. Users can use https://login.salesforce.com for normal usage.

<img src=https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-sfdc/master/docs/setup/resources/create_connected%20_app.png alt="Create Connected Apps" width="100%" style="border:1px solid #000000">

4. After the creation user can get consumer key and secret through clicking on the `Manage Consumer Details` button.

<img src=https://raw.githubusercontent.com/ballerina-platform/module-ballerinax-sfdc/master/docs/setup/resources/crdentials.png alt="Consumer Secrets" width="100%" style="border:1px solid #000000">

5. The next step is to get the token.

- Log in to Salesforce in your preferred browser and enter the following URL:
`https://<YOUR_INSTANCE>.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<CONSUMER_KEY>&redirect_uri=<REDIRECT_URL>`
- Allow access if an alert pops up, and the browser will be redirected to a URL like the following:
`https://login.salesforce.com/?code=<ENCODED_CODE>`

- The code can be obtained after decoding the encoded code

6. Get Access and Refresh tokens

- The following request can be sent to obtain the tokens.
```curl -X POST https://<YOUR_INSTANCE>.salesforce.com/services/oauth2/token?code=<CODE>&grant_type=authorization_code&client_id=<CONSUMER_KEY>&client_secret=<CONSUMER_SECRET>&redirect_uri=https://test.salesforce.com/```
- Tokens can be obtained from the response.

## Quickstart

To use the Salesforce Apex client in your Ballerina application, update the .bal file as follows:

### Step 1: Import connector

Import the `ballerinax/salesforce.apex` module into the Ballerina project.

```ballerina
import ballerinax/salesforce.apex;
```

### Step 2: Create a new connector instance

Create a `ConnectionConfig` with the OAuth2 tokens obtained, and initialize the connector with it.
```ballerina
apex:ConnectionConfig sfConfig = {
baseUrl: baseUrl,
auth: {
clientId: clientId,
clientSecret: clientSecret,
refreshToken: refreshToken,
refreshUrl: refreshUrl
}
};
apex:Client apexClient = check new (sfConfig);
```

### Step 3: Invoke connector operation

1. Now you can use the operations available within the connector. Note that they are in the form of remote operations.
Following is an example of how to execute a custom Apex REST endpoint using the connector.

```ballerina
public function main() returns error? {
string caseId = check apexClient->apexRestExecute("Cases", "POST",
{
"subject": "Item Fault!",
"status": "New",
"priority": "High"
});
return;
}
```

2. Use `bal run` command to compile and run the Ballerina program.

## Examples

1. [Salesforce APEX REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/master/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce.
Loading

0 comments on commit 715f665

Please sign in to comment.