From 539f3e0f148ed10edab3a5704eac6f5e5a8d5e70 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Fri, 16 Feb 2024 14:50:00 +0530 Subject: [PATCH 01/26] Update Release workflow --- .github/workflows/release.yml | 73 +++++++---------------------------- 1 file changed, 15 insertions(+), 58 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 07d8392d..fcf51426 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,62 +1,19 @@ -name: Deployment +name: Publish Release on: - release: - types: [ published ] + workflow_dispatch: + repository_dispatch: + types: [ stdlib-release-pipeline ] jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - # Set up Java Environment - - name: Set up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17.0.7 - - # Setup Ballerina Environment - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: 2201.8.0 - - # Grant execute permission to the gradlew script - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - # Build the project with Gradle - - name: Build with Gradle - env: - packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }} - packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }} - JAVA_OPTS: -DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true - run: | - ./gradlew build -x test -x :salesforce-examples:build - - # Perform Trivy scan - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - scan-type: 'rootfs' - scan-ref: '.' - skip-dirs: 'gradle/' - format: 'table' - timeout: '10m0s' - exit-code: '1' - - # Build Ballerina Project - - name: Ballerina Build - run: bal pack ./ballerina - env: - JAVA_HOME: /usr/lib/jvm/default-jvm - - # Push to Ballerina Central - - name: Ballerina Push - run: bal push - working-directory: ./ballerina - env: - BALLERINA_CENTRAL_ACCESS_TOKEN: ${{ secrets.BALLERINA_CENTRAL_ACCESS_TOKEN }} - JAVA_HOME: /usr/lib/jvm/default-jvm + call_workflow: + name: Run Release Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/release-package-connector-template.yml@main + secrets: inherit + with: + package-name: salesforce + package-org: ballerinax + additional-build-flags: "-x :salesforce-examples:build" + additional-release-flags: "-x :salesforce-examples:build" + additional-publish-flags: "-x :salesforce-examples:build" \ No newline at end of file From f4f384e6fab448669f7064baf164e8f073400ab5 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:19:59 +0530 Subject: [PATCH 02/26] Add build.sh file to samples --- ballerina/Ballerina.toml | 6 ++--- samples/build.gradle | 16 ++++++++++++-- samples/build.sh | 47 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 5 deletions(-) create mode 100755 samples/build.sh diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index e850dc7b..3a86e41b 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -2,7 +2,7 @@ distribution = "2201.8.0" org = "ballerinax" name = "salesforce" -version = "7.6.0" +version = "8.0.0" export = ["salesforce", "salesforce.bulk", "salesforce.soap"] license= ["Apache-2.0"] authors = ["Ballerina"] @@ -17,7 +17,7 @@ observabilityIncluded = true graalvmCompatible = true [[platform.java11.dependency]] -path = "../native/build/libs/salesforce-native-7.6.0.jar" +path = "../native/build/libs/salesforce-native-8.0.0.jar" groupId = "io.ballerinax" artifactId = "salesforce" -version = "7.6.0" +version = "8.0.0" diff --git a/samples/build.gradle b/samples/build.gradle index 2ae673bc..6422254c 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -46,8 +46,20 @@ task buildExamples { } } doLast { - // Enabled --offline due to a bug in pulling incorrect versions from the central repository. - examples.each { example -> executeBalCommand ("build --offline ${example}", "${project.rootDir}") } + try { + exec { + workingDir project.projectDir + println("Working dir: ${workingDir}") + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'sh', "/c", "chmod +x ./build.s && ./build.sh build && exit %%ERRORLEVEL%%" + } else { + commandLine 'sh', "-c", "chmod +x ./build.sh && ./build.sh build" + } + } + } catch (Exception e) { + println("Example Build failed: " + e.message) + throw e + } } } diff --git a/samples/build.sh b/samples/build.sh new file mode 100755 index 00000000..66ddb2c9 --- /dev/null +++ b/samples/build.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +BAL_EXAMPLES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BAL_CENTRAL_DIR="$HOME/.ballerina/repositories/central.ballerina.io/" +BAL_HOME_DIR="$BAL_EXAMPLES_DIR/../ballerina" + +set -e + +case "$1" in +build) + BAL_CMD="build" + ;; +run) + BAL_CMD="run" + ;; +*) + echo "Invalid command provided: '$1'. Please provide 'build' or 'test' as the command." + exit 1 + ;; +esac + +# Read Ballerina package name +BAL_PACKAGE_NAME=$(awk -F'"' '/^name/ {print $2}' "$BAL_HOME_DIR/Ballerina.toml") + +# Push the package to the local repository +cd "$BAL_HOME_DIR" && + bal pack && + bal push --repository=local + +# Remove the cache directories in the repositories +cacheDirs=($(ls -d "$BAL_CENTRAL_DIR"/cache-* 2>/dev/null)) +for dir in "${cacheDirs[@]}"; do + [ -d "$dir" ] && rm -r "$dir" +done +echo "Successfully cleaned the cache directories" + +# Update the central repository +BAL_DESTINATION_DIR="$HOME/.ballerina/repositories/central.ballerina.io/bala/ballerinax/$BAL_PACKAGE_NAME" +BAL_SOURCE_DIR="$HOME/.ballerina/repositories/local/bala/ballerinax/$BAL_PACKAGE_NAME" +[ -d "$BAL_DESTINATION_DIR" ] && rm -r "$BAL_DESTINATION_DIR" +[ -d "$BAL_SOURCE_DIR" ] && cp -r "$BAL_SOURCE_DIR" "$BAL_DESTINATION_DIR" +echo "Successfully updated the local central repositories" + +# Loop through examples in the examples directory +find "$BAL_EXAMPLES_DIR" -type f -name "*.bal" | while read -r BAL_EXAMPLE_FILE; do + bal "$BAL_CMD" --offline "$BAL_EXAMPLE_FILE" +done \ No newline at end of file From 167e8e85c35f2bc71c4adace360166b5fc78fada Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:19:59 +0530 Subject: [PATCH 03/26] Add build.sh file to samples --- ballerina/Ballerina.toml | 6 ++--- samples/build.gradle | 16 ++++++++++++-- samples/build.sh | 47 ++++++++++++++++++++++++++++++++++++++++ settings.gradle | 2 +- 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100755 samples/build.sh diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index e850dc7b..3a86e41b 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -2,7 +2,7 @@ distribution = "2201.8.0" org = "ballerinax" name = "salesforce" -version = "7.6.0" +version = "8.0.0" export = ["salesforce", "salesforce.bulk", "salesforce.soap"] license= ["Apache-2.0"] authors = ["Ballerina"] @@ -17,7 +17,7 @@ observabilityIncluded = true graalvmCompatible = true [[platform.java11.dependency]] -path = "../native/build/libs/salesforce-native-7.6.0.jar" +path = "../native/build/libs/salesforce-native-8.0.0.jar" groupId = "io.ballerinax" artifactId = "salesforce" -version = "7.6.0" +version = "8.0.0" diff --git a/samples/build.gradle b/samples/build.gradle index 2ae673bc..25cc5b71 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -46,8 +46,20 @@ task buildExamples { } } doLast { - // Enabled --offline due to a bug in pulling incorrect versions from the central repository. - examples.each { example -> executeBalCommand ("build --offline ${example}", "${project.rootDir}") } + try { + exec { + workingDir project.projectDir + println("Working dir: ${workingDir}") + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'sh', "/c", "chmod +x ./build.sh && ./build.sh build && exit %%ERRORLEVEL%%" + } else { + commandLine 'sh', "-c", "chmod +x ./build.sh && ./build.sh build" + } + } + } catch (Exception e) { + println("Example Build failed: " + e.message) + throw e + } } } diff --git a/samples/build.sh b/samples/build.sh new file mode 100755 index 00000000..66ddb2c9 --- /dev/null +++ b/samples/build.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +BAL_EXAMPLES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BAL_CENTRAL_DIR="$HOME/.ballerina/repositories/central.ballerina.io/" +BAL_HOME_DIR="$BAL_EXAMPLES_DIR/../ballerina" + +set -e + +case "$1" in +build) + BAL_CMD="build" + ;; +run) + BAL_CMD="run" + ;; +*) + echo "Invalid command provided: '$1'. Please provide 'build' or 'test' as the command." + exit 1 + ;; +esac + +# Read Ballerina package name +BAL_PACKAGE_NAME=$(awk -F'"' '/^name/ {print $2}' "$BAL_HOME_DIR/Ballerina.toml") + +# Push the package to the local repository +cd "$BAL_HOME_DIR" && + bal pack && + bal push --repository=local + +# Remove the cache directories in the repositories +cacheDirs=($(ls -d "$BAL_CENTRAL_DIR"/cache-* 2>/dev/null)) +for dir in "${cacheDirs[@]}"; do + [ -d "$dir" ] && rm -r "$dir" +done +echo "Successfully cleaned the cache directories" + +# Update the central repository +BAL_DESTINATION_DIR="$HOME/.ballerina/repositories/central.ballerina.io/bala/ballerinax/$BAL_PACKAGE_NAME" +BAL_SOURCE_DIR="$HOME/.ballerina/repositories/local/bala/ballerinax/$BAL_PACKAGE_NAME" +[ -d "$BAL_DESTINATION_DIR" ] && rm -r "$BAL_DESTINATION_DIR" +[ -d "$BAL_SOURCE_DIR" ] && cp -r "$BAL_SOURCE_DIR" "$BAL_DESTINATION_DIR" +echo "Successfully updated the local central repositories" + +# Loop through examples in the examples directory +find "$BAL_EXAMPLES_DIR" -type f -name "*.bal" | while read -r BAL_EXAMPLE_FILE; do + bal "$BAL_CMD" --offline "$BAL_EXAMPLE_FILE" +done \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 554e74c1..7952bad9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,7 +30,7 @@ include ":${projectName}-examples" project(':checkstyle').projectDir = file("build-config${File.separator}checkstyle") project(":${projectName}-native").projectDir = file('native') project(":${projectName}-ballerina").projectDir = file('ballerina') -project(":${projectName}-examples").projectDir = file('examples') +project(":${projectName}-examples").projectDir = file('samples') gradleEnterprise { buildScan { From c7114c74b4c3d221ad2baf15fe48257fdc86297e Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 08:55:57 +0530 Subject: [PATCH 04/26] Update build.gradle --- samples/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/build.gradle b/samples/build.gradle index 25cc5b71..09eae3f6 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -16,6 +16,7 @@ * under the License. */ +import org.apache.tools.ant.taskdefs.condition.Os apply plugin: 'java-library' From e371cc6749b9ed88b06d5f7e7a1c1d2e3f9d13e9 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:11:36 +0530 Subject: [PATCH 05/26] Clean the code --- .github/workflows/release.yml | 3 ++- samples/build.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcf51426..cd393f52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,4 +16,5 @@ jobs: package-org: ballerinax additional-build-flags: "-x :salesforce-examples:build" additional-release-flags: "-x :salesforce-examples:build" - additional-publish-flags: "-x :salesforce-examples:build" \ No newline at end of file + additional-publish-flags: "-x :salesforce-examples:build" + \ No newline at end of file diff --git a/samples/build.sh b/samples/build.sh index 66ddb2c9..5d32ff06 100755 --- a/samples/build.sh +++ b/samples/build.sh @@ -44,4 +44,4 @@ echo "Successfully updated the local central repositories" # Loop through examples in the examples directory find "$BAL_EXAMPLES_DIR" -type f -name "*.bal" | while read -r BAL_EXAMPLE_FILE; do bal "$BAL_CMD" --offline "$BAL_EXAMPLE_FILE" -done \ No newline at end of file +done From db871a17080bb612b6313fc1db13a6ae72c0d39f Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:25:21 +0530 Subject: [PATCH 06/26] Remove integration examples --- .../.devcontainer.json | 4 - .../.gitignore | 4 - .../Ballerina.toml | 8 - .../README.md | 80 ---- .../main.bal | 120 ----- .../resources/inputs/quote1.edi | 8 - .../resources/inputs/quote2.edi | 10 - .../transformer.bal | 45 -- .../types.bal | 39 -- examples/gmail-to-salesforce-lead/.gitignore | 3 - .../gmail-to-salesforce-lead/Ballerina.toml | 8 - .../Dependencies.toml | 410 ------------------ examples/gmail-to-salesforce-lead/README.md | 98 ----- .../docs/images/flow-diagram.png | Bin 48376 -> 0 bytes examples/gmail-to-salesforce-lead/main.bal | 85 ---- examples/gmail-to-salesforce-lead/types.bal | 18 - .../kafka-message-producer/Ballerina.toml | 8 - .../kafka-message-producer/main.bal | 23 - .../Ballerina.toml | 8 - .../Docs/Flow diagram.png | Bin 176544 -> 0 bytes .../Readme.md | 51 --- .../main.bal | 45 -- .../Ballerina.toml | 7 - .../Readme.md | 52 --- .../docs/images/template_flow.png | Bin 26635 -> 0 bytes .../main.bal | 58 --- 26 files changed, 1192 deletions(-) delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/.devcontainer.json delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/.gitignore delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/Ballerina.toml delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/README.md delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/main.bal delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote1.edi delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote2.edi delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/transformer.bal delete mode 100644 examples/ftp-edi-message-to-salesforce-opportunity/types.bal delete mode 100644 examples/gmail-to-salesforce-lead/.gitignore delete mode 100644 examples/gmail-to-salesforce-lead/Ballerina.toml delete mode 100644 examples/gmail-to-salesforce-lead/Dependencies.toml delete mode 100644 examples/gmail-to-salesforce-lead/README.md delete mode 100644 examples/gmail-to-salesforce-lead/docs/images/flow-diagram.png delete mode 100644 examples/gmail-to-salesforce-lead/main.bal delete mode 100644 examples/gmail-to-salesforce-lead/types.bal delete mode 100644 examples/kafka_salesforce_integration/kafka-message-producer/Ballerina.toml delete mode 100644 examples/kafka_salesforce_integration/kafka-message-producer/main.bal delete mode 100644 examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Ballerina.toml delete mode 100644 examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Docs/Flow diagram.png delete mode 100644 examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Readme.md delete mode 100644 examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/main.bal delete mode 100644 examples/salesforce-new-contact-to-twilio-sms/Ballerina.toml delete mode 100644 examples/salesforce-new-contact-to-twilio-sms/Readme.md delete mode 100644 examples/salesforce-new-contact-to-twilio-sms/docs/images/template_flow.png delete mode 100644 examples/salesforce-new-contact-to-twilio-sms/main.bal diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/.devcontainer.json b/examples/ftp-edi-message-to-salesforce-opportunity/.devcontainer.json deleted file mode 100644 index 6269c065..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/.devcontainer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "image": "ballerina/ballerina-devcontainer:2201.7.0", - "extensions": ["WSO2.ballerina"], -} diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/.gitignore b/examples/ftp-edi-message-to-salesforce-opportunity/.gitignore deleted file mode 100644 index d0bbdca4..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -target -generated -Config.toml -test_input diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/Ballerina.toml b/examples/ftp-edi-message-to-salesforce-opportunity/Ballerina.toml deleted file mode 100644 index 9cce1c5c..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/Ballerina.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -org = "salesforce_examples" -name = "ftp_edi_message_to_salesforce_opportunity" -version = "0.1.0" -distribution = "2201.7.0" - -[build-options] -observabilityIncluded = true diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/README.md b/examples/ftp-edi-message-to-salesforce-opportunity/README.md deleted file mode 100644 index dec92a6b..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# FTP B2B EDI message to Salesforce opportunity - -This sample reads EDI files from a given FTP location, converts those EDI messages to Ballerina records, and creates a Salesforce opportunity for each EDI message. - -## Use case - -Business-to-Business(B2B) communications are commonly performed via EDI messages. Therefore, it's critical to integrate B2B messaging channels with internal IT to streamline and automate business processes. In this context, this sample shows how EDI messages containing requests for quotes (EDIFACT REQOTE) can be used to automatically create opportunities in Salesforce, and add all products in a quote as products associated with the opportunity. - -## Prerequisites -* Salesforce account -* FTP server - -### Setting up the Salesforce account -1. Visit [Salesforce](https://www.salesforce.com/) and create a Salesforce Account. -2. Create a connected app and obtain the following credentials: - * Base URL (Endpoint) - * Access Token - * Client ID - * Client Secret - * Refresh Token - * Refresh Token URL -3. When you are setting up the connected app, select the following scopes under Selected OAuth Scopes: - * Access and manage your data (api) - * Perform requests on your behalf at any time (refresh_token, offline_access) - * Provide access to your data via the Web (web) -4. Provide the client ID and client secret to obtain the refresh token and access token. For more information on obtaining OAuth2 credentials, go to [Salesforce documentation](https://help.salesforce.com/articleView?id=remoteaccess_authenticate_overview.htm). -5. Fill in details under the `Salesforce configuration` in the `Config.toml` with Salesforce access details. -6. Create a sample Account named `TechShop` in Salesforce. -7. Create two Products in Salesforce and obtain product IDs. Replace `` and `` place holders in `resoures/inputs/quote1.edi` and `resources/inputs/quote2.edi` with product IDs. -8. Create a PriceBook in Salesforce and fill the `salesforcePriceBookId` entry in `Config.toml` with the price book ID. Add prices for products created in step 7 to the price book. - -### Setting up an FTP server -1. Start FTP server using the command below. -```docker run -d -p :21 -p 21000-21010:21000-21010 -e USERS="|" -e ADDRESS=localhost delfer/alpine-ftp-server``` -(E.g. ```docker run -d -p 2100:21 -p 21000-21010:21000-21010 -e USERS="user1|pass1" -e ADDRESS=localhost delfer/alpine-ftp-server```). -Note that any FTP server with read and write access can be used for this sample. If an FTP server is available, skip this point. -2. Create two folders in the FTP server for input EDI files and processed EDI files (E.g. `samples/new-quotes`, `samples/processed-quotes`) -3. Copy files in the resources/inputs folder to the FTP folder created for input EDI files. -4. Fill in fields under the `FTP configuration` section in `Config.toml` with FTP server details and paths for EDI files. - -### Config.toml -``` -salesforcePriceBookId = "" -ftpNewQuotesPath = "" -ftpProcessedQuotesPath = "" - -# ========================== -# FTP configuration -# ========================== - -[ftpConfig] -protocol = "ftp" -host = "localhost" -port = - -[ftpConfig.auth.credentials] -username = "" -password = "" - -# ========================== -# Salesforce configuration -# ========================== - -[salesforceConfig] -baseUrl = "" - -[salesforceConfig.auth] -clientId = "" -clientSecret = "" -refreshToken = "" -refreshUrl = "" -``` - -## Testing - -1. Make sure the FTP server is running. -2. Run the sample using the `bal run` command. -3. Log in to Salesforce and check opportunities. Two new opportunities will be created, one for each EDI file. -4. Check FTP locations. Both EDI files will be moved to the process-quotes folder. - diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/main.bal b/examples/ftp-edi-message-to-salesforce-opportunity/main.bal deleted file mode 100644 index 1739defb..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/main.bal +++ /dev/null @@ -1,120 +0,0 @@ -import ballerina/ftp; -import ballerina/io; -import ballerinax/edifact.d03a.retail.mREQOTE; -import ballerinax/salesforce as sf; -configurable ftp:ClientConfiguration ftpConfig = ?; -configurable string ftpNewQuotesPath = ?; -configurable string ftpProcessedQuotesPath = ?; -configurable sf:ConnectionConfig salesforceConfig = ?; -configurable string salesforcePriceBookId = ?; -sf:Client salesforce = check new (salesforceConfig); -ftp:Client fileServer = check new ftp:Client(ftpConfig); -public function main() returns error? { - ftp:FileInfo[] quoteList = check fileServer->list(ftpNewQuotesPath); - foreach ftp:FileInfo quoteFile in quoteList { - stream fileStream = check fileServer->get(quoteFile.path); - string quoteText = check streamToString(fileStream); - mREQOTE:EDI_REQOTE_Request_for_quote_message quote = check mREQOTE:fromEdiString(quoteText); - QuoteRequest quoteRequest = check transformQuoteRequest(quote); - stream accQuery = check salesforce->query( - string `SELECT Id FROM Account WHERE Name = '${quoteRequest.accountName}'` - ); - record {|Id value;|}? account = check accQuery.next(); - check accQuery.close(); - if account is () { - return error("Account not found. Account name: " + quoteRequest.accountName); - } - Opportunity opp = { - Name: quoteRequest.oppName, - AccountId: account.value.Id, - Pricebook2Id: salesforcePriceBookId - }; - string oppId = check getOpportunityId(salesforce, quoteRequest, opp); - check createOpportunityLineItems(quoteRequest, oppId); - } -} -function createOpportunityLineItems(QuoteRequest quoteRequest, string oppId) returns error? { - foreach ItemData item in quoteRequest.itemData { - stream query = check salesforce->query( - string `SELECT UnitPrice FROM PricebookEntry WHERE Pricebook2Id = - '01s6C000000UN4PQAW' AND Product2Id = '${item.itemId}'` - ); - record {|PriceBookEntry value;|}? unionResult = check query.next(); - check query.close(); - if unionResult is () { - return error(string `Pricebook entry not found. Opportunity name: ${quoteRequest.oppName}, Item ID: ${item.itemId}`); - } - OpportunityProduct oppProduct = { - OpportunityId: oppId, - Product2Id: item.itemId, - Quantity: item.quantity, - UnitPrice: unionResult.value.UnitPrice - }; - _ = check salesforce->create("OpportunityLineItem", oppProduct); - } -} -function getOpportunityId(sf:Client salesforce, QuoteRequest quoteRequest, Opportunity opp) returns string|error { - string oppId = ""; - stream oppQuery = check salesforce->query( - string `SELECT Id FROM Opportunity WHERE Name = '${quoteRequest.oppName}'`); - record {|Id value;|}? existingOpp = check oppQuery.next(); - check oppQuery.close(); - if existingOpp is () { - sf:CreationResponse oppResult = check salesforce->create("Opportunity", opp); - oppId = oppResult.id; - } else { - oppId = existingOpp.value.Id; - } - return oppId; -} -function transformQuoteRequest(mREQOTE:EDI_REQOTE_Request_for_quote_message quote) returns QuoteRequest|error { - QuoteRequest quoteRequest = {accountName: "", oppName: ""}; - mREQOTE:Segment_group_1_GType[] segmentGroup1 = quote.Segment_group_1; - foreach mREQOTE:Segment_group_1_GType ref in segmentGroup1 { - if ref.REFERENCE.REFERENCE.Reference_code_qualifier == "AES" { - string? oppId = ref.REFERENCE.REFERENCE.Reference_identifier; - if oppId is () { - return error("Opportunity ID is not given"); - } - quoteRequest.oppName = oppId; - } - } - mREQOTE:Segment_group_11_GType[] segmentGroup11 = quote.Segment_group_11; - foreach mREQOTE:Segment_group_11_GType party in segmentGroup11 { - if party.NAME_AND_ADDRESS.Party_function_code_qualifier == "BY" { - string? prospectId = party.NAME_AND_ADDRESS?.PARTY_IDENTIFICATION_DETAILS?.Party_identifier; - if prospectId is () { - return error("Prospect identifier not available in quote."); - } - quoteRequest.accountName = prospectId; - } - } - mREQOTE:Segment_group_27_GType[] items = quote.Segment_group_27; - foreach mREQOTE:Segment_group_27_GType item in items { - string? itemId = item.LINE_ITEM.Line_item_identifier; - if itemId is () { - return error("Item ID is not given"); - } - ItemData itemData = {itemId}; - mREQOTE:QUANTITY_Type[] quantities = item.QUANTITY; - foreach mREQOTE:QUANTITY_Type quantity in quantities { - if quantity.QUANTITY_DETAILS.Quantity_type_code_qualifier == "21" { - int|error amount = int:fromString(quantity.QUANTITY_DETAILS.Quantity); - if amount is error { - return error("Quantity must be a valid number."); - } - itemData.quantity = amount; - break; - } - } - quoteRequest.itemData.push(itemData); - } - return quoteRequest; -} -function streamToString(stream inStream) returns string|error { - byte[] content = []; - check inStream.forEach(function(byte[] & readonly chunk) { - content.push(...chunk); - }); - return string:fromBytes(content); -} \ No newline at end of file diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote1.edi b/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote1.edi deleted file mode 100644 index 24bf9064..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote1.edi +++ /dev/null @@ -1,8 +0,0 @@ -BGM+930+1001' -DTM+137:20230815:102' -RFF+AES:TS_035' -NAD+BY+TechShop' -LIN+' -QTY+21:10' -UNS+S' -UNT+8+1' diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote2.edi b/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote2.edi deleted file mode 100644 index 662ce9ab..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/resources/inputs/quote2.edi +++ /dev/null @@ -1,10 +0,0 @@ -BGM+930+1002' -DTM+137:20230819:102' -RFF+AES:TS_015' -NAD+BY+TechShop' -LIN+' -QTY+21:25' -LIN+' -QTY+21:18' -UNS+S' -UNT+8+1' diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/transformer.bal b/examples/ftp-edi-message-to-salesforce-opportunity/transformer.bal deleted file mode 100644 index 204fcaeb..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/transformer.bal +++ /dev/null @@ -1,45 +0,0 @@ -import ballerinax/edifact.d03a.retail.mREQOTE; -function transformQuoteRequest(mREQOTE:EDI_REQOTE_Request_for_quote_message quote) returns QuoteRequest|error { - QuoteRequest quoteRequest = {accountName: "", oppName: ""}; - mREQOTE:Segment_group_1_GType[] segmentGroup1 = quote.Segment_group_1; - foreach mREQOTE:Segment_group_1_GType ref in segmentGroup1 { - if ref.REFERENCE.REFERENCE.Reference_code_qualifier == "AES" { - string? oppId = ref.REFERENCE.REFERENCE.Reference_identifier; - if oppId is () { - return error("Opportunity ID is not given"); - } - quoteRequest.oppName = oppId; - } - } - mREQOTE:Segment_group_11_GType[] segmentGroup11 = quote.Segment_group_11; - foreach mREQOTE:Segment_group_11_GType party in segmentGroup11 { - if party.NAME_AND_ADDRESS.Party_function_code_qualifier == "BY" { - string? prospectId = party.NAME_AND_ADDRESS?.PARTY_IDENTIFICATION_DETAILS?.Party_identifier; - if prospectId is () { - return error("Prospect identifier not available in quote."); - } - quoteRequest.accountName = prospectId; - } - } - mREQOTE:Segment_group_27_GType[] items = quote.Segment_group_27; - foreach mREQOTE:Segment_group_27_GType item in items { - string? itemId = item.LINE_ITEM.Line_item_identifier; - if itemId is () { - return error("Item ID is not given"); - } - ItemData itemData = {itemId}; - mREQOTE:QUANTITY_Type[] quantities = item.QUANTITY; - foreach mREQOTE:QUANTITY_Type quantity in quantities { - if quantity.QUANTITY_DETAILS.Quantity_type_code_qualifier == "21" { - int|error amount = int:fromString(quantity.QUANTITY_DETAILS.Quantity); - if amount is error { - return error("Quantity must be a valid number."); - } - itemData.quantity = amount; - break; - } - } - quoteRequest.itemData.push(itemData); - } - return quoteRequest; -} \ No newline at end of file diff --git a/examples/ftp-edi-message-to-salesforce-opportunity/types.bal b/examples/ftp-edi-message-to-salesforce-opportunity/types.bal deleted file mode 100644 index 8d2b9eef..00000000 --- a/examples/ftp-edi-message-to-salesforce-opportunity/types.bal +++ /dev/null @@ -1,39 +0,0 @@ -type QuoteRequest record {| - string oppName; - string accountName; - ItemData[] itemData = []; -|}; - -type ItemData record {| - string itemId; - int quantity = 0; -|}; - -type Id record {| - string Id; -|}; - -type PriceBookEntry record {| - decimal UnitPrice; -|}; - -type OpportunityProduct record {| - string OpportunityId; - string Working_with_3rd_party__c = "No"; - string Product2Id; - int Quantity; - decimal UnitPrice; -|}; - -type Opportunity record {| - string Name; - string CurrencyIsoCode = "USD"; - string LeadSource = "Customer Inbound"; - string AccountId; - string ForecastCategoryName = "Pipeline"; - string CloseDate = "2023-12-18"; - string StageName = "40 - Negotiation/Review"; - string Confidence__c = "Low"; - string Pricebook2Id = "01s6C000000UN4PQAW"; - string Working_with_3rd_party__c = "No"; -|}; diff --git a/examples/gmail-to-salesforce-lead/.gitignore b/examples/gmail-to-salesforce-lead/.gitignore deleted file mode 100644 index 7512ebe2..00000000 --- a/examples/gmail-to-salesforce-lead/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target -generated -Config.toml diff --git a/examples/gmail-to-salesforce-lead/Ballerina.toml b/examples/gmail-to-salesforce-lead/Ballerina.toml deleted file mode 100644 index 5995c893..00000000 --- a/examples/gmail-to-salesforce-lead/Ballerina.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -org = "salesforce_examples" -name = "gmail_to_salesforce_lead" -version = "0.1.0" -distribution = "2201.7.0" - -[build-options] -observabilityIncluded = true diff --git a/examples/gmail-to-salesforce-lead/Dependencies.toml b/examples/gmail-to-salesforce-lead/Dependencies.toml deleted file mode 100644 index 4598e5a0..00000000 --- a/examples/gmail-to-salesforce-lead/Dependencies.toml +++ /dev/null @@ -1,410 +0,0 @@ -# AUTO-GENERATED FILE. DO NOT MODIFY. - -# This file is auto-generated by Ballerina for managing dependency versions. -# It should not be modified by hand. - -[ballerina] -dependencies-toml-version = "2" -distribution-version = "2201.7.1" - -[[package]] -org = "ballerina" -name = "auth" -version = "2.9.0" -dependencies = [ - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "log"} -] - -[[package]] -org = "ballerina" -name = "cache" -version = "3.6.0" -dependencies = [ - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "task"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "constraint" -version = "1.3.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "crypto" -version = "2.4.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "file" -version = "1.8.1" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "os"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "http" -version = "2.9.2" -dependencies = [ - {org = "ballerina", name = "auth"}, - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "file"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "jwt"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.decimal"}, - {org = "ballerina", name = "lang.int"}, - {org = "ballerina", name = "lang.regexp"}, - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "lang.value"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "mime"}, - {org = "ballerina", name = "oauth2"}, - {org = "ballerina", name = "observe"}, - {org = "ballerina", name = "time"}, - {org = "ballerina", name = "url"} -] - -[[package]] -org = "ballerina" -name = "io" -version = "1.5.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.value"} -] - -[[package]] -org = "ballerina" -name = "jballerina.java" -version = "0.0.0" - -[[package]] -org = "ballerina" -name = "jwt" -version = "2.9.0" -dependencies = [ - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.int"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "lang.__internal" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.object"} -] - -[[package]] -org = "ballerina" -name = "lang.array" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.__internal"} -] - -[[package]] -org = "ballerina" -name = "lang.boolean" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.decimal" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.float" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.int" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.__internal"}, - {org = "ballerina", name = "lang.object"} -] - -[[package]] -org = "ballerina" -name = "lang.object" -version = "0.0.0" - -[[package]] -org = "ballerina" -name = "lang.regexp" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.runtime" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "lang.runtime", moduleName = "lang.runtime"} -] - -[[package]] -org = "ballerina" -name = "lang.string" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.regexp"} -] - -[[package]] -org = "ballerina" -name = "lang.value" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.xml" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "log" -version = "2.8.1" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.value"}, - {org = "ballerina", name = "observe"} -] -modules = [ - {org = "ballerina", packageName = "log", moduleName = "log"} -] - -[[package]] -org = "ballerina" -name = "mime" -version = "2.8.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.int"} -] -modules = [ - {org = "ballerina", packageName = "mime", moduleName = "mime"} -] - -[[package]] -org = "ballerina" -name = "oauth2" -version = "2.9.0" -dependencies = [ - {org = "ballerina", name = "cache"}, - {org = "ballerina", name = "crypto"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "time"}, - {org = "ballerina", name = "url"} -] - -[[package]] -org = "ballerina" -name = "observe" -version = "1.1.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "os" -version = "1.7.0" -dependencies = [ - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "regex" -version = "1.4.3" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.string"} -] - -[[package]] -org = "ballerina" -name = "task" -version = "2.4.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "time"} -] - -[[package]] -org = "ballerina" -name = "time" -version = "2.3.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "url" -version = "2.3.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerinai" -name = "observe" -version = "0.0.0" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "observe"} -] -modules = [ - {org = "ballerinai", packageName = "observe", moduleName = "observe"} -] - -[[package]] -org = "ballerinax" -name = "client.config" -version = "1.0.1" -dependencies = [ - {org = "ballerina", name = "http"}, - {org = "ballerina", name = "oauth2"} -] - -[[package]] -org = "ballerinax" -name = "googleapis.gmail" -version = "3.5.0" -dependencies = [ - {org = "ballerina", name = "http"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "mime"}, - {org = "ballerina", name = "os"}, - {org = "ballerina", name = "regex"}, - {org = "ballerina", name = "url"}, - {org = "ballerinai", name = "observe"}, - {org = "ballerinax", name = "client.config"} -] -modules = [ - {org = "ballerinax", packageName = "googleapis.gmail", moduleName = "googleapis.gmail"} -] - -[[package]] -org = "ballerinax" -name = "openai.chat" -version = "1.1.2" -dependencies = [ - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "http"}, - {org = "ballerina", name = "url"}, - {org = "ballerinai", name = "observe"} -] -modules = [ - {org = "ballerinax", packageName = "openai.chat", moduleName = "openai.chat"} -] - -[[package]] -org = "ballerinax" -name = "salesforce" -version = "7.5.1" -dependencies = [ - {org = "ballerina", name = "http"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.boolean"}, - {org = "ballerina", name = "lang.float"}, - {org = "ballerina", name = "lang.int"}, - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "lang.string"}, - {org = "ballerina", name = "lang.xml"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "os"}, - {org = "ballerina", name = "regex"}, - {org = "ballerina", name = "url"}, - {org = "ballerinai", name = "observe"}, - {org = "ballerinax", name = "client.config"} -] -modules = [ - {org = "ballerinax", packageName = "salesforce", moduleName = "salesforce"}, - {org = "ballerinax", packageName = "salesforce", moduleName = "salesforce.bulk"}, - {org = "ballerinax", packageName = "salesforce", moduleName = "salesforce.soap"}, - {org = "ballerinax", packageName = "salesforce", moduleName = "salesforce.utils"} -] - -[[package]] -org = "integration_samples" -name = "gmail_to_salesforce_lead" -version = "0.1.0" -dependencies = [ - {org = "ballerina", name = "lang.runtime"}, - {org = "ballerina", name = "log"}, - {org = "ballerina", name = "mime"}, - {org = "ballerinai", name = "observe"}, - {org = "ballerinax", name = "googleapis.gmail"}, - {org = "ballerinax", name = "openai.chat"}, - {org = "ballerinax", name = "salesforce"} -] -modules = [ - {org = "integration_samples", packageName = "gmail_to_salesforce_lead", moduleName = "gmail_to_salesforce_lead"} -] - diff --git a/examples/gmail-to-salesforce-lead/README.md b/examples/gmail-to-salesforce-lead/README.md deleted file mode 100644 index ceee3ecf..00000000 --- a/examples/gmail-to-salesforce-lead/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# Email Lead Info into Salesforce using OpenAI. -This sample creates a lead on [Salesforce](https://salesforce.com) for each email marked with a specific label on [Gmail](https://mail.google.com) using the [OpenAI](https://openai.com) chat API to infer customer details. - -## Use case -The following sample demonstrates a scenario in which customer leads obtained through email are automatically pushed to Salesforce. The required details for the lead (name, company, designation, etc.) are inferred from the content of the email and the OpenAI chat API. - -When the user receives an email pertaining to a lead, they will mark that thread with a specific label (e.g., `"Lead"`). This Ballerina program will run continuously in the background, polling the email server every 10 minutes for threads marked with this label. If an email is found, its content will be read and used to infer the following details -* First name -* Last name -* Phone number -* Email address -* Company name -* Designation - -Once these details have been inferred, a new lead will be generated on Salesforce. - -![Flow diagram](/gmail-to-salesforce-lead/docs/images/flow-diagram.png) - -## Prerequisites -* An email account configured to use [Gmail](https://mail.google.com) -* An account on the [Google Cloud Platform](https://console.cloud.google.com) -* An [OpenAI](https://openai.com) account with API usage enabled -* A [Salesforce](https://salesforce.com) account - ->Note: The following steps will require you to generate keys for the Gmail, OpenAI and Salesforce APIs. These keys will have to be securely stored in the `Config.toml` file in the project directory under the relevant fields. - -### Configuring your email account to use Gmail -> Note: If you already have a Gmail account (ending with `@gmail.com`) or your account is on the Google workspace, you do not need to follow the steps below. In essence, if you can access your email via `www.gmail.com`, the following is not necessary. -1. Visit [Gmail](https://gmail.com) and create a new account or log into an existing account. -2. Enter the `Accounts` tab under settings and click on `Add a mail account`. -3. Provide the necessary authentication details to your email account. -4. After adding a mail account, you should be able to see all new emails received to your email via the Gmail interface. - -### Obtaining the Gmail API keys -1. Create a new [Google Cloud Platform project](https://console.cloud.google.com). -2. Find and click `APIs & Services` --> `Library` from the navigation menu. -3. In the search box, enter `"Gmail"`. -4. Then select Gmail API and click `Enable` button. -5. Complete the OAuth consent screen setup. -6. Click the `Credential` tab from the left sidebar. In the displaying window click on the `Create Credentials` button and select OAuth client ID. -7. Fill in the required fields. Add `"https://developers.google.com/oauthplayground"` to the Redirect URI field. -8. Note down the `clientId` and `clientSecret`. -9. Visit https://developers.google.com/oauthplayground/. Go to settings (Top right corner) -> Tick 'Use your own OAuth credentials' and insert Oauth ClientId and clientSecret. Click close. -10. Then, Complete Step1 (Select and Authorize APIs) -11. Make sure you select the `"https://www.googleapis/auth/gmail.modify"` and `"https://www.googleapis/auth/gmail.labels` OAuth scopes. These two scopes will allow the program to read emails, including adding/removing labels. -12. Click `Authorize APIs`, and you will be in step 2. -13. Exchange Auth code for tokens. -14. Copy the `Access token` and enter it on the `Config.toml` file. - -### Obtaining an OpenAI key -1. Create an [OpenAI account](https://platform.openai.com). -2. If you are eligible for a free trial of the OpenAI API, use that. Otherwise, set up your [billing information](https://platform.openai.com/account/billing/overview). -3. Obtain your [API key](https://platform.openai.com/account/api-keys) and include it in the `Config.toml` file. - -### Setting up the Salesforce account -1. Visit [Salesforce](https://www.salesforce.com/) and create a Salesforce account. -2. Create a connected app and obtain the following credentials: - * Base URL (Endpoint) - * Client ID - * Client Secret - * Refresh Token - * Refresh Token URL -3. When you are setting up the connected app, select the following scopes under Selected OAuth Scopes: - * Access and manage your data (api) - * Perform requests on your behalf at any time (refresh_token, offline_access) - * Provide access to your data via the Web (web) -4. Provide the client ID and client secret to obtain the refresh token and access token. For more information on obtaining OAuth2 credentials, go to [Salesforce documentation](https://help.salesforce.com/articleView?id=remoteaccess_authenticate_overview.htm). -5. Once you have obtained the access token, include it in the `Config.toml` file. - -## Configuration -Create a file called `Config.toml` at the root of the project. - -### Config.toml -``` -gmailAccessToken = "" -openAIKey = "" -salesforceBaseUrl = "https://.salesforce.com" -salesforceAccessToken = "" -``` -### Configuration -1. Obtain the relevant OAuth access tokens for `Google Drive` and `Microsoft One Drive` configurations. -2. Obtain the folder ID of the Google Drive folder you want to sync. -3. Obtain the path of the OneDrive folder you want to sync. -4. Once you have obtained all configurations, Create the `Config.toml` file in the root directory. -5. Replace the necessary fields in the `Config.toml` file with your data. - -## Testing - -### Adding labels -In Gmail, we can use a label to mark an email under several categories. These labels can be manually added to email threads by the user or can be automatically added based on user-provided rules as well. For this sample, we will use a custom label to mark emails pertaining to a lead generation as `"Lead"`. - -1. Log into your Gmail account. -2. Create a new label named `"Lead"` from the `Labels` tab under `Settings` -3. Whenever you receive an email pertaining to a lead generation, add the newly created label to it by clicking on the Labels icon above the thread. - -### Running the project -1. Execute the ballerina project by executing `bal run` in the project directory. -2. You should see the emails you've marked as `LEAD` should have the label removed and a new lead should be created on Salesforce. diff --git a/examples/gmail-to-salesforce-lead/docs/images/flow-diagram.png b/examples/gmail-to-salesforce-lead/docs/images/flow-diagram.png deleted file mode 100644 index 9a72de9519e9833149ce87daf8e79991f43ea85f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48376 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 TN^}J<6_R=_|Efe(Kj41=xqn!^ diff --git a/examples/gmail-to-salesforce-lead/main.bal b/examples/gmail-to-salesforce-lead/main.bal deleted file mode 100644 index f935adbd..00000000 --- a/examples/gmail-to-salesforce-lead/main.bal +++ /dev/null @@ -1,85 +0,0 @@ -import ballerina/mime; -import ballerinax/googleapis.gmail; -import ballerinax/openai.chat; -import ballerinax/salesforce as sf; - -configurable string gmailAccessToken = ?; -configurable string openAIKey = ?; -configurable string salesforceBaseUrl = ?; -configurable string salesforceAccessToken = ?; - -gmail:Client gmail = check new ({auth: {token: gmailAccessToken}}); -chat:Client openAiChat = check new ({auth: {token: openAIKey}}); -sf:Client salesforce = check new ({baseUrl: salesforceBaseUrl, auth: {token: salesforceAccessToken}}); - -public function main() returns error? { - gmail:LabelList labelList = check gmail->listLabels("me"); - Email[] emails = check getMatchingEmails(labelList); - foreach Email email in emails { - chat:CreateChatCompletionRequest request = { - model: "gpt-3.5-turbo", - messages: [ - { - role: "user", - content: string `Extract the following details in JSON from the email. - { - firstName__c: string, // Mandatory - lastName__c: string, // Mandatory - email__c: string // Mandatory - phoneNumber__c: string, // With country code. Use N/A if unable to find - company__c: string, // Mandatory - designation__c: string // Not mandatory. Use N/A if unable to find - } - Here is the email: - { - from: ${email.'from}, - subject: ${email.subject}, - body: ${email.body} - }` - } - ] - }; - chat:CreateChatCompletionResponse response = check openAiChat->/chat/completions.post(request); - if response.choices.length() < 1 { - return error("Unable to find any choices in the response."); - } - string content = check response.choices[0].message?.content.ensureType(string); - _ = check salesforce->create("EmailLead__c", check content.fromJsonStringWithType(Lead)); - - } -} - -function getMatchingEmails(gmail:LabelList labelList) returns Email[]|error { - string[] labelIdsToMatch = from gmail:Label {name, id} in labelList.labels - where ["Lead"].indexOf(name) != () - select id; - gmail:MsgSearchFilter searchFilter = { - includeSpamTrash: false, - labelIds: labelIdsToMatch - }; - gmail:MailThread[] matchingMailThreads = check from gmail:MailThread mailThread - in check gmail->listThreads(filter = searchFilter) - select mailThread; - foreach gmail:MailThread mailThread in matchingMailThreads { - _ = check gmail->modifyThread(mailThread.id, [], labelIdsToMatch); - } - gmail:Message[] matchingEmails = []; - foreach gmail:MailThread mailThread in matchingMailThreads { - gmail:MailThread response = check gmail->readThread(mailThread.id); - matchingEmails.push((response.messages)[0]); - } - Email[] emails = from gmail:Message message in matchingEmails - select check parseEmail(message); - return emails; -} - -function parseEmail(gmail:Message message) returns Email|error { - gmail:MessageBodyPart bodyPart = check message.emailBodyInText.ensureType(gmail:MessageBodyPart); - string bodyPartText = check bodyPart.data.ensureType(string); - string body = check mime:base64Decode(bodyPartText).ensureType(string); - return { - 'from: check message.headerFrom.ensureType(string), - subject: check message.headerSubject.ensureType(string), - body: body - }; -} diff --git a/examples/gmail-to-salesforce-lead/types.bal b/examples/gmail-to-salesforce-lead/types.bal deleted file mode 100644 index 2f576233..00000000 --- a/examples/gmail-to-salesforce-lead/types.bal +++ /dev/null @@ -1,18 +0,0 @@ -type Email record {| - string 'from; - string subject; - string body; -|}; - -type Name record {| - string firstName__c; - string lastName__c; -|}; - -type Lead record {| - *Name; - string email__c; - string phoneNumber__c; - string company__c; - string designation__c; -|}; diff --git a/examples/kafka_salesforce_integration/kafka-message-producer/Ballerina.toml b/examples/kafka_salesforce_integration/kafka-message-producer/Ballerina.toml deleted file mode 100644 index 3a008806..00000000 --- a/examples/kafka_salesforce_integration/kafka-message-producer/Ballerina.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -org = "salesforce_examples" -name = "kafka_message_producer" -version = "0.1.0" -distribution = "2201.7.0" - -[build-options] -observabilityIncluded = true diff --git a/examples/kafka_salesforce_integration/kafka-message-producer/main.bal b/examples/kafka_salesforce_integration/kafka-message-producer/main.bal deleted file mode 100644 index 2a26e011..00000000 --- a/examples/kafka_salesforce_integration/kafka-message-producer/main.bal +++ /dev/null @@ -1,23 +0,0 @@ -import ballerina/http; -import ballerinax/kafka; - -public type ProductPrice readonly & record {| - string name; - float unitPrice; -|}; - -service / on new http:Listener(9090) { - private final kafka:Producer kafka; - - function init() returns error? { - self.kafka = check new (kafka:DEFAULT_URL); - } - - resource function post orders(@http:Payload anydata productPrice) returns http:Accepted|error { - check self.kafka->send({ - topic: "product-price-updates", - value: productPrice - }); - return http:ACCEPTED; - } -} diff --git a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Ballerina.toml b/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Ballerina.toml deleted file mode 100644 index c3caadd1..00000000 --- a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Ballerina.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -org = "salesforce_examples" -name = "kafka_salesforce_pricebook_update" -version = "0.1.0" -distribution = "2201.7.0" - -[build-options] -observabilityIncluded = true diff --git a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Docs/Flow diagram.png b/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Docs/Flow diagram.png deleted file mode 100644 index 0432cd3a064ecd9a35231f70d506926daeed9b34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176544 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%0A%TFc{GL0B`ge=rSF&SJ`B^va&wyp;6ev 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 diff --git a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Readme.md b/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Readme.md deleted file mode 100644 index fbbe3f86..00000000 --- a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/Readme.md +++ /dev/null @@ -1,51 +0,0 @@ -# Kafka Message to Salesforce Price Book Update - -This example updates the product price in the [Salesforce](https://www.salesforce.com/) price book through [Kafka](https://kafka.apache.org/) and Salesforce integration. - -## Use case -Apache Kafka is a distributed event store and stream-processing platform, widely used for enterprise messaging applications. - -Organizations maintain details about products in various data stores such as ERP systems, databases, etc. Different business units can update these data stores. As these updates roll out, it's essential to implement reliable communication between business units and data stores to update data across all systems consistently. - -The following sample demonstrates a scenario in which a product's price in a price book in Salesforce is updated with product details fetched from a Kafka topic whenever a new message is received. - -## Prerequisites -* Salesforce account -* Install Kafka - -### Setting up a Salesforce account -1. Visit [Salesforce](https://www.salesforce.com/) and create a Salesforce Account. -2. Create a connected app and obtain the following credentials: - * Base URL (Endpoint) - * Access Token - * Client ID - * Client Secret - * Refresh Token - * Refresh Token URL -3. When you are setting up the connected app, select the following scopes under Selected OAuth Scopes: - * Access and manage your data (API) - * Perform requests on your behalf at any time (refresh_token, offline_access) - * Provide access to your data via the Web (web) -4. Provide the client ID and client secret to obtain the refresh token and access token. For more information on obtaining OAuth2 credentials, go to [Salesforce documentation](https://help.salesforce.com/articleView?id=remoteaccess_authenticate_overview.htm). -5. Once you obtained all configurations, add those to the `Config.toml` file. - -### Setting up Kafka. -1. To test in local machines, install the Kafka to your machine and start the server. You can follow the steps [here](https://kafka.apache.org/quickstart). - -## Configuration -Create a file called `Config.toml` at the root of the project. - -### Config.toml -``` -[.kafka_salesforce_pricebook_update] -salesforceBaseUrl = "" -salesforceAccessToken = "" -salesforcePriceBookId = "" -``` - -## Testing -1. First, run the kafka-message-producer to start the Kafka producer. -2. Start the Kafka subscriber by running the kafka-salesforce-pricebook_update. -3. Then send the required message to Kafka producer using `curl http://localhost:9090/orders -H "Content-type:application/json" -d "{\"name\": \"\", \"unitPrice\": }"`. - -When the new message is published to the Kafka topic, the subscriber will update the new price in the Salesforce price book. diff --git a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/main.bal b/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/main.bal deleted file mode 100644 index d3b33966..00000000 --- a/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update/main.bal +++ /dev/null @@ -1,45 +0,0 @@ -import ballerinax/kafka; -import ballerinax/salesforce; - -configurable string salesforceAccessToken = ?; -configurable string salesforceBaseUrl = ?; -configurable string salesforcePriceBookId = ?; - -public type ProductPrice readonly & record {| - string name; - float unitPrice; -|}; - -public type ProductPriceUpdate readonly & record {| - float UnitPrice; -|}; - -listener kafka:Listener priceListener = new (kafka:DEFAULT_URL, { - groupId: "order-group-id", - topics: "product-price-updates" -}); - -final salesforce:Client salesforce = check new ({ - baseUrl: salesforceBaseUrl, - auth: { - token: salesforceAccessToken - } -}); - -service on priceListener { - isolated remote function onConsumerRecord(ProductPrice[] prices) returns error? { - foreach ProductPrice {name, unitPrice} in prices { - stream retrievedStream = check salesforce->query( - string `SELECT Id FROM PricebookEntry - WHERE Pricebook2Id = '${salesforcePriceBookId}' AND - Name = '${name}'`); - record {}[] retrieved = check from record {} entry in retrievedStream - select entry; - anydata pricebookEntryId = retrieved[0]["Id"]; - if pricebookEntryId is string { - ProductPriceUpdate updatedPrice = {UnitPrice: unitPrice}; - check salesforce->update("PricebookEntry", pricebookEntryId, updatedPrice); - } - } - } -} diff --git a/examples/salesforce-new-contact-to-twilio-sms/Ballerina.toml b/examples/salesforce-new-contact-to-twilio-sms/Ballerina.toml deleted file mode 100644 index 5d1c4194..00000000 --- a/examples/salesforce-new-contact-to-twilio-sms/Ballerina.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -org = "salesforce_examples" -name = "sfdc_new_contact_to_twilio_sms" -distribution = "2201.7.0" -version = "0.1.0" -[build-options] -observabilityIncluded = true diff --git a/examples/salesforce-new-contact-to-twilio-sms/Readme.md b/examples/salesforce-new-contact-to-twilio-sms/Readme.md deleted file mode 100644 index 7c58a962..00000000 --- a/examples/salesforce-new-contact-to-twilio-sms/Readme.md +++ /dev/null @@ -1,52 +0,0 @@ -# Salesforce New Contact to Twilio SMS - -This example sends a [Twilio](https://www.twilio.com/) SMS for every new [Salesforce](https://www.salesforce.com/) contact. - -## Use case -Twilio is a cloud communications platform as a service (CPaaS) company. It allows software developers to programmatically make and receive phone calls, send and receive text messages, and perform other communication functions using its web service APIs. - -As most organizations maintain a well-organized sales process, it is important to follow up with Contacts as soon as they are added to Salesforce. There may be a specific person who wanted to be on alert of new Salesforce contacts. Any time you create a new Contact in Salesforce, an SMS message will be automatically sent to the specific person via Twilio. - -The following sample demonstrates a scenario in which a Twilio SMS message containing all the defined fields in Contacts SObject is sent to a given mobile number when a new Contact is created in Salesforce. - -## Prerequisites -* Twilio account -* Salesforce account - -### Setting up a Salesforce account -1. Create a Salesforce account and create a connected app by visiting [Salesforce](https://www.salesforce.com). -2. Salesforce username and password will be needed for initializing the listener. -3. Once you have obtained all configurations, Replace relevant places in the `Config.toml` file with your data. -4. [Select Objects](https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_select_objects.htm) for Change Notifications in the User Interface of Salesforce account. - -### Setting up a Twilio account -1. Create a [Twilio developer account](https://www.twilio.com/). -2. Obtain the Account SID and Auth Token from the project dashboard. -3. Obtain the phone number from the project dashboard and set it as the value of the `fromNumber` variable in the `Config.toml`. -4. Give a mobile number where the SMS should be sent as the value of the `toNumber` variable in the `Config.toml`. -5. Once you have obtained all configurations, add those to the `Config.toml` file. - -## Configuration -Create a file called `Config.toml` at the root of the project. - -## Config.toml -``` -[.sfdc_new_contact_to_twilio_sms] -fromNumber = "" -toNumber = "" - -[.sfdc_new_contact_to_twilio_sms.salesforceListenerConfig] -username = "" -password = "" - -[.sfdc_new_contact_to_twilio_sms.twilioClientConfig] -accountSId = "" -authToken = "" - -``` -Phone numbers must be provided in E.164 format: +, for example: +16175551212 - -## Testing -Run the Ballerina project created by the integration template by executing `bal run` from the root. - -You can check the Twilio SMS for information related to the new Salesforce Contact. diff --git a/examples/salesforce-new-contact-to-twilio-sms/docs/images/template_flow.png b/examples/salesforce-new-contact-to-twilio-sms/docs/images/template_flow.png deleted file mode 100644 index c8b658c247251ff5bf2232ed49b2411227608053..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26635 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 TyA%KI4-a*p=H86mM}PhwPet6$ diff --git a/examples/salesforce-new-contact-to-twilio-sms/main.bal b/examples/salesforce-new-contact-to-twilio-sms/main.bal deleted file mode 100644 index 353aa569..00000000 --- a/examples/salesforce-new-contact-to-twilio-sms/main.bal +++ /dev/null @@ -1,58 +0,0 @@ -import ballerinax/trigger.salesforce; -import ballerinax/twilio; - -type SalesforceListenerConfig record {| - string username; - string password; -|}; - -type TwilioClientConfig record {| - string accountSId; - string authToken; -|}; - -// Salesforce configuration parameters -configurable SalesforceListenerConfig salesforceListenerConfig = ?; - -// Twilio configuration parameters -configurable TwilioClientConfig twilioClientConfig = ?; -configurable string fromNumber = ?; -configurable string toNumber = ?; - -listener salesforce:Listener sfdcEventListener = new ({ - username: salesforceListenerConfig.username, - password: salesforceListenerConfig.password, - channelName: "/data/ContactChangeEvent" -}); - -final twilio:Client twilio = check new ({ - twilioAuth: { - accountSId: twilioClientConfig.accountSId, - authToken: twilioClientConfig.authToken - } -}); - -service salesforce:RecordService on sfdcEventListener { - isolated remote function onCreate(salesforce:EventData payload) returns error? { - string[] nameParts = re `,`.split(payload.changedData["Name"].toString()); - string firstName = (nameParts.length() >= 2) ? re `=`.split(nameParts[0])[1] : ""; - string lastName = (nameParts.length() >= 2) ? - re `=`.split(re `\}`.replace(nameParts[1], ""))[1] : - re `=`.split(re `\}`.replace(nameParts[0], ""))[1]; - _ = check twilio->sendSms(fromNumber, toNumber, - string `New contact is created! | Name: ${firstName} ${lastName} | Created Date: - ${(check payload.changedData.CreatedDate).toString()}`); - } - - isolated remote function onUpdate(salesforce:EventData payload) returns error? { - return; - } - - isolated remote function onDelete(salesforce:EventData payload) returns error? { - return; - } - - isolated remote function onRestore(salesforce:EventData payload) returns error? { - return; - } -} From 6fa31e6658da554801e69203cf8e76b112379270 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:25:58 +0530 Subject: [PATCH 07/26] move samples to examples --- examples/apex_rest_api_usecases/README.md | 28 +++++++++++++++++++ .../invoke_apex_methods.bal | 0 {samples => examples}/build.gradle | 2 +- {samples => examples}/build.sh | 0 .../bulk-operations-csv/bulk_delete_csv.bal | 0 .../bulk_file_insert_csv.bal | 0 .../bulk-operations-csv/bulk_insert_csv.bal | 0 .../bulk-operations-csv/bulk_query_csv.bal | 0 .../bulk-operations-csv/bulk_update_csv.bal | 0 .../bulk-operations-csv/bulk_upsert_csv.bal | 0 .../bulk-operations-json/bulk_delete_json.bal | 0 .../bulk_file_insert_json.bal | 0 .../bulk-operations-json/bulk_insert_json.bal | 0 .../bulk-operations-json/bulk_query_json.bal | 0 .../bulk-operations-json/bulk_update_json.bal | 0 .../bulk-operations-json/bulk_upsert_json.bal | 0 .../bulk-operations-xml/bulk_delete_xml.bal | 0 .../bulk_file_insert_xml.bal | 0 .../bulk-operations-xml/bulk_insert_xml.bal | 0 .../bulk-operations-xml/bulk_query_xml.bal | 0 .../bulk-operations-xml/bulk_update_xml.bal | 0 .../bulk-operations-xml/bulk_upsert_xml.bal | 0 .../bulkv2_api_usecases/bulkv2_insert.bal | 0 .../find_record_by_query_stream.bal | 0 .../org-metadata-usecases/get_api_version.bal | 0 .../org-metadata-usecases/get_org_limits.bal | 0 .../get_organizational_data.bal | 0 .../get_version_resources.bal | 0 .../search_record_by_string_stream.bal | 0 .../describe_available_objects.bal | 0 .../describe_sobject.bal | 0 .../get_sobject_info.bal | 0 .../get_sobject_platformAction.bal | 0 .../rest_api_usecases/sobject_create.bal | 0 .../rest_api_usecases/sobject_delete.bal | 0 .../rest_api_usecases/sobject_get_by_id.bal | 0 .../rest_api_usecases/sobject_update.bal | 0 .../sojbect_get_record_by_ext.bal | 0 .../soap_api_usecases/convert_lead.bal | 0 settings.gradle | 2 +- 40 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 examples/apex_rest_api_usecases/README.md rename {samples => examples}/apex_rest_api_usecases/invoke_apex_methods.bal (100%) rename {samples => examples}/build.gradle (98%) rename {samples => examples}/build.sh (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal (100%) rename {samples => examples}/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal (100%) rename {samples => examples}/bulkv2_api_usecases/bulkv2_insert.bal (100%) rename {samples => examples}/rest_api_usecases/find_record_by_query_stream.bal (100%) rename {samples => examples}/rest_api_usecases/org-metadata-usecases/get_api_version.bal (100%) rename {samples => examples}/rest_api_usecases/org-metadata-usecases/get_org_limits.bal (100%) rename {samples => examples}/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal (100%) rename {samples => examples}/rest_api_usecases/org-metadata-usecases/get_version_resources.bal (100%) rename {samples => examples}/rest_api_usecases/search_record_by_string_stream.bal (100%) rename {samples => examples}/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal (100%) rename {samples => examples}/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal (100%) rename {samples => examples}/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal (100%) rename {samples => examples}/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal (100%) rename {samples => examples}/rest_api_usecases/sobject_create.bal (100%) rename {samples => examples}/rest_api_usecases/sobject_delete.bal (100%) rename {samples => examples}/rest_api_usecases/sobject_get_by_id.bal (100%) rename {samples => examples}/rest_api_usecases/sobject_update.bal (100%) rename {samples => examples}/rest_api_usecases/sojbect_get_record_by_ext.bal (100%) rename {samples => examples}/soap_api_usecases/convert_lead.bal (100%) diff --git a/examples/apex_rest_api_usecases/README.md b/examples/apex_rest_api_usecases/README.md new file mode 100644 index 00000000..da27e90a --- /dev/null +++ b/examples/apex_rest_api_usecases/README.md @@ -0,0 +1,28 @@ +# Use APEX API + +This example demonstrates how to invoke APEX AREST API of Salesforce. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/samples/apex_rest_api_usecases/invoke_apex_methods.bal b/examples/apex_rest_api_usecases/invoke_apex_methods.bal similarity index 100% rename from samples/apex_rest_api_usecases/invoke_apex_methods.bal rename to examples/apex_rest_api_usecases/invoke_apex_methods.bal diff --git a/samples/build.gradle b/examples/build.gradle similarity index 98% rename from samples/build.gradle rename to examples/build.gradle index 09eae3f6..aa346e8a 100644 --- a/samples/build.gradle +++ b/examples/build.gradle @@ -18,7 +18,7 @@ import org.apache.tools.ant.taskdefs.condition.Os -apply plugin: 'java-library' +apply plugin: 'java' description = 'Ballerina - Salesforce Test samples' diff --git a/samples/build.sh b/examples/build.sh similarity index 100% rename from samples/build.sh rename to examples/build.sh diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal rename to examples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal rename to examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal diff --git a/samples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal similarity index 100% rename from samples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal rename to examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal diff --git a/samples/bulkv2_api_usecases/bulkv2_insert.bal b/examples/bulkv2_api_usecases/bulkv2_insert.bal similarity index 100% rename from samples/bulkv2_api_usecases/bulkv2_insert.bal rename to examples/bulkv2_api_usecases/bulkv2_insert.bal diff --git a/samples/rest_api_usecases/find_record_by_query_stream.bal b/examples/rest_api_usecases/find_record_by_query_stream.bal similarity index 100% rename from samples/rest_api_usecases/find_record_by_query_stream.bal rename to examples/rest_api_usecases/find_record_by_query_stream.bal diff --git a/samples/rest_api_usecases/org-metadata-usecases/get_api_version.bal b/examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal similarity index 100% rename from samples/rest_api_usecases/org-metadata-usecases/get_api_version.bal rename to examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal diff --git a/samples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal b/examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal similarity index 100% rename from samples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal rename to examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal diff --git a/samples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal b/examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal similarity index 100% rename from samples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal rename to examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal diff --git a/samples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal b/examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal similarity index 100% rename from samples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal rename to examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal diff --git a/samples/rest_api_usecases/search_record_by_string_stream.bal b/examples/rest_api_usecases/search_record_by_string_stream.bal similarity index 100% rename from samples/rest_api_usecases/search_record_by_string_stream.bal rename to examples/rest_api_usecases/search_record_by_string_stream.bal diff --git a/samples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal b/examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal similarity index 100% rename from samples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal rename to examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal diff --git a/samples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal b/examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal similarity index 100% rename from samples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal rename to examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal diff --git a/samples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal b/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal similarity index 100% rename from samples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal rename to examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal diff --git a/samples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal b/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal similarity index 100% rename from samples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal rename to examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal diff --git a/samples/rest_api_usecases/sobject_create.bal b/examples/rest_api_usecases/sobject_create.bal similarity index 100% rename from samples/rest_api_usecases/sobject_create.bal rename to examples/rest_api_usecases/sobject_create.bal diff --git a/samples/rest_api_usecases/sobject_delete.bal b/examples/rest_api_usecases/sobject_delete.bal similarity index 100% rename from samples/rest_api_usecases/sobject_delete.bal rename to examples/rest_api_usecases/sobject_delete.bal diff --git a/samples/rest_api_usecases/sobject_get_by_id.bal b/examples/rest_api_usecases/sobject_get_by_id.bal similarity index 100% rename from samples/rest_api_usecases/sobject_get_by_id.bal rename to examples/rest_api_usecases/sobject_get_by_id.bal diff --git a/samples/rest_api_usecases/sobject_update.bal b/examples/rest_api_usecases/sobject_update.bal similarity index 100% rename from samples/rest_api_usecases/sobject_update.bal rename to examples/rest_api_usecases/sobject_update.bal diff --git a/samples/rest_api_usecases/sojbect_get_record_by_ext.bal b/examples/rest_api_usecases/sojbect_get_record_by_ext.bal similarity index 100% rename from samples/rest_api_usecases/sojbect_get_record_by_ext.bal rename to examples/rest_api_usecases/sojbect_get_record_by_ext.bal diff --git a/samples/soap_api_usecases/convert_lead.bal b/examples/soap_api_usecases/convert_lead.bal similarity index 100% rename from samples/soap_api_usecases/convert_lead.bal rename to examples/soap_api_usecases/convert_lead.bal diff --git a/settings.gradle b/settings.gradle index 7952bad9..554e74c1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,7 +30,7 @@ include ":${projectName}-examples" project(':checkstyle').projectDir = file("build-config${File.separator}checkstyle") project(":${projectName}-native").projectDir = file('native') project(":${projectName}-ballerina").projectDir = file('ballerina') -project(":${projectName}-examples").projectDir = file('samples') +project(":${projectName}-examples").projectDir = file('examples') gradleEnterprise { buildScan { From 26e8f8bd84a5859d7fdb0612a5d66ec6eb8c7a06 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:30:50 +0530 Subject: [PATCH 08/26] Update examples in to ballerina projects --- .../create_case/Ballerina.toml | 5 + .../{ => create_case}/README.md | 2 +- .../{ => create_case}/invoke_apex_methods.bal | 5 +- examples/build.sh | 11 +- .../bulk_file_insert_csv.bal | 131 -------------- .../bulk-operations-json/bulk_delete_json.bal | 142 --------------- .../bulk_file_insert_json.bal | 129 ------------- .../bulk-operations-json/bulk_insert_json.bal | 146 --------------- .../bulk-operations-json/bulk_query_json.bal | 119 ------------ .../bulk-operations-json/bulk_update_json.bal | 160 ----------------- .../bulk-operations-json/bulk_upsert_json.bal | 162 ----------------- .../bulk-operations-xml/bulk_delete_xml.bal | 154 ---------------- .../bulk_file_insert_xml.bal | 130 -------------- .../bulk-operations-xml/bulk_insert_xml.bal | 142 --------------- .../bulk-operations-xml/bulk_query_xml.bal | 118 ------------ .../bulk-operations-xml/bulk_update_xml.bal | 167 ----------------- .../bulk-operations-xml/bulk_upsert_xml.bal | 169 ------------------ .../execute_delete_job/Ballerina.toml | 5 + .../execute_delete_job/README.md | 28 +++ .../bulk_delete_csv.bal | 0 .../execute_insert_job/Ballerina.toml | 5 + .../execute_insert_job/README.md | 28 +++ .../bulk_insert_csv.bal | 0 .../execute_query_job/Ballerina.toml | 5 + .../execute_query_job/README.md | 28 +++ .../bulk_query_csv.bal | 0 .../execute_update_job/Ballerina.toml | 5 + .../execute_update_job/README.md | 28 +++ .../bulk_update_csv.bal | 0 .../execute_upsert_job/Ballerina.toml | 5 + .../execute_upsert_job/README.md | 28 +++ .../bulk_upsert_csv.bal | 0 .../execute_bulkv2_ingest_job/Ballerina.toml | 5 + .../execute_bulkv2_ingest_job/README.md | 28 +++ .../bulkv2_insert.bal | 0 .../create_sobjects/Ballerina.toml | 5 + .../create_sobjects/README.md | 28 +++ .../{ => create_sobjects}/sobject_create.bal | 0 .../delete_sobject/Ballerina.toml | 5 + .../delete_sobject/README.md | 28 +++ .../{ => delete_sobject}/sobject_delete.bal | 0 .../get_by_id/Ballerina.toml | 5 + .../rest_api_usecases/get_by_id/README.md | 28 +++ .../{ => get_by_id}/sobject_get_by_id.bal | 0 .../org-metadata-usecases/get_api_version.bal | 51 ------ .../org-metadata-usecases/get_org_limits.bal | 51 ------ .../get_organizational_data.bal | 67 ------- .../get_version_resources.bal | 50 ------ .../describe_available_objects.bal | 57 ------ .../describe_sobject.bal | 52 ------ .../get_sobject_info.bal | 52 ------ .../get_sobject_platformAction.bal | 50 ------ .../sojbect_get_record_by_ext.bal | 51 ------ .../update_sobject/Ballerina.toml | 5 + .../update_sobject/README.md | 28 +++ .../{ => update_sobject}/sobject_update.bal | 0 .../use_query_api/Ballerina.toml | 5 + .../rest_api_usecases/use_query_api/README.md | 28 +++ .../find_record_by_query_stream.bal | 0 .../use_search_api/Ballerina.toml | 5 + .../use_search_api/README.md | 28 +++ .../search_record_by_string_stream.bal | 0 .../convert_lead/Ballerina.toml | 5 + .../soap_api_usecases/convert_lead/README.md | 28 +++ .../{ => convert_lead}/convert_lead.bal | 0 65 files changed, 446 insertions(+), 2356 deletions(-) create mode 100644 examples/apex_rest_api_usecases/create_case/Ballerina.toml rename examples/apex_rest_api_usecases/{ => create_case}/README.md (87%) rename examples/apex_rest_api_usecases/{ => create_case}/invoke_apex_methods.bal (94%) delete mode 100644 examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal delete mode 100644 examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal create mode 100644 examples/bulk_api_usecases/execute_delete_job/Ballerina.toml create mode 100644 examples/bulk_api_usecases/execute_delete_job/README.md rename examples/bulk_api_usecases/{bulk-operations-csv => execute_delete_job}/bulk_delete_csv.bal (100%) create mode 100644 examples/bulk_api_usecases/execute_insert_job/Ballerina.toml create mode 100644 examples/bulk_api_usecases/execute_insert_job/README.md rename examples/bulk_api_usecases/{bulk-operations-csv => execute_insert_job}/bulk_insert_csv.bal (100%) create mode 100644 examples/bulk_api_usecases/execute_query_job/Ballerina.toml create mode 100644 examples/bulk_api_usecases/execute_query_job/README.md rename examples/bulk_api_usecases/{bulk-operations-csv => execute_query_job}/bulk_query_csv.bal (100%) create mode 100644 examples/bulk_api_usecases/execute_update_job/Ballerina.toml create mode 100644 examples/bulk_api_usecases/execute_update_job/README.md rename examples/bulk_api_usecases/{bulk-operations-csv => execute_update_job}/bulk_update_csv.bal (100%) create mode 100644 examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml create mode 100644 examples/bulk_api_usecases/execute_upsert_job/README.md rename examples/bulk_api_usecases/{bulk-operations-csv => execute_upsert_job}/bulk_upsert_csv.bal (100%) create mode 100644 examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml create mode 100644 examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md rename examples/bulkv2_api_usecases/{ => execute_bulkv2_ingest_job}/bulkv2_insert.bal (100%) create mode 100644 examples/rest_api_usecases/create_sobjects/Ballerina.toml create mode 100644 examples/rest_api_usecases/create_sobjects/README.md rename examples/rest_api_usecases/{ => create_sobjects}/sobject_create.bal (100%) create mode 100644 examples/rest_api_usecases/delete_sobject/Ballerina.toml create mode 100644 examples/rest_api_usecases/delete_sobject/README.md rename examples/rest_api_usecases/{ => delete_sobject}/sobject_delete.bal (100%) create mode 100644 examples/rest_api_usecases/get_by_id/Ballerina.toml create mode 100644 examples/rest_api_usecases/get_by_id/README.md rename examples/rest_api_usecases/{ => get_by_id}/sobject_get_by_id.bal (100%) delete mode 100644 examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal delete mode 100644 examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal delete mode 100644 examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal delete mode 100644 examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal delete mode 100644 examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal delete mode 100644 examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal delete mode 100644 examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal delete mode 100644 examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal delete mode 100644 examples/rest_api_usecases/sojbect_get_record_by_ext.bal create mode 100644 examples/rest_api_usecases/update_sobject/Ballerina.toml create mode 100644 examples/rest_api_usecases/update_sobject/README.md rename examples/rest_api_usecases/{ => update_sobject}/sobject_update.bal (100%) create mode 100644 examples/rest_api_usecases/use_query_api/Ballerina.toml create mode 100644 examples/rest_api_usecases/use_query_api/README.md rename examples/rest_api_usecases/{ => use_query_api}/find_record_by_query_stream.bal (100%) create mode 100644 examples/rest_api_usecases/use_search_api/Ballerina.toml create mode 100644 examples/rest_api_usecases/use_search_api/README.md rename examples/rest_api_usecases/{ => use_search_api}/search_record_by_string_stream.bal (100%) create mode 100644 examples/soap_api_usecases/convert_lead/Ballerina.toml create mode 100644 examples/soap_api_usecases/convert_lead/README.md rename examples/soap_api_usecases/{ => convert_lead}/convert_lead.bal (100%) diff --git a/examples/apex_rest_api_usecases/create_case/Ballerina.toml b/examples/apex_rest_api_usecases/create_case/Ballerina.toml new file mode 100644 index 00000000..9a76137b --- /dev/null +++ b/examples/apex_rest_api_usecases/create_case/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_apex_rest" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/apex_rest_api_usecases/README.md b/examples/apex_rest_api_usecases/create_case/README.md similarity index 87% rename from examples/apex_rest_api_usecases/README.md rename to examples/apex_rest_api_usecases/create_case/README.md index da27e90a..d3babbe2 100644 --- a/examples/apex_rest_api_usecases/README.md +++ b/examples/apex_rest_api_usecases/create_case/README.md @@ -1,6 +1,6 @@ # Use APEX API -This example demonstrates how to invoke APEX AREST API of Salesforce. +This example demonstrates how to invoke Bulk v2 API of Salesforce. ## Prerequisites diff --git a/examples/apex_rest_api_usecases/invoke_apex_methods.bal b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal similarity index 94% rename from examples/apex_rest_api_usecases/invoke_apex_methods.bal rename to examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal index 1a0dda4b..ee289761 100644 --- a/examples/apex_rest_api_usecases/invoke_apex_methods.bal +++ b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal @@ -42,10 +42,9 @@ public function main() returns error? { salesforce:Client baseClient = check new (sfConfig); string|error caseId = baseClient->apexRestExecute("Cases", "POST", - {"subject" : "Bigfoot Sighting9!", + {"subject" : "Item Fault!", "status" : "New", - "origin" : "Phone", - "priority" : "Low"}); + "priority" : "High"}); if caseId is error { log:printError("Error occurred while creating the case. "); return; diff --git a/examples/build.sh b/examples/build.sh index 5d32ff06..1c283320 100755 --- a/examples/build.sh +++ b/examples/build.sh @@ -41,7 +41,14 @@ BAL_SOURCE_DIR="$HOME/.ballerina/repositories/local/bala/ballerinax/$BAL_PACKAGE [ -d "$BAL_SOURCE_DIR" ] && cp -r "$BAL_SOURCE_DIR" "$BAL_DESTINATION_DIR" echo "Successfully updated the local central repositories" + # Loop through examples in the examples directory -find "$BAL_EXAMPLES_DIR" -type f -name "*.bal" | while read -r BAL_EXAMPLE_FILE; do - bal "$BAL_CMD" --offline "$BAL_EXAMPLE_FILE" +cd "$BAL_EXAMPLES_DIR" +for dir in $(find "$BAL_EXAMPLES_DIR" -type d -maxdepth 2 -mindepth 2); do + # Skip the build directory + if [[ "$dir" == *libs ]] || [[ "$dir" == *tmp ]]; then + continue + fi + (cd "$dir" && bal "$BAL_CMD" --offline && cd ..); done + diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal b/examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal deleted file mode 100644 index 286145b6..00000000 --- a/examples/bulk_api_usecases/bulk-operations-csv/bulk_file_insert_csv.bal +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/io; -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - string csvContactsFilePath = "resources/contacts.csv"; - - bulk:BulkJob|error insertJob = bulkClient->createJob("insert", "Contact", "CSV"); - - if insertJob is bulk:BulkJob { - io:ReadableByteChannel|io:Error rbc = io:openReadableFile(csvContactsFilePath); - if rbc is io:ReadableByteChannel { - error|bulk:BatchInfo batch = bulkClient->addBatch(insertJob, rbc); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Added Successfully" : "Failed to add the Batch"; - batchId = batch.id; - log:printInfo(message + " : " + message + " " + batchId); - } else { - log:printError(batch.message()); - } - } - - else { - log:printError(rbc.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(insertJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(insertJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(insertJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(insertJob, batchId); - if batchRequest is string { - string message = (re `\n`.split(batchRequest)).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(insertJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(insertJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal deleted file mode 100644 index 2830b18a..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_delete_json.bal +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Avenra", "Stanis", "Software Engineer Level 1"); - string id2 = check getContactIdByName("Irma", "Martin", "Software Engineer Level 1"); - - json contactsToDelete = [ - {"Id": id1}, - {"Id": id2} - ]; - - bulk:BulkJob|error deleteJob = bulkClient->createJob("delete", "Contact", "JSON"); - - if deleteJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(deleteJob, contactsToDelete); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Contacts Successfully uploaded to delete" : "Failed to upload the Contacts to delete"; - log:printInfo(message); - batchId = batch.id; - - } else { - log:printError(batch.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(deleteJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(deleteJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(deleteJob, batchId); - if batchRequest is json { - json[]|error batchRequestArr = batchRequest; - if batchRequestArr is json[] { - string message = batchRequestArr.length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - } else { - log:printError(batchRequestArr.message()); - } - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(deleteJob, batchId); - if batchResult is bulk:Result[] { - string message = batchResult.length() > 0 ? "Batch Result Received Successfully" : "Failed to Retrieve Batch Result"; - log:printInfo(message); - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(deleteJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; - diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal deleted file mode 100644 index 6dd2ce47..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_file_insert_json.bal +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/io; -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - string batchId = ""; - string jsonContactsFilePath = "resources/contacts.json"; - - bulk:BulkJob|error insertJob = bulkClient->createJob("insert", "Contact", "JSON"); - - if insertJob is bulk:BulkJob { - io:ReadableByteChannel|io:Error rbc = io:openReadableFile(jsonContactsFilePath); - if rbc is io:ReadableByteChannel { - error|bulk:BatchInfo batch = bulkClient->addBatch(insertJob, rbc); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Added Successfully" : "Failed to add the Batch"; - batchId = batch.id; - log:printInfo(message + " : " + message + " " + batchId); - } else { - log:printError(batch.message()); - } - } - else { - log:printError(rbc.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(insertJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(insertJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(insertJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(insertJob, batchId); - if batchRequest is json { - json[]|error batchRequestArr = batchRequest; - if batchRequestArr is json[] { - string message = batchRequestArr.length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - } else { - log:printError(batchRequestArr.message()); - } - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(insertJob, batchId); - if batchResult is bulk:Result[] { - string message = batchResult.length() > 0 ? "Batch Result Received Successfully" : "Failed to Retrieve Batch Result"; - log:printInfo(message); - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(insertJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal deleted file mode 100644 index d4e9d5ac..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_insert_json.bal +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - json contacts = [ - { - description: "Created_from_Ballerina_Sf_Bulk_API", - FirstName: "Avenra", - LastName: "Stanis", - Title: "Software Engineer Level 1", - Phone: "0475626670", - Email: "remusArf@gmail.com", - My_External_Id__c: "860" - }, - { - description: "Created_from_Ballerina_Sf_Bulk_API", - FirstName: "Irma", - LastName: "Martin", - Title: "Software Engineer Level 1", - Phone: "0465616170", - Email: "irmaHel@gmail.com", - My_External_Id__c: "861" - } - ]; - - bulk:BulkJob|error insertJob = bulkClient->createJob("insert", "Contact", "JSON"); - - if insertJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(insertJob, contacts); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Added Successfully" : "Failed to add the Batch"; - batchId = batch.id; - log:printInfo(message + " : " + message + " " + batchId); - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(insertJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(insertJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(insertJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(insertJob, batchId); - if batchRequest is json { - json[]|error batchRequestArr = batchRequest; - if batchRequestArr is json[] { - string message = batchRequestArr.length() == 2 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - } else { - log:printError(batchRequestArr.message()); - } - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(insertJob, batchId); - if batchResult is bulk:Result[] { - string message = batchResult.length() > 0 ? "Batch Result Received Successfully" : "Failed to Retrieve Batch Result"; - log:printInfo(message); - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(insertJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - else { - log:printInfo(insertJob.message()); - } - -} diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal deleted file mode 100644 index 9f856561..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_query_json.bal +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - string queryStr = "SELECT Id, Name FROM Contact WHERE Title='Software Engineer Level 1'"; - - bulk:BulkJob|error queryJob = bulkClient->createJob("query", "Contact", "JSON"); - - if queryJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(queryJob, queryStr); - if batch is bulk:BatchInfo { - _ = batch.id.length() > 0 ? "Query Executed Successfully" : "Failed to Execute the Quesry"; - batchId = batch.id; - } else { - log:printError(batch.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(queryJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(queryJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(queryJob, batchId); - if batchRequest is string { - string message = batchRequest.startsWith("SELECT") ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(queryJob, batchId); - - if batchResult is json { - json[]|error batchResultArr = batchResult; - if batchResultArr is json[] { - //io:println("count : " + batchResultArr.length().toString()); - log:printInfo("Number of Records Received :" + batchResultArr.length().toString()); - } else { - string msg = batchResultArr.toString(); - log:printError(msg); - } - } else if batchResult is error { - string msg = batchResult.message(); - log:printError(msg); - } else { - log:printError("Invalid Batch Result!"); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(queryJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal deleted file mode 100644 index f3fd460b..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_update_json.bal +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Avenra", "Stanis", "Software Engineer Level 1"); - string id2 = check getContactIdByName("Irma", "Martin", "Software Engineer Level 1"); - - json contacts = [ - { - description: "Created_from_Ballerina_Sf_Bulk_API", - Id: id1, - FirstName: "Avenra", - LastName: "Stanis", - Title: "Software Engineer Level 1", - Phone: "0937443355", - Email: "remusArf@gmail.com", - My_External_Id__c: "860" - }, - { - description: "Created_from_Ballerina_Sf_Bulk_API", - Id: id2, - FirstName: "Irma", - LastName: "Martin", - Title: "Software Engineer Level 1", - Phone: "0893345755", - Email: "irmaHel@gmail.com", - My_External_Id__c: "861" - } - ]; - - bulk:BulkJob|error updateJob = bulkClient->createJob("update", "Contact", "JSON"); - - if updateJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(updateJob, contacts); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Updated Successfully" : "Failed to Update the Batch"; - batchId = batch.id; - log:printInfo(message); - } else { - log:printError(batch.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(updateJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(updateJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(updateJob, batchId); - if batchRequest is json { - json[]|error batchRequestArr = batchRequest; - if batchRequestArr is json[] { - string message = batchRequestArr.length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - } else { - log:printError(batchRequestArr.message()); - } - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(updateJob, batchId); - if batchResult is bulk:Result[] { - string message = batchResult.length() > 0 ? "Batch Result Received Successfully" : "Failed to Retrieve Batch Result"; - log:printInfo(message); - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(updateJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; - diff --git a/examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal b/examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal deleted file mode 100644 index 367bd0ef..00000000 --- a/examples/bulk_api_usecases/bulk-operations-json/bulk_upsert_json.bal +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Avenra", "Stanis", "Software Engineer Level 1"); - string id2 = check getContactIdByName("Irma", "Martin", "Software Engineer Level 1"); - - json contacts = [ - { - description: "Created_from_Ballerina_Sf_Bulk_API", - Id: id1, - FirstName: "Avenra", - LastName: "Stanis", - Title: "Software Engineer Level 1", - Phone: "0937443354", - Email: "remusArf@gmail.com", - My_External_Id__c: "860", - Department: "R&D" - }, - { - description: "Created_from_Ballerina_Sf_Bulk_API", - Id: id2, - FirstName: "Irma", - LastName: "Martin", - Title: "Software Engineer Level 1", - Phone: "0893345789", - Email: "irmaHel@gmail.com", - My_External_Id__c: "861", - Department: "R&D" - } - ]; - - bulk:BulkJob|error updateJob = bulkClient->createJob("upsert", "Contact", "JSON", "My_External_Id__c"); - - if updateJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(updateJob, contacts); - if batch is bulk:BatchInfo { - batchId = batch.id; - string message = batch.id.length() > 0 ? "Batch added to upsert Successfully" : "Failed to add the batch"; - log:printInfo(message); - } else { - log:printError(batch.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(updateJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(updateJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(updateJob, batchId); - if batchRequest is json { - json[]|error batchRequestArr = batchRequest; - if batchRequestArr is json[] { - string message = batchRequestArr.length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - } else { - log:printError(batchRequestArr.message()); - } - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(updateJob, batchId); - if batchResult is bulk:Result[] { - string message = batchResult.length() > 0 ? "Batch Result Received Successfully" : "Failed to Retrieve Batch Result"; - log:printInfo(message); - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(updateJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; - diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal deleted file mode 100644 index e7e04036..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_delete_xml.bal +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Wanda", "Davidson", "Software Engineer Level 3"); - string id2 = check getContactIdByName("Natasha", "Romenoff", "Software Engineer Level 3"); - - xml contactsToDelete = xml ` - - ${id1} - - - ${id2} - - `; - - bulk:BulkJob|error deleteJob = bulkClient->createJob("delete", "Contact", "XML"); - - if deleteJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(deleteJob, contactsToDelete); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Contacts Successfully uploaded to delete" : "Failed to upload the Contacts to delete"; - log:printInfo(message); - batchId = batch.id; - - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(deleteJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(deleteJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(deleteJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(deleteJob, batchId); - if batchRequest is xml { - string message = (batchRequest/<*>).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(deleteJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(deleteJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal deleted file mode 100644 index b693eca8..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_file_insert_xml.bal +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/io; -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - string xmlContactsFilePath = "resources/contacts.xml"; - - bulk:BulkJob|error insertJob = bulkClient->createJob("insert", "Contact", "XML"); - - if insertJob is bulk:BulkJob { - io:ReadableByteChannel|io:Error rbc = io:openReadableFile(xmlContactsFilePath); - if rbc is io:ReadableByteChannel { - error|bulk:BatchInfo batch = bulkClient->addBatch(insertJob, rbc); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Added Successfully" : "Failed to add the Batch"; - batchId = batch.id; - log:printInfo(message + " : " + message + " " + batchId); - } else { - log:printError(batch.message()); - } - } - else { - log:printError(rbc.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(insertJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(insertJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(insertJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(insertJob, batchId); - if batchRequest is xml { - string message = (batchRequest/<*>).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(insertJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(insertJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal deleted file mode 100644 index f9b3d693..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_insert_xml.bal +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - xml contacts = xml ` - - Created_from_Ballerina_Sf_Bulk_API - Wanda - Davidson - Software Engineer Level 03 - 099116123 - wanda67@yahoo.com - 864 - - - Created_from_Ballerina_Sf_Bulk_API - Natasha - Romenoff - Software Engineer Level 03 - 086755643 - natashaRom@gmail.com - 865 - - `; - - bulk:BulkJob|error insertJob = bulkClient->createJob("insert", "Contact", "XML"); - - if insertJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(insertJob, contacts); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Added Successfully" : "Failed to add the Batch"; - batchId = batch.id; - log:printInfo(message + " : " + message + " " + batchId); - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(insertJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(insertJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(insertJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(insertJob, batchId); - if batchRequest is xml { - string message = (batchRequest/<*>).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(insertJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(insertJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal deleted file mode 100644 index 66cb5637..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_query_xml.bal +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - - string batchId = ""; - - // Create Salesforce client. - bulk:Client bulkClient = check new (sfConfig); - - string queryStr = "SELECT Id, Name FROM Contact WHERE Title='Software Engineer Level 3'"; - - bulk:BulkJob|error queryJob = bulkClient->createJob("query", "Contact", "XML"); - - if queryJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(queryJob, queryStr); - if batch is bulk:BatchInfo { - _ = batch.id.length() > 0 ? "Query Executed Successfully" : "Failed to Execute the Quesry"; - batchId = batch.id; - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(queryJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(queryJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(queryJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(queryJob, batchId); - if batchRequest is string { - string message = batchRequest.startsWith("SELECT") ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(queryJob, batchId); - if batchResult is xml { - log:printInfo("Number of Records Received :" + ((batchResult/<*>).length().toString())); - } else if batchResult is error { - string msg = batchResult.message(); - log:printError(msg); - } else { - log:printError("Invalid Batch Result!"); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(queryJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } -} diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal deleted file mode 100644 index 4c1c4e4f..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_update_xml.bal +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Wanda", "Davidson", "Software Engineer Level 03"); - string id2 = check getContactIdByName("Natasha", "Romenoff", "Software Engineer Level 03"); - - xml contacts = xml ` - - Created_from_Ballerina_Sf_Bulk_API - ${id1} - Wanda - Davidson - Software Engineer Level 3 - 0991161233 - wanda67@yahoo.com - 864 - - - Created_from_Ballerina_Sf_Bulk_API - ${id2} - Natasha - Romenoff - Software Engineer Level 3 - 0867556833 - natashaRom@gmail.com - 865 - - `; - - bulk:BulkJob|error updateJob = bulkClient->createJob("update", "Contact", "XML"); - - if updateJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(updateJob, contacts); - if batch is bulk:BatchInfo { - string message = batch.id.length() > 0 ? "Batch Updated Successfully" : "Failed to Update the Batch"; - batchId = batch.id; - log:printInfo(message); - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(updateJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(updateJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(updateJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(updateJob, batchId); - if batchRequest is xml { - string message = (batchRequest/<*>).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(updateJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(updateJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; diff --git a/examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal b/examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal deleted file mode 100644 index db921d5e..00000000 --- a/examples/bulk_api_usecases/bulk-operations-xml/bulk_upsert_xml.bal +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce.bulk; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -bulk:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -// Create Salesforce client. -salesforce:Client baseClient = check new (sfConfig); -bulk:Client bulkClient = check new (sfConfig); - -public function main() returns error? { - - string batchId = ""; - - string id1 = check getContactIdByName("Wanda", "Davidson", "Software Engineer Level 3"); - string id2 = check getContactIdByName("Natasha", "Romenoff", "Software Engineer Level 3"); - - xml contacts = xml ` - - Created_from_Ballerina_Sf_Bulk_API - ${id1} - Wanda - Davidson - Software Engineer Level 3 - 0991161283 - wanda67@yahoo.com - 864 - Finance - - - Created_from_Ballerina_Sf_Bulk_API - ${id2} - Natasha - Romenoff - Software Engineer Level 3 - 0867556843 - natashaRom@gmail.com - 865 - Finance - - `; - - bulk:BulkJob|error updateJob = bulkClient->createJob("upsert", "Contact", "XML", "My_External_Id__c"); - - if updateJob is bulk:BulkJob { - error|bulk:BatchInfo batch = bulkClient->addBatch(updateJob, contacts); - if batch is bulk:BatchInfo { - batchId = batch.id; - string message = batch.id.length() > 0 ? "Batch added to upsert Successfully" : "Failed to add the batch"; - log:printInfo(message); - } else { - log:printError(batch.message()); - } - - //get job info - error|bulk:JobInfo jobInfo = bulkClient->getJobInfo(updateJob); - if jobInfo is bulk:JobInfo { - string message = jobInfo.id.length() > 0 ? "Jon Info Received Successfully" : "Failed Retrieve Job Info"; - log:printInfo(message); - } else { - log:printError(jobInfo.message()); - } - - //get batch info - error|bulk:BatchInfo batchInfo = bulkClient->getBatchInfo(updateJob, batchId); - if batchInfo is bulk:BatchInfo { - string message = batchInfo.id == batchId ? "Batch Info Received Successfully" : "Failed to Retrieve Batch Info"; - log:printInfo(message); - } else { - log:printError(batchInfo.message()); - } - - //get all batches - error|bulk:BatchInfo[] batchInfoList = bulkClient->getAllBatches(updateJob); - if batchInfoList is bulk:BatchInfo[] { - string message = batchInfoList.length() == 1 ? "All Batches Received Successfully" : "Failed to Retrieve All Batches"; - log:printInfo(message); - } else { - log:printError(batchInfoList.message()); - } - - //get batch request - var batchRequest = bulkClient->getBatchRequest(updateJob, batchId); - if batchRequest is xml { - string message = (batchRequest/<*>).length() > 0 ? "Batch Request Received Successfully" : "Failed to Retrieve Batch Request"; - log:printInfo(message); - - } else if batchRequest is error { - log:printError(batchRequest.message()); - } else { - log:printError(batchRequest.toString()); - } - - //get batch result - var batchResult = bulkClient->getBatchResult(updateJob, batchId); - if batchResult is bulk:Result[] { - foreach bulk:Result res in batchResult { - if !res.success { - log:printError("Failed result, res=" + res.toString(), err = ()); - } - } - } else if batchResult is error { - log:printError(batchResult.message()); - } else { - log:printError(batchResult.toString()); - } - - //close job - error|bulk:JobInfo closedJob = bulkClient->closeJob(updateJob); - if closedJob is bulk:JobInfo { - string message = closedJob.state == "Closed" ? "Job Closed Successfully" : "Failed to Close the Job"; - log:printInfo(message); - } else { - log:printError(closedJob.message()); - } - } - -} - -function getContactIdByName(string firstName, string lastName, string title) returns string|error { - string contactId = ""; - string sampleQuery = string `SELECT Id FROM Contact WHERE FirstName='${firstName}' AND LastName='${lastName}' - AND Title='${title}' LIMIT 1`; - stream queryResults = check baseClient->query(sampleQuery); - ResultValue|error? result = queryResults.next(); - if result is ResultValue { - contactId = check result.value.get("Id").ensureType(); - } else { - log:printError(msg = "Getting Contact ID by name failed."); - } - return contactId; -} - -type ResultValue record {| - record {} value; -|}; diff --git a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml new file mode 100644 index 00000000..1b516bdd --- /dev/null +++ b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_bulk_delete" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulk_api_usecases/execute_delete_job/README.md b/examples/bulk_api_usecases/execute_delete_job/README.md new file mode 100644 index 00000000..5b8b840d --- /dev/null +++ b/examples/bulk_api_usecases/execute_delete_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk API + +This example demonstrates how to invoke delete operation using bulk API. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal b/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal similarity index 100% rename from examples/bulk_api_usecases/bulk-operations-csv/bulk_delete_csv.bal rename to examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal diff --git a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml new file mode 100644 index 00000000..22265dab --- /dev/null +++ b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_bulk_insert" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulk_api_usecases/execute_insert_job/README.md b/examples/bulk_api_usecases/execute_insert_job/README.md new file mode 100644 index 00000000..9d10a361 --- /dev/null +++ b/examples/bulk_api_usecases/execute_insert_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk API + +This example demonstrates how to invoke insert operation using bulk API. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal b/examples/bulk_api_usecases/execute_insert_job/bulk_insert_csv.bal similarity index 100% rename from examples/bulk_api_usecases/bulk-operations-csv/bulk_insert_csv.bal rename to examples/bulk_api_usecases/execute_insert_job/bulk_insert_csv.bal diff --git a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml new file mode 100644 index 00000000..7bdc7775 --- /dev/null +++ b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_bulk_query" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulk_api_usecases/execute_query_job/README.md b/examples/bulk_api_usecases/execute_query_job/README.md new file mode 100644 index 00000000..ef860427 --- /dev/null +++ b/examples/bulk_api_usecases/execute_query_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk API + +This example demonstrates how to invoke query operation using bulk API. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal b/examples/bulk_api_usecases/execute_query_job/bulk_query_csv.bal similarity index 100% rename from examples/bulk_api_usecases/bulk-operations-csv/bulk_query_csv.bal rename to examples/bulk_api_usecases/execute_query_job/bulk_query_csv.bal diff --git a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml new file mode 100644 index 00000000..a123863c --- /dev/null +++ b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_bulk_update" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulk_api_usecases/execute_update_job/README.md b/examples/bulk_api_usecases/execute_update_job/README.md new file mode 100644 index 00000000..a5dbfda2 --- /dev/null +++ b/examples/bulk_api_usecases/execute_update_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk API + +This example demonstrates how to invoke update operation using bulk API. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal b/examples/bulk_api_usecases/execute_update_job/bulk_update_csv.bal similarity index 100% rename from examples/bulk_api_usecases/bulk-operations-csv/bulk_update_csv.bal rename to examples/bulk_api_usecases/execute_update_job/bulk_update_csv.bal diff --git a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml new file mode 100644 index 00000000..cb8b0c05 --- /dev/null +++ b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_bulk_upsert" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulk_api_usecases/execute_upsert_job/README.md b/examples/bulk_api_usecases/execute_upsert_job/README.md new file mode 100644 index 00000000..ee27c518 --- /dev/null +++ b/examples/bulk_api_usecases/execute_upsert_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk API + +This example demonstrates how to invoke upsert operation using bulk API. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal b/examples/bulk_api_usecases/execute_upsert_job/bulk_upsert_csv.bal similarity index 100% rename from examples/bulk_api_usecases/bulk-operations-csv/bulk_upsert_csv.bal rename to examples/bulk_api_usecases/execute_upsert_job/bulk_upsert_csv.bal diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml new file mode 100644 index 00000000..9a76137b --- /dev/null +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_apex_rest" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md new file mode 100644 index 00000000..af781e93 --- /dev/null +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md @@ -0,0 +1,28 @@ +# Use Bulk V2 API + +This example demonstrates how to invoke APEX REST API of Salesforce. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/bulkv2_api_usecases/bulkv2_insert.bal b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal similarity index 100% rename from examples/bulkv2_api_usecases/bulkv2_insert.bal rename to examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal diff --git a/examples/rest_api_usecases/create_sobjects/Ballerina.toml b/examples/rest_api_usecases/create_sobjects/Ballerina.toml new file mode 100644 index 00000000..ae56b98a --- /dev/null +++ b/examples/rest_api_usecases/create_sobjects/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_rest_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/create_sobjects/README.md b/examples/rest_api_usecases/create_sobjects/README.md new file mode 100644 index 00000000..71b92c22 --- /dev/null +++ b/examples/rest_api_usecases/create_sobjects/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to create sObjects. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/sobject_create.bal b/examples/rest_api_usecases/create_sobjects/sobject_create.bal similarity index 100% rename from examples/rest_api_usecases/sobject_create.bal rename to examples/rest_api_usecases/create_sobjects/sobject_create.bal diff --git a/examples/rest_api_usecases/delete_sobject/Ballerina.toml b/examples/rest_api_usecases/delete_sobject/Ballerina.toml new file mode 100644 index 00000000..648d9277 --- /dev/null +++ b/examples/rest_api_usecases/delete_sobject/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_getbyid_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/delete_sobject/README.md b/examples/rest_api_usecases/delete_sobject/README.md new file mode 100644 index 00000000..b4ba40e0 --- /dev/null +++ b/examples/rest_api_usecases/delete_sobject/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to delete sObjects. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/sobject_delete.bal b/examples/rest_api_usecases/delete_sobject/sobject_delete.bal similarity index 100% rename from examples/rest_api_usecases/sobject_delete.bal rename to examples/rest_api_usecases/delete_sobject/sobject_delete.bal diff --git a/examples/rest_api_usecases/get_by_id/Ballerina.toml b/examples/rest_api_usecases/get_by_id/Ballerina.toml new file mode 100644 index 00000000..648d9277 --- /dev/null +++ b/examples/rest_api_usecases/get_by_id/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_getbyid_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/get_by_id/README.md b/examples/rest_api_usecases/get_by_id/README.md new file mode 100644 index 00000000..a3628570 --- /dev/null +++ b/examples/rest_api_usecases/get_by_id/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to get sObject by Id. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/sobject_get_by_id.bal b/examples/rest_api_usecases/get_by_id/sobject_get_by_id.bal similarity index 100% rename from examples/rest_api_usecases/sobject_get_by_id.bal rename to examples/rest_api_usecases/get_by_id/sobject_get_by_id.bal diff --git a/examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal b/examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal deleted file mode 100644 index 694aabb5..00000000 --- a/examples/rest_api_usecases/org-metadata-usecases/get_api_version.bal +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - salesforce:Version[]|error apiVersions = baseClient->getApiVersions(); - - if apiVersions is salesforce:Version[] { - log:printInfo("Versions retrieved successfully : " + apiVersions.toString()); - } else { - log:printError(msg = apiVersions.message()); - } - -} diff --git a/examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal b/examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal deleted file mode 100644 index 4e616d67..00000000 --- a/examples/rest_api_usecases/org-metadata-usecases/get_org_limits.bal +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - map|error orgLimits = baseClient->getLimits(); - - if orgLimits is map { - log:printInfo("Versions retrieved successfully : " + orgLimits.toString()); - } else { - log:printError(msg = orgLimits.message()); - } - -} diff --git a/examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal b/examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal deleted file mode 100644 index 5697b274..00000000 --- a/examples/rest_api_usecases/org-metadata-usecases/get_organizational_data.bal +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - salesforce:Version[]|error apiVersions = baseClient->getApiVersions(); - - if apiVersions is salesforce:Version[] { - log:printInfo("Versions retrieved successfully : " + apiVersions.toString()); - } else { - log:printError(msg = apiVersions.message()); - } - - map|error apiVersionResources = baseClient->getResources("v48.0"); - - if apiVersionResources is map { - log:printInfo("Versions retrieved successfully : " + apiVersionResources.toString()); - } else { - log:printError(msg = apiVersionResources.message()); - } - - map|error apiLimits = baseClient->getLimits(); - - if apiLimits is map { - log:printInfo("Versions retrieved successfully : " + apiLimits.toString()); - } else { - log:printError(msg = apiLimits.message()); - } - -} diff --git a/examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal b/examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal deleted file mode 100644 index 69e024d7..00000000 --- a/examples/rest_api_usecases/org-metadata-usecases/get_version_resources.bal +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - map|error apiVersionResources = baseClient->getResources("v48.0"); - - if apiVersionResources is map { - log:printInfo("Versions retrieved successfully : " + apiVersionResources.toString()); - } else { - log:printError(msg = apiVersionResources.message()); - } -} diff --git a/examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal b/examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal deleted file mode 100644 index c0306547..00000000 --- a/examples/rest_api_usecases/sobject-metadata-usecases/describe_available_objects.bal +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - salesforce:OrganizationMetadata|error availableObjsDes = baseClient->getOrganizationMetaData(); - - if availableObjsDes is salesforce:OrganizationMetadata { - int|error countSobjects = availableObjsDes.sobjects.length(); - if countSobjects is int { - log:printInfo("Number of SObjects Received = " + countSobjects.toString()); - } - else { - log:printError("No SObjects Found"); - } - } else { - log:printError(msg = availableObjsDes.message()); - } - -} diff --git a/examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal b/examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal deleted file mode 100644 index fe08097c..00000000 --- a/examples/rest_api_usecases/sobject-metadata-usecases/describe_sobject.bal +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - string objName = "Account"; - - salesforce:SObjectMetaData|error objDesc = baseClient->describe(objName); - - if objDesc is salesforce:SObjectMetaData { - log:printInfo("Object description received : " + objDesc.toString()); - } else { - log:printError(msg = objDesc.message()); - } -} diff --git a/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal b/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal deleted file mode 100644 index 7c1842c8..00000000 --- a/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_info.bal +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - string objName = "Account"; - salesforce:SObjectBasicInfo|error sobjectInfo = baseClient->getBasicInfo(objName); - - if sobjectInfo is salesforce:SObjectBasicInfo { - log:printInfo("SObject basic info received " + sobjectInfo.toString()); - } else { - log:printError(msg = sobjectInfo.message()); - } - -} diff --git a/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal b/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal deleted file mode 100644 index 62b0ed5e..00000000 --- a/examples/rest_api_usecases/sobject-metadata-usecases/get_sobject_platformAction.bal +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - salesforce:SObjectBasicInfo|error actionInfo = baseClient->getPlatformAction(); - - if actionInfo is salesforce:SObjectBasicInfo { - log:printInfo("Platform Action Info Received : " + actionInfo.toString()); - } else { - log:printError(msg = actionInfo.message()); - } -} diff --git a/examples/rest_api_usecases/sojbect_get_record_by_ext.bal b/examples/rest_api_usecases/sojbect_get_record_by_ext.bal deleted file mode 100644 index 4f3d2496..00000000 --- a/examples/rest_api_usecases/sojbect_get_record_by_ext.bal +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2021 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -// -// WSO2 Inc. licenses this file to you under the Apache License, -// Version 2.0 (the "License"); you may not use this file except -// in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -import ballerina/log; -import ballerinax/salesforce; -import ballerina/os; - -// Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); - -// Using direct-token config for client configuration -salesforce:ConnectionConfig sfConfig = { - baseUrl, - auth: { - clientId, - clientSecret, - refreshToken, - refreshUrl - } -}; - -public function main() returns error? { - // Create Salesforce client. - salesforce:Client baseClient = check new (sfConfig); - - record {}|error res = baseClient->getByExternalId("Contact", "My_External_Id__c", "102"); - - if res is record {} { - anydata recName = res["FirstName"]; - log:printInfo("Account data received successfully. Account Name : " + recName.toString()); - } else { - log:printError(msg = res.message()); - } -} diff --git a/examples/rest_api_usecases/update_sobject/Ballerina.toml b/examples/rest_api_usecases/update_sobject/Ballerina.toml new file mode 100644 index 00000000..1a681b63 --- /dev/null +++ b/examples/rest_api_usecases/update_sobject/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_update_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/update_sobject/README.md b/examples/rest_api_usecases/update_sobject/README.md new file mode 100644 index 00000000..71b92c22 --- /dev/null +++ b/examples/rest_api_usecases/update_sobject/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to create sObjects. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/sobject_update.bal b/examples/rest_api_usecases/update_sobject/sobject_update.bal similarity index 100% rename from examples/rest_api_usecases/sobject_update.bal rename to examples/rest_api_usecases/update_sobject/sobject_update.bal diff --git a/examples/rest_api_usecases/use_query_api/Ballerina.toml b/examples/rest_api_usecases/use_query_api/Ballerina.toml new file mode 100644 index 00000000..4159e14e --- /dev/null +++ b/examples/rest_api_usecases/use_query_api/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_query_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/use_query_api/README.md b/examples/rest_api_usecases/use_query_api/README.md new file mode 100644 index 00000000..4dba39cf --- /dev/null +++ b/examples/rest_api_usecases/use_query_api/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to query sObjects. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/find_record_by_query_stream.bal b/examples/rest_api_usecases/use_query_api/find_record_by_query_stream.bal similarity index 100% rename from examples/rest_api_usecases/find_record_by_query_stream.bal rename to examples/rest_api_usecases/use_query_api/find_record_by_query_stream.bal diff --git a/examples/rest_api_usecases/use_search_api/Ballerina.toml b/examples/rest_api_usecases/use_search_api/Ballerina.toml new file mode 100644 index 00000000..050375d5 --- /dev/null +++ b/examples/rest_api_usecases/use_search_api/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_search_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/rest_api_usecases/use_search_api/README.md b/examples/rest_api_usecases/use_search_api/README.md new file mode 100644 index 00000000..2af94727 --- /dev/null +++ b/examples/rest_api_usecases/use_search_api/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke REST API of Salesforce to search sObjects. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/rest_api_usecases/search_record_by_string_stream.bal b/examples/rest_api_usecases/use_search_api/search_record_by_string_stream.bal similarity index 100% rename from examples/rest_api_usecases/search_record_by_string_stream.bal rename to examples/rest_api_usecases/use_search_api/search_record_by_string_stream.bal diff --git a/examples/soap_api_usecases/convert_lead/Ballerina.toml b/examples/soap_api_usecases/convert_lead/Ballerina.toml new file mode 100644 index 00000000..630759e1 --- /dev/null +++ b/examples/soap_api_usecases/convert_lead/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "salsforce_exsamples" +name = "use_soap_api" +version = "0.1.0" +distribution = "2201.8.2" \ No newline at end of file diff --git a/examples/soap_api_usecases/convert_lead/README.md b/examples/soap_api_usecases/convert_lead/README.md new file mode 100644 index 00000000..7c85170e --- /dev/null +++ b/examples/soap_api_usecases/convert_lead/README.md @@ -0,0 +1,28 @@ +# Use REST API + +This example demonstrates how to invoke SOAP API of Salesforce to convert Leads. + +## Prerequisites + +### 1. Set up +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. + +### 2. Configuration + +Configure Salesforce API credentials in Config.toml in the example directory: + +```toml +clientId = "" +clientSecret = "" +refreshToken = "" +refreshUrl = "" +baseUrl = "" +``` + +## Run the Example + +Execute the following command to run the example: + +```bash +bal run +``` \ No newline at end of file diff --git a/examples/soap_api_usecases/convert_lead.bal b/examples/soap_api_usecases/convert_lead/convert_lead.bal similarity index 100% rename from examples/soap_api_usecases/convert_lead.bal rename to examples/soap_api_usecases/convert_lead/convert_lead.bal From 873c8b8a225392b3204aa83b81d7f1c1343d791b Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:43:00 +0530 Subject: [PATCH 09/26] Update examples removing os dependancy --- .../create_case/invoke_apex_methods.bal | 11 +++++------ .../execute_delete_job/bulk_delete_csv.bal | 11 +++++------ .../execute_bulkv2_ingest_job/bulkv2_insert.bal | 11 +++++------ .../soap_api_usecases/convert_lead/convert_lead.bal | 11 +++++------ 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal index ee289761..a3907b88 100644 --- a/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal +++ b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal @@ -16,15 +16,14 @@ import ballerina/log; import ballerinax/salesforce; -import ballerina/os; import ballerina/lang.runtime; // Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); +configurable string clientId = ?; +configurable string clientSecret = ?; +configurable string refreshToken = ?; +configurable string refreshUrl = ?; +configurable string baseUrl = ?; // Using direct-token config for client configuration salesforce:ConnectionConfig sfConfig = { diff --git a/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal b/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal index 5a2bf16e..6a9c74f3 100644 --- a/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal +++ b/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal @@ -17,14 +17,13 @@ import ballerina/log; import ballerinax/salesforce.bulk; import ballerinax/salesforce; -import ballerina/os; // Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); +configurable string clientId = ?; +configurable string clientSecret = ?; +configurable string refreshToken = ?; +configurable string refreshUrl = ?; +configurable string baseUrl = ?; // Using direct-token config for client configuration bulk:ConnectionConfig sfConfig = { diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal index 341034b1..4d6105e0 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal @@ -15,16 +15,15 @@ // under the License. import ballerinax/salesforce; -import ballerina/os; import ballerina/lang.runtime; import ballerina/io; // Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); +configurable string clientId = ?; +configurable string clientSecret = ?; +configurable string refreshToken = ?; +configurable string refreshUrl = ?; +configurable string baseUrl = ?; // Using direct-token config for client configuration salesforce:ConnectionConfig sfConfig = { diff --git a/examples/soap_api_usecases/convert_lead/convert_lead.bal b/examples/soap_api_usecases/convert_lead/convert_lead.bal index 0b340030..2eeeb578 100644 --- a/examples/soap_api_usecases/convert_lead/convert_lead.bal +++ b/examples/soap_api_usecases/convert_lead/convert_lead.bal @@ -16,14 +16,13 @@ import ballerinax/salesforce.soap; import ballerina/log; -import ballerina/os; // Create Salesforce client configuration by reading from environemnt. -configurable string clientId = os:getEnv("CLIENT_ID"); -configurable string clientSecret = os:getEnv("CLIENT_SECRET"); -configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); -configurable string refreshUrl = os:getEnv("REFRESH_URL"); -configurable string baseUrl = os:getEnv("EP_URL"); +configurable string clientId = ?; +configurable string clientSecret = ?; +configurable string refreshToken = ?; +configurable string refreshUrl = ?; +configurable string baseUrl = ?; public function main() returns error? { soap:Client salesforceClient = check new ({ From 05e45d374577ae1d46461222f7f27b94bae9a84a Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:53:46 +0530 Subject: [PATCH 10/26] Update .github/workflows/release.yml Co-authored-by: MohamedSabthar --- .github/workflows/release.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cd393f52..fcf51426 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,5 +16,4 @@ jobs: package-org: ballerinax additional-build-flags: "-x :salesforce-examples:build" additional-release-flags: "-x :salesforce-examples:build" - additional-publish-flags: "-x :salesforce-examples:build" - \ No newline at end of file + additional-publish-flags: "-x :salesforce-examples:build" \ No newline at end of file From c7804834c3154f4e1c9516726accc75a08a55ace Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:55:35 +0530 Subject: [PATCH 11/26] Update CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b694bfc5..dd9d7182 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,4 +4,4 @@ # See: https://help.github.com/articles/about-codeowners/ # These owners will be the default owners for everything in the repo. -* @indikasampath2000 @abeykoon @sachinira +* @aashikam @niveathika @sahanHe From 06c736469c2cb5d70eec0100da6aa986049e64f9 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:26:17 +0530 Subject: [PATCH 12/26] Update pull-request.yml --- .github/workflows/pull-request.yml | 65 +++++------------------------- 1 file changed, 11 insertions(+), 54 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 81fed605..70b82b03 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -1,57 +1,14 @@ -name: CI_pull_request +name: PR Build -on: [ pull_request ] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - # Set up Java Environment - - name: Set up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17.0.7 - - # Setup Ballerina Environment - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: latest +on: pull_request - # Grant execute permission to the gradlew script - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - # Build the project with Gradle - - name: Build with Gradle - env: - packageUser: ${{ github.actor }} - packagePAT: ${{ secrets.GITHUB_TOKEN }} - JAVA_OPTS: -DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true - run: | - ./gradlew build -x test - - # Build Ballerina Project - - name: Ballerina Build - run: bal pack ./ballerina - env: - JAVA_HOME: /usr/lib/jvm/default-jvm - - # Test Ballerina Project - - name: Ballerina Test - # tests will be skipped if the PR is from a forked repository (as the secrets are not available) - if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} - run: bal test --test-report --code-coverage --coverage-format=xml ./ballerina - env: - CLIENT_ID: ${{ secrets.CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} - EP_URL: ${{ secrets.EP_URL }} - REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} - REFRESH_URL: ${{ secrets.REFRESH_URL }} - JAVA_HOME: /usr/lib/jvm/default-jvm - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 +jobs: + call_workflow: + name: Run PR Build Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/pr-build-connector-template.yml@main + secrets: inherit \ No newline at end of file From 8e8e3b67e24ba078ea1763fc5cb52313b49c8381 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:06:41 +0530 Subject: [PATCH 13/26] Update resource paths --- ballerina/modules/bulk/tests/bulk_csv_insert.bal | 6 +++--- ballerina/modules/bulk/tests/bulk_json_insert.bal | 2 +- ballerina/modules/bulk/tests/bulk_xml_insert.bal | 2 +- ballerina/tests/bulk_csv_insert.bal | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ballerina/modules/bulk/tests/bulk_csv_insert.bal b/ballerina/modules/bulk/tests/bulk_csv_insert.bal index 90654606..34ae74e0 100644 --- a/ballerina/modules/bulk/tests/bulk_csv_insert.bal +++ b/ballerina/modules/bulk/tests/bulk_csv_insert.bal @@ -176,7 +176,7 @@ function insertCsvFromFile() { log:printInfo("baseClient -> insertCsvFromFile"); string batchId = ""; - string csvContactsFilePath = "ballerina/modules/bulk/tests/resources/contacts1.csv"; + string csvContactsFilePath = "modules/bulk/tests/resources/contacts1.csv"; //create job error|BulkJob insertJob = baseClient->createJob("insert", "Contact", "CSV"); @@ -323,7 +323,7 @@ function insertCsvStringArrayFromFile() returns error? { log:printInfo("baseClient -> insertCsvStringArrayFromFile"); string batchId = ""; - string csvContactsFilePath = "ballerina/modules/bulk/tests/resources/contacts2.csv"; + string csvContactsFilePath = "modules/bulk/tests/resources/contacts2.csv"; //create job error|BulkJob insertJob = baseClient->createJob("insert", "Contact", "CSV"); @@ -464,7 +464,7 @@ function insertCsvStreamFromFile() returns error? { log:printInfo("baseClient -> insertCsvStreamFromFile"); string batchId = ""; - string csvContactsFilePath = "ballerina/modules/bulk/tests/resources/contacts3.csv"; + string csvContactsFilePath = "modules/bulk/tests/resources/contacts3.csv"; //create job error|BulkJob insertJob = baseClient->createJob("insert", "Contact", "CSV"); diff --git a/ballerina/modules/bulk/tests/bulk_json_insert.bal b/ballerina/modules/bulk/tests/bulk_json_insert.bal index 58a5eb33..a11f174b 100644 --- a/ballerina/modules/bulk/tests/bulk_json_insert.bal +++ b/ballerina/modules/bulk/tests/bulk_json_insert.bal @@ -187,7 +187,7 @@ function insertJson() returns error? { function insertJsonFromFile() returns error? { log:printInfo("baseClient -> insertJsonFromFile"); string jsonBatchId = ""; - string jsonContactsFilePath = "ballerina/modules/bulk/tests/resources/contacts.json"; + string jsonContactsFilePath = "modules/bulk/tests/resources/contacts.json"; //create job BulkJob jsonInsertJob = check baseClient->createJob("insert", "Contact", "JSON"); diff --git a/ballerina/modules/bulk/tests/bulk_xml_insert.bal b/ballerina/modules/bulk/tests/bulk_xml_insert.bal index ada788d9..32685fc1 100644 --- a/ballerina/modules/bulk/tests/bulk_xml_insert.bal +++ b/ballerina/modules/bulk/tests/bulk_xml_insert.bal @@ -167,7 +167,7 @@ function insertXmlFromFile() returns error? { log:printInfo("baseClient -> insertXmlFromFile"); string xmlBatchId = ""; - string xmlContactsFilePath = "ballerina/modules/bulk/tests/resources/contacts.xml"; + string xmlContactsFilePath = "modules/bulk/tests/resources/contacts.xml"; //create job BulkJob xmlInsertJob = check baseClient->createJob("insert", "Contact", "XML"); diff --git a/ballerina/tests/bulk_csv_insert.bal b/ballerina/tests/bulk_csv_insert.bal index 75295d44..796778bf 100644 --- a/ballerina/tests/bulk_csv_insert.bal +++ b/ballerina/tests/bulk_csv_insert.bal @@ -95,7 +95,7 @@ function insertCsv() returns error? { } function insertCsvFromFile() returns error? { log:printInfo("baseClient -> insertCsvFromFile"); - string csvContactsFilePath = "ballerina/tests/resources/contacts1.csv"; + string csvContactsFilePath = "tests/resources/contacts1.csv"; //create job BulkCreatePayload payload = { @@ -158,7 +158,7 @@ function insertCsvFromFile() returns error? { function insertCsvStringArrayFromFile() returns error? { log:printInfo("baseClient -> insertCsvStringArrayFromFile"); - string csvContactsFilePath = "ballerina/tests/resources/contacts2.csv"; + string csvContactsFilePath = "tests/resources/contacts2.csv"; //create job BulkCreatePayload payload = { @@ -226,7 +226,7 @@ function insertCsvStringArrayFromFile() returns error? { function insertCsvStreamFromFile() returns error? { log:printInfo("baseClient -> insertCsvStreamFromFile"); - string csvContactsFilePath = "ballerina/tests/resources/contacts3.csv"; + string csvContactsFilePath = "tests/resources/contacts3.csv"; stream csvStream = check io:fileReadCsvAsStream(csvContactsFilePath); //create job From 4135f269b379dc335cd1c7b2ef25f481549ff450 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 14:49:06 +0530 Subject: [PATCH 14/26] Update example links in md files --- README.md | 10 +++++----- ballerina/Module.md | 10 +++++----- ballerina/Package.md | 12 ++++++++---- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 5d394cdd..e2b5de7b 100644 --- a/README.md +++ b/README.md @@ -112,15 +112,15 @@ bal run ## Examples -The `salesforce` integration samples illustrate its usage in various integration scenarios. Explore these examples below, covering the use of salesforce APIs in integrations. +The `salesforce` connector provides practical examples illustrating usage in various scenarios. Explore these examples below, covering use cases like creating sObjects, retrieving records, and executing bulk operations. -1. [FTP B2B EDI message to Salesforce opportunity](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/ftp-edi-message-to-salesforce-opportunity) - This example reads EDI files from a given FTP location, converts those EDI messages to Ballerina records and creates a Salesforce opportunity for each EDI message. +1. [Salesforce REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. -2. [Salesforce new contact to Twilio SMS](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/salesforce-new-contact-to-twilio-sms) - This example sends a Twilio SMS for every new Salesforce contact. +2. [Salesforce Bulk API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. -3. [Kafka message to Salesforce new Contact](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update) - This example updates the product price in the Salesforce price book through Kafka and Salesforce integration. +3. [Salesforce Bulk v2 API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. -4. [Email Lead info into Salesforce using OpenAI](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/gmail-to-salesforce-lead) - This example creates a lead on Salesforce for each email marked with a specific label on Gmail using the OpenAI chat API to infer customer details. +4. [Salesforce APEX REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. ## Report Issues diff --git a/ballerina/Module.md b/ballerina/Module.md index e289a3ae..4ad4d6ee 100644 --- a/ballerina/Module.md +++ b/ballerina/Module.md @@ -97,12 +97,12 @@ bal run ## Examples -The `salesforce` integration samples illustrate its usage in various integration scenarios. Explore these examples below, covering the use of salesforce APIs in integrations. +The `salesforce` connector provides practical examples illustrating usage in various scenarios. Explore these examples below, covering use cases like creating sObjects, retrieving records, and executing bulk operations. -1. [FTP B2B EDI message to Salesforce opportunity](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/ftp-edi-message-to-salesforce-opportunity) - This example reads EDI files from a given FTP location, converts those EDI messages to Ballerina records and creates a Salesforce opportunity for each EDI message. +1. [Salesforce REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. -2. [Salesforce new contact to Twilio SMS](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/salesforce-new-contact-to-twilio-sms) - This example sends a Twilio SMS for every new Salesforce contact. +2. [Salesforce Bulk API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. -3. [Kafka message to Salesforce new Contact](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update) - This example updates the product price in the Salesforce price book through Kafka and Salesforce integration. +3. [Salesforce Bulk v2 API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/revamp-2023/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. -4. [Email Lead info into Salesforce using OpenAI](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/gmail-to-salesforce-lead) - This example creates a lead on Salesforce for each email marked with a specific label on Gmail using the OpenAI chat API to infer customer details. +4. [Salesforce APEX REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/revamp-2023/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. diff --git a/ballerina/Package.md b/ballerina/Package.md index 9ef62326..e0fb9627 100644 --- a/ballerina/Package.md +++ b/ballerina/Package.md @@ -93,10 +93,14 @@ bal run The `salesforce` integration samples illustrate its usage in various integration scenarios. Explore these examples below, covering the use of salesforce APIs in integrations. -1. [FTP B2B EDI message to Salesforce opportunity](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/ftp-edi-message-to-salesforce-opportunity) - This example reads EDI files from a given FTP location, converts those EDI messages to Ballerina records and creates a Salesforce opportunity for each EDI message. +## Examples + +The `salesforce` connector provides practical examples illustrating usage in various scenarios. Explore these examples below, covering use cases like creating sObjects, retrieving records, and executing bulk operations. + +1. [Salesforce REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. -2. [Salesforce new contact to Twilio SMS](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/salesforce-new-contact-to-twilio-sms) - This example sends a Twilio SMS for every new Salesforce contact. +2. [Salesforce Bulk API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. -3. [Kafka message to Salesforce new Contact](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/kafka_salesforce_integration/kafka-salesforce-pricebook_update) - This example updates the product price in the Salesforce price book through Kafka and Salesforce integration. +3. [Salesforce Bulk v2 API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. -4. [Email Lead info into Salesforce using OpenAI](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/gmail-to-salesforce-lead) - This example creates a lead on Salesforce for each email marked with a specific label on Gmail using the OpenAI chat API to infer customer details. +4. [Salesforce APEX REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. From d20575aa704c19e6c2a56e5f128aa1cc2292e2e1 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:10:56 +0530 Subject: [PATCH 15/26] Update Ballerina.toml --- examples/bulk_api_usecases/execute_insert_job/Ballerina.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml index 22265dab..8d371e11 100644 --- a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_insert" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" From afdc8b01482a6794ef41162af43c1544169e471f Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:28:58 +0530 Subject: [PATCH 16/26] Clean the code --- examples/apex_rest_api_usecases/create_case/Ballerina.toml | 2 +- examples/apex_rest_api_usecases/create_case/README.md | 4 ++-- examples/bulk_api_usecases/execute_delete_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_delete_job/README.md | 2 +- examples/bulk_api_usecases/execute_insert_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_insert_job/README.md | 2 +- examples/bulk_api_usecases/execute_query_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_query_job/README.md | 2 +- examples/bulk_api_usecases/execute_update_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_update_job/README.md | 2 +- examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_upsert_job/README.md | 2 +- .../execute_bulkv2_ingest_job/Ballerina.toml | 2 +- .../bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md | 2 +- examples/rest_api_usecases/create_sobjects/Ballerina.toml | 2 +- examples/rest_api_usecases/create_sobjects/README.md | 2 +- examples/rest_api_usecases/delete_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/delete_sobject/README.md | 2 +- examples/rest_api_usecases/get_by_id/Ballerina.toml | 2 +- examples/rest_api_usecases/get_by_id/README.md | 2 +- examples/rest_api_usecases/update_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/update_sobject/README.md | 4 ++-- examples/rest_api_usecases/use_query_api/Ballerina.toml | 2 +- examples/rest_api_usecases/use_query_api/README.md | 2 +- examples/rest_api_usecases/use_search_api/Ballerina.toml | 2 +- examples/rest_api_usecases/use_search_api/README.md | 2 +- examples/soap_api_usecases/convert_lead/Ballerina.toml | 2 +- examples/soap_api_usecases/convert_lead/README.md | 2 +- 28 files changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/apex_rest_api_usecases/create_case/Ballerina.toml b/examples/apex_rest_api_usecases/create_case/Ballerina.toml index 9a76137b..8987ffc5 100644 --- a/examples/apex_rest_api_usecases/create_case/Ballerina.toml +++ b/examples/apex_rest_api_usecases/create_case/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_apex_rest" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/apex_rest_api_usecases/create_case/README.md b/examples/apex_rest_api_usecases/create_case/README.md index d3babbe2..f1187357 100644 --- a/examples/apex_rest_api_usecases/create_case/README.md +++ b/examples/apex_rest_api_usecases/create_case/README.md @@ -5,7 +5,7 @@ This example demonstrates how to invoke Bulk v2 API of Salesforce. ## Prerequisites ### 1. Set up -Refer to the setup guide in [ReadMe](../../README.md) for necessary credentials. +Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentials. ### 2. Configuration @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml index 1b516bdd..0c8e72a6 100644 --- a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_delete" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_delete_job/README.md b/examples/bulk_api_usecases/execute_delete_job/README.md index 5b8b840d..fa79795d 100644 --- a/examples/bulk_api_usecases/execute_delete_job/README.md +++ b/examples/bulk_api_usecases/execute_delete_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml index 22265dab..8d371e11 100644 --- a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_insert" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_insert_job/README.md b/examples/bulk_api_usecases/execute_insert_job/README.md index 9d10a361..11333148 100644 --- a/examples/bulk_api_usecases/execute_insert_job/README.md +++ b/examples/bulk_api_usecases/execute_insert_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml index 7bdc7775..6bd8f701 100644 --- a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_query" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_query_job/README.md b/examples/bulk_api_usecases/execute_query_job/README.md index ef860427..ba414b96 100644 --- a/examples/bulk_api_usecases/execute_query_job/README.md +++ b/examples/bulk_api_usecases/execute_query_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml index a123863c..08c496d5 100644 --- a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_update" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_update_job/README.md b/examples/bulk_api_usecases/execute_update_job/README.md index a5dbfda2..e16ac574 100644 --- a/examples/bulk_api_usecases/execute_update_job/README.md +++ b/examples/bulk_api_usecases/execute_update_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml index cb8b0c05..d6da7b7b 100644 --- a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_bulk_upsert" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_upsert_job/README.md b/examples/bulk_api_usecases/execute_upsert_job/README.md index ee27c518..16607cdd 100644 --- a/examples/bulk_api_usecases/execute_upsert_job/README.md +++ b/examples/bulk_api_usecases/execute_upsert_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml index 9a76137b..8987ffc5 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_apex_rest" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md index af781e93..b1bbeece 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/create_sobjects/Ballerina.toml b/examples/rest_api_usecases/create_sobjects/Ballerina.toml index ae56b98a..a387db4a 100644 --- a/examples/rest_api_usecases/create_sobjects/Ballerina.toml +++ b/examples/rest_api_usecases/create_sobjects/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_rest_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/create_sobjects/README.md b/examples/rest_api_usecases/create_sobjects/README.md index 71b92c22..5e819422 100644 --- a/examples/rest_api_usecases/create_sobjects/README.md +++ b/examples/rest_api_usecases/create_sobjects/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/delete_sobject/Ballerina.toml b/examples/rest_api_usecases/delete_sobject/Ballerina.toml index 648d9277..dc440581 100644 --- a/examples/rest_api_usecases/delete_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/delete_sobject/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_getbyid_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/delete_sobject/README.md b/examples/rest_api_usecases/delete_sobject/README.md index b4ba40e0..cabda639 100644 --- a/examples/rest_api_usecases/delete_sobject/README.md +++ b/examples/rest_api_usecases/delete_sobject/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/get_by_id/Ballerina.toml b/examples/rest_api_usecases/get_by_id/Ballerina.toml index 648d9277..dc440581 100644 --- a/examples/rest_api_usecases/get_by_id/Ballerina.toml +++ b/examples/rest_api_usecases/get_by_id/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_getbyid_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/get_by_id/README.md b/examples/rest_api_usecases/get_by_id/README.md index a3628570..40691b5b 100644 --- a/examples/rest_api_usecases/get_by_id/README.md +++ b/examples/rest_api_usecases/get_by_id/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/update_sobject/Ballerina.toml b/examples/rest_api_usecases/update_sobject/Ballerina.toml index 1a681b63..111396d3 100644 --- a/examples/rest_api_usecases/update_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/update_sobject/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_update_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/update_sobject/README.md b/examples/rest_api_usecases/update_sobject/README.md index 71b92c22..3ac30898 100644 --- a/examples/rest_api_usecases/update_sobject/README.md +++ b/examples/rest_api_usecases/update_sobject/README.md @@ -1,6 +1,6 @@ # Use REST API -This example demonstrates how to invoke REST API of Salesforce to create sObjects. +This example demonstrates how to invoke REST API of Salesforce to update sObjects. ## Prerequisites @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/use_query_api/Ballerina.toml b/examples/rest_api_usecases/use_query_api/Ballerina.toml index 4159e14e..f167a512 100644 --- a/examples/rest_api_usecases/use_query_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_query_api/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_query_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_query_api/README.md b/examples/rest_api_usecases/use_query_api/README.md index 4dba39cf..f0899705 100644 --- a/examples/rest_api_usecases/use_query_api/README.md +++ b/examples/rest_api_usecases/use_query_api/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/rest_api_usecases/use_search_api/Ballerina.toml b/examples/rest_api_usecases/use_search_api/Ballerina.toml index 050375d5..11f003c5 100644 --- a/examples/rest_api_usecases/use_search_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_search_api/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_search_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_search_api/README.md b/examples/rest_api_usecases/use_search_api/README.md index 2af94727..276cd5fa 100644 --- a/examples/rest_api_usecases/use_search_api/README.md +++ b/examples/rest_api_usecases/use_search_api/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` diff --git a/examples/soap_api_usecases/convert_lead/Ballerina.toml b/examples/soap_api_usecases/convert_lead/Ballerina.toml index 630759e1..1a24df22 100644 --- a/examples/soap_api_usecases/convert_lead/Ballerina.toml +++ b/examples/soap_api_usecases/convert_lead/Ballerina.toml @@ -2,4 +2,4 @@ org = "salsforce_exsamples" name = "use_soap_api" version = "0.1.0" -distribution = "2201.8.2" \ No newline at end of file +distribution = "2201.8.2" diff --git a/examples/soap_api_usecases/convert_lead/README.md b/examples/soap_api_usecases/convert_lead/README.md index 7c85170e..f3eace73 100644 --- a/examples/soap_api_usecases/convert_lead/README.md +++ b/examples/soap_api_usecases/convert_lead/README.md @@ -25,4 +25,4 @@ Execute the following command to run the example: ```bash bal run -``` \ No newline at end of file +``` From dce5b536cfbc0c62f7046a58e1323b1f3e0d1721 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:54:07 +0530 Subject: [PATCH 17/26] Apply suggestions from code review --- .github/workflows/pull-request.yml | 3 ++- .github/workflows/release.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 70b82b03..abfb0be9 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -11,4 +11,5 @@ jobs: name: Run PR Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} uses: ballerina-platform/ballerina-standard-library/.github/workflows/pr-build-connector-template.yml@main - secrets: inherit \ No newline at end of file + secrets: inherit + \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcf51426..cd393f52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,4 +16,5 @@ jobs: package-org: ballerinax additional-build-flags: "-x :salesforce-examples:build" additional-release-flags: "-x :salesforce-examples:build" - additional-publish-flags: "-x :salesforce-examples:build" \ No newline at end of file + additional-publish-flags: "-x :salesforce-examples:build" + \ No newline at end of file From 77d651af6a2f702bca5d5ffbfc259735f89b9caf Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:08:34 +0530 Subject: [PATCH 18/26] Migrate other workflows to centralized ones --- .../workflows/build-with-bal-test-native.yml | 65 +++------------ .github/workflows/daily-build.yml | 75 +++--------------- .github/workflows/dev-stg-release.yml | 79 ++++--------------- .github/workflows/pull-request.yml | 3 +- .github/workflows/release.yml | 3 +- .github/workflows/trivy-scan.yml | 41 ++-------- 6 files changed, 49 insertions(+), 217 deletions(-) diff --git a/.github/workflows/build-with-bal-test-native.yml b/.github/workflows/build-with-bal-test-native.yml index aec9384a..c867aa69 100644 --- a/.github/workflows/build-with-bal-test-native.yml +++ b/.github/workflows/build-with-bal-test-native.yml @@ -2,58 +2,19 @@ name: GraalVM Check on: schedule: - - cron: '30 18 * * *' + - cron: "30 18 * * *" workflow_dispatch: -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: 17.0.7 - - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: latest - - - name: Grant execute permission for gradlew - run: chmod +x gradlew +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: true - - name: Build with Gradle - env: - packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }} - packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }} - JAVA_OPTS: -DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true - run: | - ./gradlew build -x test - - - name: Set up GraalVM - uses: graalvm/setup-graalvm@v1 - with: - java-version: '17' - distribution: 'graalvm-community' - github-token: ${{ secrets.GITHUB_TOKEN }} - set-java-home: 'false' - - - name: Check GraalVM installation - run: | - echo "GRAALVM_HOME: ${{ env.GRAALVM_HOME }}" - echo "JAVA_HOME: ${{ env.JAVA_HOME }}" - native-image --version - - - name: Run Ballerina tests using the native executable - run: bal test --graalvm ./ballerina - env: - JAVA_HOME: /usr/lib/jvm/default-jvm - CLIENT_ID: ${{ secrets.CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} - EP_URL: ${{ secrets.EP_URL }} - REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} - REFRESH_URL: ${{ secrets.REFRESH_URL }} +jobs: + call_stdlib_workflow: + name: Run StdLib Workflow + if: ${{ github.event_name != 'schedule' || (github.event_name == 'schedule' && github.repository_owner == 'ballerina-platform') }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/build-with-bal-test-graalvm-connector-template.yml@main + secrets: inherit + with: + additional-build-flags: "-x :salesforce-examples:build"\ + \ No newline at end of file diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index ca62ce51..edae5548 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -2,71 +2,14 @@ name: Daily build on: schedule: - - cron: '30 2 * * *' + - cron: "30 2 * * *" jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - # Set up Java Environment - - name: Set up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17.0.7 - - # Setup Ballerina Environment - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: latest - - # Grant execute permission to the gradlew script - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - # Build the project with Gradle - - name: Build with Gradle - env: - packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }} - packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }} - JAVA_OPTS: -DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true - run: | - ./gradlew build -x test - - # Build Ballerina Project - - name: Ballerina Build - run: bal pack ./ballerina - env: - JAVA_HOME: /usr/lib/jvm/default-jvm - - # Test Ballerina Project - - name: Ballerina Test - run: bal test --test-report --code-coverage --coverage-format=xml ./ballerina - env: - CLIENT_ID: ${{ secrets.CLIENT_ID }} - CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }} - EP_URL: ${{ secrets.EP_URL }} - REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} - REFRESH_URL: ${{ secrets.REFRESH_URL }} - JAVA_HOME: /usr/lib/jvm/default-jvm - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 - - # Send notification when build fails - - name: Notify failure - if: ${{ failure() }} - run: | - curl -X POST \ - 'https://api.github.com/repos/ballerina-platform/ballerina-release/dispatches' \ - -H 'Accept: application/vnd.github.v3+json' \ - -H 'Authorization: Bearer ${{ secrets.BALLERINA_BOT_TOKEN }}' \ - --data "{ - \"event_type\": \"notify-build-failure\", - \"client_payload\": { - \"repoName\": \"module-ballerinax-sfdc\" - } - }" + call_workflow: + name: Run Daily Build Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/daily-build-connector-template.yml@main + secrets: inherit + with: + repo-name: module-ballerinax-sfdc + \ No newline at end of file diff --git a/.github/workflows/dev-stg-release.yml b/.github/workflows/dev-stg-release.yml index 83365f07..36db70c5 100644 --- a/.github/workflows/dev-stg-release.yml +++ b/.github/workflows/dev-stg-release.yml @@ -1,72 +1,23 @@ -name: Dev/Staging BCentral Release +name: Publish to the Ballerina Dev\Stage Central on: workflow_dispatch: inputs: - bal_central_environment: - description: Ballerina Central Environment + environment: type: choice - options: - - STAGE - - DEV + description: Select Environment required: true + options: + - DEV CENTRAL + - STAGE CENTRAL jobs: - release: - runs-on: ubuntu-latest - env: - BALLERINA_${{ github.event.inputs.bal_central_environment }}_CENTRAL: true - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 17 - uses: actions/setup-java@v1 - with: - java-version: 17.0.7 - - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: 2201.8.0 - - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - - name: Build with Gradle - env: - packageUser: ${{ secrets.BALLERINA_BOT_USERNAME }} - packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }} - JAVA_OPTS: -DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true - run: | - ./gradlew build -x test -x :salesforce-examples:build - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - scan-type: 'rootfs' - scan-ref: '.' - skip-dirs: 'gradle/' - format: 'table' - timeout: '10m0s' - exit-code: '1' - - - name: Ballerina Build - run: bal pack ./ballerina - env: - JAVA_HOME: /usr/lib/jvm/default-jvm - - - name: Push to Staging - if: github.event.inputs.bal_central_environment == 'STAGE' - run: bal push - env: - BALLERINA_CENTRAL_ACCESS_TOKEN: ${{ secrets.BALLERINA_CENTRAL_STAGE_ACCESS_TOKEN }} - WORKING_DIR: ./ballerina - JAVA_HOME: /usr/lib/jvm/default-jvm - - - name: Push to Dev - if: github.event.inputs.bal_central_environment == 'DEV' - run: bal push - env: - BALLERINA_CENTRAL_ACCESS_TOKEN: ${{ secrets.BALLERINA_CENTRAL_DEV_ACCESS_TOKEN }} - WORKING_DIR: ./ballerina - JAVA_HOME: /usr/lib/jvm/default-jvm + call_workflow: + name: Run Dev\Stage Central Publish Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/dev-stage-central-publish-connector-template.yml@main + secrets: inherit + with: + environment: ${{ github.event.inputs.environment }} + additional-publish-flags: "-x :salesforce-examples:build" + \ No newline at end of file diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 70b82b03..abfb0be9 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -11,4 +11,5 @@ jobs: name: Run PR Build Workflow if: ${{ github.repository_owner == 'ballerina-platform' }} uses: ballerina-platform/ballerina-standard-library/.github/workflows/pr-build-connector-template.yml@main - secrets: inherit \ No newline at end of file + secrets: inherit + \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcf51426..cd393f52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,4 +16,5 @@ jobs: package-org: ballerinax additional-build-flags: "-x :salesforce-examples:build" additional-release-flags: "-x :salesforce-examples:build" - additional-publish-flags: "-x :salesforce-examples:build" \ No newline at end of file + additional-publish-flags: "-x :salesforce-examples:build" + \ No newline at end of file diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index 552dd249..ac15a675 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -3,38 +3,13 @@ name: Trivy on: workflow_dispatch: schedule: - - cron: '30 20 * * *' + - cron: "30 20 * * *" jobs: - ubuntu-build: - name: Build on Ubuntu - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Set up JDK 17 - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: 17.0.7 - - - name: Set Up Ballerina - uses: ballerina-platform/setup-ballerina@v1.1.0 - with: - version: latest - - - name: Build with Gradle - env: - packageUser: ${{ github.actor }} - packagePAT: ${{ secrets.GITHUB_TOKEN }} - run: ./gradlew build -x check -x test -x :salesforce-examples:build - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - scan-type: 'rootfs' - scan-ref: '.' - skip-dirs: 'gradle/' - format: 'table' - timeout: '10m0s' - exit-code: '1' + call_workflow: + name: Run Trivy Scan Workflow + if: ${{ github.repository_owner == 'ballerina-platform' }} + uses: ballerina-platform/ballerina-standard-library/.github/workflows/trivy-scan-template.yml@main + secrets: inherit + with: + additional-build-flags: "-x :salesforce-examples:build -Pgroups=mock" From 2b56a84aa5f2f3d0b2d6dc0e896e39e0e1f31a1c Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:23:19 +0530 Subject: [PATCH 19/26] Update graalvm check workflow --- ...with-bal-test-native.yml => build-with-bal-test-graalvm.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{build-with-bal-test-native.yml => build-with-bal-test-graalvm.yml} (90%) diff --git a/.github/workflows/build-with-bal-test-native.yml b/.github/workflows/build-with-bal-test-graalvm.yml similarity index 90% rename from .github/workflows/build-with-bal-test-native.yml rename to .github/workflows/build-with-bal-test-graalvm.yml index c867aa69..09948397 100644 --- a/.github/workflows/build-with-bal-test-native.yml +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -16,5 +16,5 @@ jobs: uses: ballerina-platform/ballerina-standard-library/.github/workflows/build-with-bal-test-graalvm-connector-template.yml@main secrets: inherit with: - additional-build-flags: "-x :salesforce-examples:build"\ + additional-build-flags: "-x :salesforce-examples:build" \ No newline at end of file From 00efe4220cec6980128015746ebc87fb04ce00c6 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:10:59 +0530 Subject: [PATCH 20/26] Update readme files of examples --- examples/apex_rest_api_usecases/create_case/README.md | 4 ++-- .../bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/apex_rest_api_usecases/create_case/README.md b/examples/apex_rest_api_usecases/create_case/README.md index f1187357..d0780627 100644 --- a/examples/apex_rest_api_usecases/create_case/README.md +++ b/examples/apex_rest_api_usecases/create_case/README.md @@ -1,6 +1,6 @@ -# Use APEX API +# Use APEX REST API -This example demonstrates how to invoke Bulk v2 API of Salesforce. +This example demonstrates how to invoke APEX REST API of Salesforce. ## Prerequisites diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md index b1bbeece..3e11aaa8 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md @@ -1,6 +1,6 @@ # Use Bulk V2 API -This example demonstrates how to invoke APEX REST API of Salesforce. +This example demonstrates how to invoke Bulk API v2 of Salesforce. ## Prerequisites From 5b2cd793f41bd543921e566bf9aa36c85b9cbe5c Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:20:13 +0530 Subject: [PATCH 21/26] Update Module.md --- ballerina/Module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/Module.md b/ballerina/Module.md index 4ad4d6ee..a36ef581 100644 --- a/ballerina/Module.md +++ b/ballerina/Module.md @@ -82,7 +82,7 @@ Following is an example on how to create a record using the connector. ```ballerina salesforce:CreationResponse response = check - baseClient->create("Account", { + salesforce->create("Account", { "Name": "IT World", "BillingCity": "New York" }); From a8716f18d63f960e0c4d3298f085bf0ea5fdd3bc Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:21:10 +0530 Subject: [PATCH 22/26] Apply suggestions from code review Co-authored-by: Arshika Mohottige --- .github/workflows/build-with-bal-test-graalvm.yml | 1 + .github/workflows/daily-build.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build-with-bal-test-graalvm.yml b/.github/workflows/build-with-bal-test-graalvm.yml index 09948397..7a863b91 100644 --- a/.github/workflows/build-with-bal-test-graalvm.yml +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -17,4 +17,5 @@ jobs: secrets: inherit with: additional-build-flags: "-x :salesforce-examples:build" + \ No newline at end of file diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index edae5548..23e19ecc 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -12,4 +12,5 @@ jobs: secrets: inherit with: repo-name: module-ballerinax-sfdc + \ No newline at end of file From 70dfeb8885ce88fef103f10126fbef96e80e9ff2 Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:30:16 +0530 Subject: [PATCH 23/26] Update release.yml removing repository_dispatch --- .github/workflows/release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cd393f52..b7d76cd3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,8 +2,6 @@ name: Publish Release on: workflow_dispatch: - repository_dispatch: - types: [ stdlib-release-pipeline ] jobs: call_workflow: From bbda6d24f4c2c825f38ade4a9c7ec2467a42e73d Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:00:42 +0530 Subject: [PATCH 24/26] Update project organisation of examples --- examples/apex_rest_api_usecases/create_case/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_delete_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_insert_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_query_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_update_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml | 2 +- .../execute_bulkv2_ingest_job/Ballerina.toml | 2 +- examples/rest_api_usecases/create_sobjects/Ballerina.toml | 2 +- examples/rest_api_usecases/delete_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/get_by_id/Ballerina.toml | 2 +- examples/rest_api_usecases/update_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/use_query_api/Ballerina.toml | 2 +- examples/rest_api_usecases/use_search_api/Ballerina.toml | 2 +- examples/soap_api_usecases/convert_lead/Ballerina.toml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/apex_rest_api_usecases/create_case/Ballerina.toml b/examples/apex_rest_api_usecases/create_case/Ballerina.toml index 8987ffc5..efa056da 100644 --- a/examples/apex_rest_api_usecases/create_case/Ballerina.toml +++ b/examples/apex_rest_api_usecases/create_case/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_apex_rest" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml index 0c8e72a6..658b5270 100644 --- a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_bulk_delete" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml index 8d371e11..ebef03f8 100644 --- a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_bulk_insert" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml index 6bd8f701..e3ebe520 100644 --- a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_bulk_query" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml index 08c496d5..90606f9f 100644 --- a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_bulk_update" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml index d6da7b7b..19eb442a 100644 --- a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_bulk_upsert" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml index 8987ffc5..efa056da 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_apex_rest" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/create_sobjects/Ballerina.toml b/examples/rest_api_usecases/create_sobjects/Ballerina.toml index a387db4a..f40d5710 100644 --- a/examples/rest_api_usecases/create_sobjects/Ballerina.toml +++ b/examples/rest_api_usecases/create_sobjects/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_rest_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/delete_sobject/Ballerina.toml b/examples/rest_api_usecases/delete_sobject/Ballerina.toml index dc440581..5f89ae1f 100644 --- a/examples/rest_api_usecases/delete_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/delete_sobject/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_getbyid_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/get_by_id/Ballerina.toml b/examples/rest_api_usecases/get_by_id/Ballerina.toml index dc440581..5f89ae1f 100644 --- a/examples/rest_api_usecases/get_by_id/Ballerina.toml +++ b/examples/rest_api_usecases/get_by_id/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_getbyid_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/update_sobject/Ballerina.toml b/examples/rest_api_usecases/update_sobject/Ballerina.toml index 111396d3..8d7a4868 100644 --- a/examples/rest_api_usecases/update_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/update_sobject/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_update_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_query_api/Ballerina.toml b/examples/rest_api_usecases/use_query_api/Ballerina.toml index f167a512..38167d43 100644 --- a/examples/rest_api_usecases/use_query_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_query_api/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_query_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_search_api/Ballerina.toml b/examples/rest_api_usecases/use_search_api/Ballerina.toml index 11f003c5..6e28cede 100644 --- a/examples/rest_api_usecases/use_search_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_search_api/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_search_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/soap_api_usecases/convert_lead/Ballerina.toml b/examples/soap_api_usecases/convert_lead/Ballerina.toml index 1a24df22..42370c2d 100644 --- a/examples/soap_api_usecases/convert_lead/Ballerina.toml +++ b/examples/soap_api_usecases/convert_lead/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_exsamples" +org = "salsforce_examples" name = "use_soap_api" version = "0.1.0" distribution = "2201.8.2" From 637bff31ea6fdcb76c54d48b8f7054b644e6d85a Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Thu, 22 Feb 2024 15:37:00 +0530 Subject: [PATCH 25/26] Update code according to comments --- README.md | 8 ++++---- ballerina/Package.md | 8 ++++---- ballerina/modules/bulk/tests/utils.bal | 2 +- examples/apex_rest_api_usecases/create_case/README.md | 4 ++-- .../create_case/invoke_apex_methods.bal | 2 +- examples/bulk_api_usecases/execute_delete_job/README.md | 4 ++-- .../execute_delete_job/bulk_delete_csv.bal | 2 +- examples/bulk_api_usecases/execute_insert_job/README.md | 4 ++-- examples/bulk_api_usecases/execute_query_job/README.md | 4 ++-- examples/bulk_api_usecases/execute_update_job/README.md | 4 ++-- examples/bulk_api_usecases/execute_upsert_job/README.md | 4 ++-- .../execute_bulkv2_ingest_job/README.md | 4 ++-- .../execute_bulkv2_ingest_job/bulkv2_insert.bal | 2 +- examples/rest_api_usecases/create_sobjects/README.md | 4 ++-- examples/rest_api_usecases/delete_sobject/README.md | 4 ++-- examples/rest_api_usecases/get_by_id/README.md | 4 ++-- examples/rest_api_usecases/update_sobject/README.md | 4 ++-- examples/rest_api_usecases/use_query_api/README.md | 4 ++-- examples/rest_api_usecases/use_search_api/README.md | 4 ++-- examples/soap_api_usecases/convert_lead/README.md | 4 ++-- examples/soap_api_usecases/convert_lead/convert_lead.bal | 2 +- 21 files changed, 41 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index e2b5de7b..0000d244 100644 --- a/README.md +++ b/README.md @@ -114,13 +114,13 @@ bal run The `salesforce` connector provides practical examples illustrating usage in various scenarios. Explore these examples below, covering use cases like creating sObjects, retrieving records, and executing bulk operations. -1. [Salesforce REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. +1. [Salesforce REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. -2. [Salesforce Bulk API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. +2. [Salesforce Bulk API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. -3. [Salesforce Bulk v2 API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. +3. [Salesforce Bulk v2 API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. -4. [Salesforce APEX REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. +4. [Salesforce APEX REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. ## Report Issues diff --git a/ballerina/Package.md b/ballerina/Package.md index e0fb9627..c417811f 100644 --- a/ballerina/Package.md +++ b/ballerina/Package.md @@ -97,10 +97,10 @@ The `salesforce` integration samples illustrate its usage in various integration The `salesforce` connector provides practical examples illustrating usage in various scenarios. Explore these examples below, covering use cases like creating sObjects, retrieving records, and executing bulk operations. -1. [Salesforce REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. +1. [Salesforce REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/rest_api_usecases) - How to employ REST API of Salesforce to carryout varies tasks. -2. [Salesforce Bulk API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. +2. [Salesforce Bulk API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulk_api_usecases) - How to employ Bulk API of Salesforce to execute Bulk jobs. -3. [Salesforce Bulk v2 API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. +3. [Salesforce Bulk v2 API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/bulkv2_api_usecases) - How to employ Bulk v2 API to execute an ingest job. -4. [Salesforce APEX REST API usecases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. +4. [Salesforce APEX REST API use cases](https://github.com/ballerina-platform/module-ballerinax-sfdc/tree/main/examples/apex_rest_api_usecases) - How to employ APEX REST API to create a case in Salesforce. diff --git a/ballerina/modules/bulk/tests/utils.bal b/ballerina/modules/bulk/tests/utils.bal index 84d46b9e..9753a941 100644 --- a/ballerina/modules/bulk/tests/utils.bal +++ b/ballerina/modules/bulk/tests/utils.bal @@ -24,7 +24,7 @@ json[] jsonInsertResult = []; xml xmlInsertResult = xml ``; string csvInputResult = "Id"; -// Create Salesforce client configuration by reading from environemnt. +// Create Salesforce client configuration by reading from environment. configurable string clientId = os:getEnv("CLIENT_ID"); configurable string clientSecret = os:getEnv("CLIENT_SECRET"); configurable string refreshToken = os:getEnv("REFRESH_TOKEN"); diff --git a/examples/apex_rest_api_usecases/create_case/README.md b/examples/apex_rest_api_usecases/create_case/README.md index d0780627..34436731 100644 --- a/examples/apex_rest_api_usecases/create_case/README.md +++ b/examples/apex_rest_api_usecases/create_case/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal index a3907b88..5467222c 100644 --- a/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal +++ b/examples/apex_rest_api_usecases/create_case/invoke_apex_methods.bal @@ -18,7 +18,7 @@ import ballerina/log; import ballerinax/salesforce; import ballerina/lang.runtime; -// Create Salesforce client configuration by reading from environemnt. +// Create Salesforce client configuration by reading from environment. configurable string clientId = ?; configurable string clientSecret = ?; configurable string refreshToken = ?; diff --git a/examples/bulk_api_usecases/execute_delete_job/README.md b/examples/bulk_api_usecases/execute_delete_job/README.md index fa79795d..c1bb6fdd 100644 --- a/examples/bulk_api_usecases/execute_delete_job/README.md +++ b/examples/bulk_api_usecases/execute_delete_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../../README.md) for necessary creden Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal b/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal index 6a9c74f3..2a0655ed 100644 --- a/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal +++ b/examples/bulk_api_usecases/execute_delete_job/bulk_delete_csv.bal @@ -18,7 +18,7 @@ import ballerina/log; import ballerinax/salesforce.bulk; import ballerinax/salesforce; -// Create Salesforce client configuration by reading from environemnt. +// Create Salesforce client configuration by reading from environment. configurable string clientId = ?; configurable string clientSecret = ?; configurable string refreshToken = ?; diff --git a/examples/bulk_api_usecases/execute_insert_job/README.md b/examples/bulk_api_usecases/execute_insert_job/README.md index 11333148..90cbf42b 100644 --- a/examples/bulk_api_usecases/execute_insert_job/README.md +++ b/examples/bulk_api_usecases/execute_insert_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../../README.md) for necessary creden Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulk_api_usecases/execute_query_job/README.md b/examples/bulk_api_usecases/execute_query_job/README.md index ba414b96..d3282042 100644 --- a/examples/bulk_api_usecases/execute_query_job/README.md +++ b/examples/bulk_api_usecases/execute_query_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../../README.md) for necessary creden Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulk_api_usecases/execute_update_job/README.md b/examples/bulk_api_usecases/execute_update_job/README.md index e16ac574..9999d3f2 100644 --- a/examples/bulk_api_usecases/execute_update_job/README.md +++ b/examples/bulk_api_usecases/execute_update_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../../README.md) for necessary creden Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulk_api_usecases/execute_upsert_job/README.md b/examples/bulk_api_usecases/execute_upsert_job/README.md index 16607cdd..32d1166c 100644 --- a/examples/bulk_api_usecases/execute_upsert_job/README.md +++ b/examples/bulk_api_usecases/execute_upsert_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../../README.md) for necessary creden Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md index 3e11aaa8..1bdbbe1d 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../README.md) for necessary credentials. Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal index 4d6105e0..1c1d9fe3 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/bulkv2_insert.bal @@ -18,7 +18,7 @@ import ballerinax/salesforce; import ballerina/lang.runtime; import ballerina/io; -// Create Salesforce client configuration by reading from environemnt. +// Create Salesforce client configuration by reading from environment. configurable string clientId = ?; configurable string clientSecret = ?; configurable string refreshToken = ?; diff --git a/examples/rest_api_usecases/create_sobjects/README.md b/examples/rest_api_usecases/create_sobjects/README.md index 5e819422..5a892f58 100644 --- a/examples/rest_api_usecases/create_sobjects/README.md +++ b/examples/rest_api_usecases/create_sobjects/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/rest_api_usecases/delete_sobject/README.md b/examples/rest_api_usecases/delete_sobject/README.md index cabda639..790fef9a 100644 --- a/examples/rest_api_usecases/delete_sobject/README.md +++ b/examples/rest_api_usecases/delete_sobject/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/rest_api_usecases/get_by_id/README.md b/examples/rest_api_usecases/get_by_id/README.md index 40691b5b..bd2d99de 100644 --- a/examples/rest_api_usecases/get_by_id/README.md +++ b/examples/rest_api_usecases/get_by_id/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/rest_api_usecases/update_sobject/README.md b/examples/rest_api_usecases/update_sobject/README.md index 3ac30898..637a5e7b 100644 --- a/examples/rest_api_usecases/update_sobject/README.md +++ b/examples/rest_api_usecases/update_sobject/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/rest_api_usecases/use_query_api/README.md b/examples/rest_api_usecases/use_query_api/README.md index f0899705..ba32d8a1 100644 --- a/examples/rest_api_usecases/use_query_api/README.md +++ b/examples/rest_api_usecases/use_query_api/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/rest_api_usecases/use_search_api/README.md b/examples/rest_api_usecases/use_search_api/README.md index 276cd5fa..82d34703 100644 --- a/examples/rest_api_usecases/use_search_api/README.md +++ b/examples/rest_api_usecases/use_search_api/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/soap_api_usecases/convert_lead/README.md b/examples/soap_api_usecases/convert_lead/README.md index f3eace73..eb2afc6c 100644 --- a/examples/soap_api_usecases/convert_lead/README.md +++ b/examples/soap_api_usecases/convert_lead/README.md @@ -12,14 +12,14 @@ Refer to the setup guide in [ReadMe](../../../README.md) for necessary credentia Configure Salesforce API credentials in Config.toml in the example directory: ```toml -clientId = "" +clientId = "" clientSecret = "" refreshToken = "" refreshUrl = "" baseUrl = "" ``` -## Run the Example +## Run the example Execute the following command to run the example: diff --git a/examples/soap_api_usecases/convert_lead/convert_lead.bal b/examples/soap_api_usecases/convert_lead/convert_lead.bal index 2eeeb578..76e3f418 100644 --- a/examples/soap_api_usecases/convert_lead/convert_lead.bal +++ b/examples/soap_api_usecases/convert_lead/convert_lead.bal @@ -17,7 +17,7 @@ import ballerinax/salesforce.soap; import ballerina/log; -// Create Salesforce client configuration by reading from environemnt. +// Create Salesforce client configuration by reading from environment. configurable string clientId = ?; configurable string clientSecret = ?; configurable string refreshToken = ?; From a31293117a3f18318138dcf6a3de40ca07c383fe Mon Sep 17 00:00:00 2001 From: Sahan He <45299562+sahanHe@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:44:58 +0530 Subject: [PATCH 26/26] Update org name --- examples/apex_rest_api_usecases/create_case/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_delete_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_insert_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_query_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_update_job/Ballerina.toml | 2 +- examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml | 2 +- .../execute_bulkv2_ingest_job/Ballerina.toml | 2 +- examples/rest_api_usecases/create_sobjects/Ballerina.toml | 2 +- examples/rest_api_usecases/delete_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/get_by_id/Ballerina.toml | 2 +- examples/rest_api_usecases/update_sobject/Ballerina.toml | 2 +- examples/rest_api_usecases/use_query_api/Ballerina.toml | 2 +- examples/rest_api_usecases/use_search_api/Ballerina.toml | 2 +- examples/soap_api_usecases/convert_lead/Ballerina.toml | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/apex_rest_api_usecases/create_case/Ballerina.toml b/examples/apex_rest_api_usecases/create_case/Ballerina.toml index efa056da..37090d1f 100644 --- a/examples/apex_rest_api_usecases/create_case/Ballerina.toml +++ b/examples/apex_rest_api_usecases/create_case/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_apex_rest" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml index 658b5270..101357e9 100644 --- a/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_delete_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_bulk_delete" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml index ebef03f8..60c9dbfd 100644 --- a/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_insert_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_bulk_insert" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml index e3ebe520..7538ae34 100644 --- a/examples/bulk_api_usecases/execute_query_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_query_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_bulk_query" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml index 90606f9f..c74e693e 100644 --- a/examples/bulk_api_usecases/execute_update_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_update_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_bulk_update" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml index 19eb442a..3ff5dd70 100644 --- a/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml +++ b/examples/bulk_api_usecases/execute_upsert_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_bulk_upsert" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml index efa056da..37090d1f 100644 --- a/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml +++ b/examples/bulkv2_api_usecases/execute_bulkv2_ingest_job/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_apex_rest" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/create_sobjects/Ballerina.toml b/examples/rest_api_usecases/create_sobjects/Ballerina.toml index f40d5710..4c87ec52 100644 --- a/examples/rest_api_usecases/create_sobjects/Ballerina.toml +++ b/examples/rest_api_usecases/create_sobjects/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_rest_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/delete_sobject/Ballerina.toml b/examples/rest_api_usecases/delete_sobject/Ballerina.toml index 5f89ae1f..2cc6d065 100644 --- a/examples/rest_api_usecases/delete_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/delete_sobject/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_getbyid_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/get_by_id/Ballerina.toml b/examples/rest_api_usecases/get_by_id/Ballerina.toml index 5f89ae1f..2cc6d065 100644 --- a/examples/rest_api_usecases/get_by_id/Ballerina.toml +++ b/examples/rest_api_usecases/get_by_id/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_getbyid_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/update_sobject/Ballerina.toml b/examples/rest_api_usecases/update_sobject/Ballerina.toml index 8d7a4868..7abe8777 100644 --- a/examples/rest_api_usecases/update_sobject/Ballerina.toml +++ b/examples/rest_api_usecases/update_sobject/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_update_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_query_api/Ballerina.toml b/examples/rest_api_usecases/use_query_api/Ballerina.toml index 38167d43..6d323665 100644 --- a/examples/rest_api_usecases/use_query_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_query_api/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_query_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/rest_api_usecases/use_search_api/Ballerina.toml b/examples/rest_api_usecases/use_search_api/Ballerina.toml index 6e28cede..d8500275 100644 --- a/examples/rest_api_usecases/use_search_api/Ballerina.toml +++ b/examples/rest_api_usecases/use_search_api/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_search_api" version = "0.1.0" distribution = "2201.8.2" diff --git a/examples/soap_api_usecases/convert_lead/Ballerina.toml b/examples/soap_api_usecases/convert_lead/Ballerina.toml index 42370c2d..e26a57b2 100644 --- a/examples/soap_api_usecases/convert_lead/Ballerina.toml +++ b/examples/soap_api_usecases/convert_lead/Ballerina.toml @@ -1,5 +1,5 @@ [package] -org = "salsforce_examples" +org = "salesforce_examples" name = "use_soap_api" version = "0.1.0" distribution = "2201.8.2"